1. 什么是PWM?
PWM(脉冲宽度调制)简略的讲是一种变频技能之一,是靠改动脉冲宽度来操控输出电压,经过改动周期来操控其输出频率。假如还不是很清楚,好吧,来看看咱们实际生活中的比如,咱们的电电扇为什么扭一下按扭,电扇的转速就会产生变化;调一下收音机的声响按钮,声响的巨细就会产生变化;还有待会儿咱们要讲的蜂鸣器也会依据不同的输入值而宣布不同频率的叫声等等!!这些都是PWM的运用,都是经过PWM输出的频率信号进行操控的。
2. ARM Linux中的PWM
依据S3C2440的手册介绍,S3C2440A内部有5个16位的定时器,定时器0、1、2、3都带有脉冲宽度调制功用(PWM),定时器4是一个没有输出引脚的内部定时器,定时器0有一个用于大电流设备的死区生成器。看下图解说吧!!
由S3C2440的技能手册和上面这幅结构图,咱们来总结一下2440内部定时器模块的特性吧:
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} / 时钟分频值。下面咱们来经过一个蜂鸣器的实例来阐明PWM功用的运用。
1. 蜂鸣器的品种和作业原理
蜂鸣器首要分为压电式蜂鸣器和电磁式蜂鸣器两品种型。
压电式蜂鸣器首要由多谐振动器、压电蜂鸣片、阻抗匹配器及共识箱、外壳等组成。有的压电式蜂鸣器外壳上还装有发光二极管。多谐振动器由晶体管或%&&&&&%构成。当接通电源后(1.5~15V直流作业电压),多谐振动器起振,输出1.5~2.5kHZ的音频信号,阻抗匹配器推进压电蜂鸣片发声。
电磁式蜂鸣器由振动器、电磁线圈、磁铁、振动膜片及外壳等组成。接通电源后,振动器产生的音频信号电流经过电磁线圈,使电磁线圈产生磁场。振动膜片在电磁线圈和磁铁的相互作用下,周期性地振动发声。
有源蜂鸣器和无源蜂鸣器的差异:这个“源”字是不是指电源,而是指震动源,即有源蜂鸣器内有振动源而无源蜂鸣器内部没有振动源。有振动源的通电就能够发声,没有振动源的需求脉冲信号驱动才干发声。
1)制备电磁铁M:在长约6厘米的铁螺栓上绕100圈导线,线端留下5厘米作引线,用通明胶布把线圈粘好,避免线圈松开,再用胶布把它粘在一个盒子上,电磁铁就做好了;
3. 编写适宜开发板的蜂鸣器驱动程序,文件名:my2440_pwm.c
/* #include #definePWM_MAJOR 0//主设备号 staticintdevice_major=PWM_MAJOR;//体系动态生成的主设备号 //翻开设备 return0; //封闭设备 //对设备进行操控 structclk*clk_p; //以下对各存放器的操作结合上面讲的开端一个PWM定时器的过程和2440手册PWM存放器操作部分来看就比较简单了解 tcfg0&=~S3C2410_TCFG_PRESCALER0_MASK; tcfg1&=~S3C2410_TCFG1_MUX0_MASK; __raw_writel(tcfg1,S3C2410_TCFG1);//将值tcfg1写入定时器装备存放器1中 clk_p=clk_get(NULL,”pclk”); __raw_writel(tcnt,S3C2410_TCNTB(0));//设置定时器0计数缓存存放器的值 tcon=__raw_readl(S3C2410_TCON);//读取定时器操控存放器的值 tcon&=~0x1f; tcon&=~2; return0; //设备操作结构体 //界说一个设备类 staticint__init pwm_init(void) if(device_major<0) //注册一个设备类,使mdev能够在/dev/目录下主动树立设备节点 if(IS_ERR(pwm_class)) //创立一个设备节点,设备名为PWM_NAME,即:my2440_pwm return0; staticvoid__exit pwm_exit(void) //删去设备节点 //刊出设备类 module_init(pwm_init); MODULE_L%&&&&&%ENSE(“PGL”); |
#cp -f my2440_pwm.c /linux-2.6.30.4/drivers/char //把驱动源码到内核驱动的字符设备下 |
#gedit /linux-2.6.30.4/drivers/char/Kconfig //增加PWM蜂鸣器设备装备 |
config MY2440_PWM_BEEP |
#gedit /linux-2.6.30.4/drivers/char/Makefile //增加PWM蜂鸣器设备装备 |
obj-$(CONFIG_MY2440_PWM_BEEP) +=my2440_pwm.o |
5.装备内核,挑选PWM蜂鸣器设备选项
#make menuconfig |
Device Drivers —> |
6. 编译内核并下载到开发板上。这儿要注意,现在咱们不需求手动的在开发板上创立设备的节点了,由于咱们现在运用了mdev进行管理了(运用办法请看:设备文件体系分析与运用),在驱动程序中也增加了对类设备接口的支撑。之前讲的一些驱动都没有,今后咱们都运用这种办法。现在能够查看到/dev目录下主动创立好的my2440_pwm设备节点,就直接能够运用它了。
7. 编写PWM蜂鸣器驱动的测验程序。文件名:pwm_test.c
/* #include intmain(intargc,char**argv) //翻开蜂鸣器设备 if(fd<0) //提示用户输入一个参数来对蜂鸣器进行调频,0表明中止作业 while(1) //IO操控 if(tmp<=0) //封闭设备 return0; |
8. 在开发主机上穿插编译测验运用程序,并到文件体系的/usr/sbin目录下,然后从头编译文件体系下载到开发板上。
#arm-linux-gcc -o pwm_test pwm_test.c |
9. 在开发板上运转测验程序。能够看到依据你输入参数的巨细,蜂鸣器也会产生不同频率的叫声,输入0蜂鸣器中止鸣叫。