s3c2440芯片中一共有5个16位的定时器,其中有4个定时器(定时器0~定时器3)具有脉宽调制功能,即他们都有个输出引脚,可以通过定时器来控制引脚周期性的高低电平变化,定时器4没有输出引脚。上次脱机运行PWM测试程序实验的时候就用到了这块,所以这次将PWM和定时器放在一起来学习。
1.程序初始,先设置TCMPBn、TCNTBn这两个寄存器,分别表示定时器n的比较值和初始计数值。
1.
[7:0],[15:8]各8位分别被用于控制预分频器0,1,值为0~255。经过预分频器出来的时钟频率为:PCLK/(prescaler+1)。
2.
经过预分频器得到的时钟将进入2次分频,这个寄存器就是设置2次分频系数的。这样定时器的工作频率为:PCLK/(prescaler+1)/(dividervalue),其中prescaler=0~255,divider value=2,4,6,8。
3.
TCON寄存器位[3:0]、[11:8]、[15:12]、[19:16]、[22:20]分别用于定时器0~4,位[4]为死区使能位,[7:5]为保留位。除了定时器4没有输出反转位外,其他位功能相似,这里以定时器0为例加以说明。位[0]开启停止位:0停止定时器,1开始定时器。[1]手动更新位:0无用,1将TCNTBn/TCMPBn寄存器的值装入内部寄存器TCNTn\TCMPn中。[2]输出反转:0不反转,1反转。[3]自动加载:0不自动加载,1自动加载。
4.
5.
下面就具体介绍如何实现PWM功能。
1、PWM是通过引脚TOUT0~TOUT3输出的,而这4个引脚是与GPB0~GPB3复用的,因此要实现PWM功能首先要把相应的引脚配置成TOUT输出。
2、再设置定时器的输出时钟频率,它是以PCLK为基准,再除以用寄存器TCFG0配置的prescaler参数,和用寄存器TCFG1配置的divider参数。
3、然后设置脉冲的具体宽度,它的基本原理是通过寄存器TCNTBn来对寄存器TCNTn(内部寄存器)进行配置计数,TCNTn是递减的,如果减到零,则它又会重新装载TCNTBn里的数,重新开始计数,而寄存器TCMPBn作为比较寄存器与计数值进行比较,当TCNTn等于TCMPBn时,TOUTn输出的电平会翻转,而当TCNTn减为零时,电平会又翻转过来,就这样周而复始。因此这一步的关键是设置寄存器TCNTBn和TCMPBn,前者可以确定一个计数周期的时间长度,而后者可以确定方波的占空比。由于s3c2440的定时器具有双缓存,因此可以在定时器运行的状态下,改变这两个寄存器的值,它会在下个周期开始有效。
4、最后就是对PWM的控制,它是通过寄存器TCON来实现的,当不想计数了,可以使自动重载无效,这样在TCNTn减为零后,不会有新的数加载给它,那么TOUTn输出会始终保持一个电平(输出反转位为0时,是高电平输出;输出反转位为1时,是低电平输出),这样就没有PWM功能了,因此这一位可以用于停止PWM。
变相器的开和关决定了初始状态和维持TOUTn的电平的高低。
{
}
首先rGPBCON &=~3;其他位不变,只是把最低2位清0。
rGPBCON |=2;最低2位赋值为10。
这两句话的作用是让GPBCON寄存器最低两位为10,即配置GPB0为复用功能TOUT0作为PWM输出。
rTCFG0&= ~0xff; TCFG0寄存器低8位清0,即使用定时器0。
rTCFG0 |=15;赋值给TCFG0寄存器低8位,prescaler = 15。
rTCFG1&= ~0xf; TCFG1只是最低4位清0,使用定时器0。
rTCFG1 |=2;定时器0二次分频divider value=8。
rTCNTB0 =(PCLK>>7)/freq;这里是配置计时器的计数缓冲寄存器,让PCLK/2^7/freq得到完成一个PWM周期需要计数值。因为通过前面的设置,我们知道定时器的工作频率=PCLK/(15+1)/8=PCLK/(2^7),即PCLK>>7,所以定时器工作频率/PWM freq=计数值。(PWM周期/定时器计一次计数的周期) =计数值,因为计数值*定时器一次技术队周期=PWM的周期。
rTCMPB0 =rTCNTB0>>1; 这里是配置计时器的比较缓冲寄存器,让比较值为初始值的一半,即设定了PWM的占空比为50%。
rTCON&= ~0x1f; 和rTCON |=0xb;这两句同上,给TCON最低5位赋值,开启定时器,第一次使用定时器手动更新以便装入TCNTB0和TCMP0的值,关闭反相器,自动加载,disable 死区。
rTCON&= ~2;
这就完成了PWM的设置。
当我们完成试验退出时用到Buzzer_Stop函数,我们来看这个函数:
voidBuzzer_Stop( void )
{
}
rGPBCON&= ~3;和rGPBCON |= 1;这两句上面已经分析过,是配置GPBCON的,不同是这次让GPBCON最低两位为01,即作为输出功能,不再作为PWM的TOUT了。
rGPBDAT&= ~1;即GPB0输出0,蜂鸣器不发声。
至此PWM蜂鸣器发声实验就分析完了。后面使用蜂鸣器唱歌等实验原理相似,只不过调整声音频率和对于声音频率的延时时长的控制,后面不做分析了。
具体的驱动实现代码:pwm驱动原理和代码实现
引自,http://blog.sina.com.cn/s/blog_8ad7bc620100xhzv.htmlhttp://blog.sina.com.cn/s/blog_8ad7bc620100xhzv.html
致以感谢。