本帖最后由 billsmate333 于 2013-1-6 17:19 编辑
开发平台:TQ2440,WinCE5.0 测试工具:泰克示波器TDS3012B 测试程序为TQ2440光盘提供的PWMTest工程; 问题描述:系统内核是光盘提供的内核,程序是光盘提供的程序。运行PWMTest程序以后从TOUT0口用示波器看到的方波频率与程序设定的不符;程序设定频率为800,示波器测的的频率为1067左右。为什么计算的频率会和实际输出不一致? 以下为我探究的过程: PWM工作原理: 1)S3C2440芯片的PWM是通过引脚TOUT0~TOUT3输出的,从原理图上看出PWMTest输出为TOUT0因为连接蜂鸣器的引脚是TOUT0; 2)再设置定时器的输出时钟频率,它是以PCLK为基准,再除以用寄存器TCFG0配置的prescaler参数,和用寄存器TCFG1配置的divider参数。 有如下公式: 定时器输出时钟频率=PCLK ÷ (prescaler+1) ÷ divider 其中prescaler值由TCFG0决定,divider值由TCFG1决定,而prescaler只能取0~255之间的整数,divider只能取2、4、8和16。比如已知PCLK为50MHz,而我们想得到某一定时器的输出时钟频率为25kHz,则依据公式可以使prescaler等于249,divider等于8。有了这个输出时钟频率,理论上我们通过设置寄存器TCNTBn就可以得到任意与0.04毫秒(1÷25000×1000)成整数倍关系的时间间隔了。例如我们想要得到1秒钟的延时,则使TCNTBn为25000(1000÷0.04)即可。 3)然后设置脉冲的具体宽度,它的基本原理是通过寄存器TCNTBn来对寄存器TCNTn(内部寄存器)进行配置计数,TCNTn是递减的,如果减到零,则它又会重新装载TCNTBn里的数,重新开始计数,而寄存器TCMPBn作为比较寄存器与计数值进行比较,当TCNTn等于TCMPBn时,TOUTn输出的电平会翻转,而当TCNTn减为零时,电平会又翻转过来,就这样周而复始。因此这一步的关键是设置寄存器TCNTBn和TCMPBn,前者可以确定一个计数周期的时间长度,而后者可以确定方波的占空比。由于s3c2440的定时器具有双缓存,因此可以在定时器运行的状态下,改变这两个寄存器的值,它会在下个周期开始有效。 以上内容来自与CSDN博客, 转化成例程中的代码即以下几句: intfreq = 800; // 工作频率初值 #defineS3C2440_PCLK 50000000 // PCLK是MHz #definePrescaler0 15 // 预分频 #defineMUX0 8 // 定时器分频值 #defineTCNTB0 (S3C2440_PCLK/128/freq) // 工作频率 #defineTCMPB0 (TCNTB0>>1) // 占空比,默认是%50
TCNTB0 = 50M/128/800 最终的频率经过一系列的消去就变成了F=freq,这样,freq的值其实就是最后的输出频率,理论上是这么计算;实际上运行就出现了上述问题;
修改Prescaler0和MUX0 的值为24与4这样MUX0×(Prescaler0+1)正好等于100,设定freq=1000,这样TCNTB0 = 50000000/100/freq = 500能整除。
这样得出的结果还是不行,设定1000得到的结果是1333
用驱动的控制字IOCTL_PWM_GET_FREQUENCY获取频率,得到的值也是1333.
细看驱动代码,发现在PWMDriver.c文件中的第29行 #defineDEFAULT_S3C2440X_PCLK (405000000 / 8) 这个定义的时钟不是50M,大喜,以为问题就出现在这里,遂将PWMTest程序的时钟定义改为 #defineS3C2440_PCLK (405000000 / 8) 结果还是有偏差,这时候得到的频率是1317Hz,不论是从驱动GetFrequency还是用示波器测量,结果都是1317.
现在处于崩溃之中,PWM驱动的代码看的迷迷糊糊的,驱动的流程基本上也了解了,计算方法也没有问题。为什么就是不一样。总是多出一些频率。800变成1067.1000变成1333,貌似每次都增加了33%似的。 等等!既然这个关系都知道了,那我设定频率的时候少设置33%,输出的频率不就正好是我要的频率了么?!!!
终极解决办法:将freq乘以0.75,然后再运行,得到的结果就是1001了,虽然还是有点误差,但是至少比1333强。
可是我还是不明白为什么,我哪里计算的有问题?这可是天嵌提供的例程啊!!例程输出的频率还有问题?驱动蜂鸣器的时候不可能听出差别来,蜂鸣器乌里哇啦的,忽悠忽悠小女生还有点用,但是我对频率的要求比较精确啊~, 大神们,救救我吧~
|