一.PWM定时器简述:

S3C2440一共有5个16位的定时器,其中定时器0、1、2、3有PWM(脉冲宽度调制)功能,它们都有一个输出引脚(如TOUTn【n为0~3】),可以通过定时器来控制引脚周期性的高、低电平变化,但是定时器4没有输出引脚。

      定时器顾名思义需要时钟去维持,那么它的时钟源为PCLK,首先通过两个8位的预分频降低频率,其中,定时器0共用第一个预分频器,定时器2、3、4共用第二个预分频器。预分频器的输出将进入第二级分频器,它们输出5种频率的时钟,2、4、8、16和TCLK0/1(外部时钟),每个定时器的工作时钟就是从这5种频率中选择得来的啦。

   8位预分频是通过TCFG0寄存器来设置的,4位分频是通过TCFG1来设置的。定时器的结构示意图如下:

 

s3c2440 PWM使用之蜂鸣器驱动移植_脉冲宽度

S3c2440datesheet分布原理图如下:

s3c2440 PWM使用之蜂鸣器驱动移植_s3c2440 PWM使用之蜂鸣器驱动移_02

 

    通过S3C2440原理图可知蜂鸣器接2440的GPB0/TOUT0.即我们的蜂鸣器是通过GPB0 IO口使用PWM信号驱动工作的,而且GPB0口是一个复用的IO口,要使用它得把他设置成TOUT0 PWM输出模式。

   蜂鸣器可以发声,靠的不仅仅是蜂鸣器硬件的驱动,还有linux下的PWM(脉冲宽度调制)这种变频技术,靠改变脉冲宽度来控制输出电压,通过改变周期来控制其输出频率。通过改变频率可以使蜂鸣器发出不同的声音。

二.修改内核代码

[leiyuxing@centos6 linux-3.0]$ vim ./arch/arm/mach-s3c2440/mach-smdk2440.c
235 #include <linux/gpio.h>  //add by leiyuxing,2016.8.18
236 /* beeper add by leiyuxing 2016.8.18*/
237 static struct platform_device smdk2440_beeper_device= {
238 .name= "pwm-beeper",
239 .dev= {
240 .parent = &s3c_device_timer[0].dev,//采用具有PWM脉冲宽度调制功能的定时器0;
241 .platform_data = 0,
242 },
243 .id= 0,
244 };
245 /* beeper add by leiyuxing 2016.8.18*/
246
247 static struct platform_device *smdk2440_devices[] __initdata = {
248 &s3c_device_ohci,
249 &s3c_device_lcd,
250 &s3c_device_wdt,
251 &s3c_device_i2c0,
252 &s3c_device_iis,
253 &s3c_device_dm9000,
254 &uda1340_codec,
255 &s3c24xx_uda134x,
256 &samsung_asoc_dma,
257 &s3c_device_adc, /* modify by leiyuxing */
258 &s3c_device_ts, /* modify by leiyuxing */
259 &s3c_device_rtc,//add by leiyuxing
260
261
262 &s3c_device_timer,//add by leiyuxing,2016.8.18
263 &smdk2440_beeper_device,//add by leiyuxing,2016.8.18
264 };

288 static void __init smdk2440_machine_init(void)
289 {
290 s3c24xx_fb_set_platdata(&smdk2440_fb_info);
291 s3c_i2c0_set_platdata(NULL);
292 s3c24xx_ts_set_platdata(&smdk2440_ts_cfg);/*Add Touch Screen info by leiy uxing*/
293
294 /* PWM beeper add by leiyuxing 2016.8.18*/
295 gpio_request(S3C2410_GPB(0),"beeper");//IO口使用GPB0
296 s3c_gpio_setpull(S3C2410_GPB(0), S3C_GPIO_PULL_NONE);
297 s3c_gpio_cfgpin(S3C2410_GPB(0), S3C2410_GPB0_TOUT0);//设置为TOUT0 PWM输出模式
298 /* PWM beeper add by leiyuxing 2016.8.18*/

三.我们进到drivers/input/misc目录下的Kconfig文件中找到并修改注释掉

[leiyuxing@centos6 linux-3.0]$ vim drivers/input/misc/Kconfig
321
322 config INPUT_PWM_BEEPER
323 tristate "PWM beeper support"
324 #depends on HAVE_PWM //注释掉
325 help
326 Say Y here to get support for PWM based beeper devices.
327
328 If unsure, say N.
329
330 To compile this driver as a module, choose M here: the module will be
331 called pwm-beeper

四.修改内核配置并检验效果

[leiyuxing@centos6 linux-3.0]$make menuconfig

SystemType --->
[ * ] PWM device support

DeviceDrivers --->
Input device support --->
[* ] Miscellaneous devices --->
< * > PWM beeper support
- * - Pules-Width Modulation (PWM) Supprot --->
--- Pulse-Width Modulation (PWM) Support
- *- Samsung pwmsupport

到此,蜂鸣器的简单驱动配置就已经完成了,编译后烧进内核中重启后在启动内核成功时就能听到哔的一声了,这说明蜂鸣器已经配置正确可以使用了。另外在启动的过程中,系统会输出下列语句:

 

s3c2440 PWM使用之蜂鸣器驱动移植_脉冲宽度_03

我们也可以通过查看输入子系统的设备来进一步确认:

 

s3c2440 PWM使用之蜂鸣器驱动移植_3c_04

当然这是最简单的,并没有调整修改频率而发出来的声音。