文档详情

TQ开发板蜂鸣器beep驱动测试

千****8
实名认证
店铺
DOC
1,011.50KB
约12页
文档ID:192724388
TQ开发板蜂鸣器beep驱动测试_第1页
1/12

TQ开发板蜂鸣器beep驱动测试———————————————————————————————— 作者:———————————————————————————————— 日期: 12 个人收集整理 勿做商业用途TQ2440开发板蜂鸣器beep驱动测试1、查看开发板TQ2440底板原理图,找到蜂鸣器控制模块,如下图:图1 蜂鸣器控制电路图从上图我们可以清楚地看到控制蜂鸣器的管脚是TOUT0.2、查看TQ2440核心板原理图,找到对应的CPU管脚,如下图:图2 TOUT0对应CPU管脚电路图由原理图可知,通过对TOUT0/GPB0进行编程可控制蜂鸣器蜂鸣器是通过GPB0端口使用PWM信号驱动工作的,而GPB0口是一个复用的IO口,要使用它得先把他设置成TOUT0 PWM输出模式3、查看S3C2440芯片手册,查看CPU管脚的模式,如下:端口配置寄存器(GPACON至GPJCON)S3C2440A中,大多数端口为复用引脚因此要决定每个引脚选择哪项功能。

PnCON(引脚控制寄存器)决定了每个引脚使用哪项功能端口数据寄存器(GPADAT至GPJDAT)如果端口配置为输出端口,可以写入数据到PnDAT的相应位如果端口配置为输入端口,可以从PnDAT的相应位读取数据.表1 端口B控制寄存器(GPBCON,GPBDAT,GPBUP)寄存器地址R/W描述复位值GPBCON0x56000010R/W配置端口B的引脚0x0GPBDAT0x56000014R/W端口B的数据寄存器–GPBUP0x56000018R/W端口B的上拉使能寄存器0x0保留0x5600001C–保留–GPBDAT位描述初始状态GPB[10:0][10:0]端口配置为输入端口时,相应位为引脚状态.当端口配置为输出端口时,引脚状态将与相应位相同.当端口配置为功能引脚,将读取到未定义值—GPBCON位描述初始状态GPB0[1:0]00=输入 01=输出 10=TOUT0 11=保留0从上表我们可以看出对于S3C2440的GPIO来说,只需要设置GPBCON和GPBDAT寄存器即可4、S3C2440 PWM基础知识:PWM(脉冲宽度调制)简单的讲是一种变频技术,靠改变脉冲宽度来控制输出电压,通过改变周期来控制其输出频率.如果还不是很清楚,好吧,来看看我们实际生活中的例子,我们的电风扇为什么扭一下按扭,风扇的转速就会发生变化;调一下收音机的声音按钮,声音的大小就会发生变化;还有待会儿我们要讲的蜂鸣器也会根据不同的输入值而发出不同频率的叫声等,这些都是PWM的应用,都是通过PWM输出的频率信号进行控制的.根据S3C2440的手册介绍,S3C2440A内部有5个16位的定时器,定时器0、1、2、3都带有脉冲宽度调制功能(PWM),定时器4是一个没有输出引脚的内部定时器,定时器0有一个用于大电流设备的死区生成器,请看下图解释:图3 S3C2440内部定时器模块部分结构图由S3C2440的技术手册和上面这幅结构图,我们来总结一下S3C2440内部定时器模块的特性吧:1)共5个16位的定时器,定时器0、1、2、3都带有脉冲宽度调制功能(PWM);2)每个定时器都有一个比较缓存寄存器(TCMPB)和一个计数缓存寄存器(TCNTB);3)定时器0、1共享一个8位的预分频器(预定标器),定时器2、3、4共享另一个8位的预分频器(预定标器),其值范围是0~255;4)定时器0、1共享一个时钟分频器,定时器2、3、4共享另一个时钟分频器,这两个时钟分频器都能产生5种不同的分频信号值(即:1/2、1/4、1/8、1/16和TCLK);5)两个8位的预分频器是可编程的且根据装载的值来对PCLK进行分频,预分频器和时钟分频器的值分别存储在定时器配置寄存器TCFG0和TCFG1中;6)有一个TCON控制寄存器控制着所有定时器的属性和状态,TCON的第0~7位控制着定时器0、第8~11位控制着定时器1、第12~15位控制着定时器2、第16~19位控制着定时器3、第20~22位控制着定时器4。

还是根据S3C2440手册的描述和上图的结构,要开始一个PWM定时器功能的步骤如下(假设使用的是第一个定时器):1)分别设置定时器0的预分频值和时钟分频值,以供定时器0的比较缓存寄存器和计数缓存寄存器用;2)设置比较缓存寄存器TCMPB0和计数缓存寄存器TCNTB0的初始值(即定时器0的输出时钟频率);3)关闭定时器0的死区生成器(设置TCON的第4位);4)开启定时器0的自动重载(设置TCON的第3位);5)关闭定时器0的反相器(设置TCON的第2位);6)开启定时器0的手动更新TCNTB0&TCMPB0功能(设置TCON的第1位);7)启动定时器0(设置TCON的第0位);8)清除定时器0的手动更新TCNTB0&TCMPB0功能(设置TCON的第1位)由此可以看到,PWM的输出频率跟比较缓存寄存器和计数缓存寄存器的取值有关,而比较缓存寄存器和计数缓存寄存器的值又跟预分频器和时钟分频器的值有关;要使用PWM功能其实也就是对定时器的相关寄存器进行操作手册上也有一个公式:定时器输出频率=PCLK/{预分频器值+1}/时钟分频值5、在linux2.630.4/drivers/char下新建文件夹mybeep,在其中建立驱动程序文件mybeep.c:#include 〈linux/module。

h〉#include #include 〈linux/fs.h〉#include #include #include #include 〈asm/io.h>#include #include #define DEVICE_NAME ”mybeep” #define BEEP_MAJOR 240 static char __initdata banner[] = "lizss TQ2440 Beep, (R) 2010.07\n”;static struct class *beep_class;//应用程序对设备文件/dev/mybeep执行ioclt时,就会调用my_beep_ioctl函数。

//cmd<0:不使用pwm,cmd>0:设置down_counter中的数值(鸣叫频率)static int my_beep_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg){ unsigned long temp; if(cmd <= 0) { temp = __raw_readl(S3C2410_GPBCON); //GPBCON = 0xfb000010 printk(”1—--S3C2410_GPBCON = %x\n", S3C2410_GPBCON); temp &= ~3;//清零 temp |= 1; //置 1 __raw_writel(temp, S3C2410_GPBCON);//S3C2410_GPBCON寄存器[1:0]置为01 temp = __raw_readl(S3C2410_GPBDAT); //读GPBDAT = 0Xfb000014 printk(”2-——S3C2410_GPBDAT = %x\n", S3C2410_GPBDAT);//输出 temp &= ~1; //清零 __raw_writel(temp, S3C2410_GPBDAT);//写S3C2410_GPBDAT寄存器[0]置为0 } else { temp = __raw_readl(S3C2410_GPBCON); //GPBCON = 0xfb000010 printk(”3——-S3C2410_GPBCON = %x\n", S3C2410_GPBCON); temp &= ~3; temp |= 2;//10 __raw_writel(temp, S3C2410_GPBCON);//S3C2410_GPBCON[1:0]置为10,使能TOUT0(pwm timer) temp = __raw_readl(S3C2410_TCFG0); //TCFG0 = 0xf4300000 printk("4——-S3C2410_TCFG0 = %x\n”, S3C2410_TCFG0); temp &= ~0xff;//清零 temp |= 15;//1101 __raw_writel(temp, S3C2410_TCFG0);//S3C2410_TCFG0[7:0]置为00001111,定时器0的预分频值为15 temp = __raw_readl(S3C2410_TCFG1); //TCFG1 = 0xf4300004 printk(”5---S3C2410_TCFG1 = %x\n”, S3C2410_TCFG1); temp &= ~0xf;//清零0000 temp |= 1;//0001 __raw_writel(temp, S3C2410_TCFG1);//S3C2410_TCFG1[3:0]置为0001,定时器0的时钟分频值输入为1/4 //TCNTB寄存器设置装载到递减计数器中的初始值,并依次递减。

TCMPB寄存器则用于装载同递减计数器进行比较的值.所以当设置TCMPB=TCNTB/2即表示进行1:1分时 temp = (50000000/64)/cmd;//set timer count buffer rgister ,50MHZ/(16*4*cmd) __raw_writel(temp, S3C2410_TCNTB(0));//S3C2410_TCNTB(0) = 0xf430000c printk(”6———S3C2410_TCNTB(0) = %x\n", S3C2410_TCNTB(0)); temp 〉>= 1; __raw_writel(temp, S3C2410_TCMPB(0));//S3C2410_TCMPB(0) = 0xf4300010 printk(”7—。

下载提示
相似文档
正为您匹配相似的精品文档