#include
#include "stdio.h"
#include "Key.h"
#include "Delay.h"
#include "Timer0.h"
sbit led0 = P1^0;
unsigned int cycle;
int duty=50;
int pwm =100;
char a = 1;
void main()
{
int num;
Timer0Init();
while(1){
num = Key();
if(num)
{
if(num==1)
{
pwm++;
}
if(num==2)
{
pwm--;
}
if(num==3)
{
duty++;
if(duty>100)
duty=0;
}
if(num==4)
{
if(duty==0)
{
duty=100;
}
else
{
duty--;
}
}
}
}
}
void Timer0_Routine() interrupt 1
{
cycle=10000/pwm;
if(a)
{
TL0=(256256-cycleduty)%256;
TH0=(256256-cycleduty)/256;
led0 = 0;
a = 0;
}
else
{
TL0=(256*256-cycle*(100-duty))%256;
TH0=(256*256-cycle*(100-duty))/256;
led0 = 1;
a = 1;
}
}
如初始化输出100HZ和50%占空比的PWM,然后在50%占空比不变的情况下,按键增加频率,大部分没有问题,但是107 108 109 110HZ都会显示大1HZ 26 20 16都会显示小1HZ;频率不变的情况下,调占空比56%检测出来的是55%,频率检测出来为101HZ,57测出来的是57 56之间变,频率在100 101之间变;78卡死,79测出来的也是101HZ,96到99也是101HZ,50以下43 44 22 21 2 3 4也是一样的情况。
猜测应该是定时器内部,用到了乘法导致指令周期变长,所以有的频率和占空比输出就有问题,但是没想到怎么解决
单片机一开始输出100HZ和50%占空比的PWM,然后按键可以控制占空比和频率的增加和减小(1HZ和1%),需要至少90到100HZ之间可以精确输出每个HZ和某个占空比。
是数据精度处理的问题,不管是整型,还是浮点型,运算过后要转换成对应的频率或者占空比,我们运算的时候按10进制,比如1000,但是要给机器的时候,只能按1024来,可能没办法解决
把你定时器里面的cycle=10000/pwm计算放在定时器外面如按键处理里面处理,影响定时精度,也没必要每一个定时周期都计算一次,中断里面的语句尽量要少。既然是几个特定频率的计算有问题,可以看看在这个频率时的th和Tl都和计算值预期是否一致,应该不难查
你先参考这个实例是否对你有所帮助,链接:https://www.csdn.net/tags/Mtzacg0sMzgxNzMtYmxvZwO0O0OO0O0O.html
可以考虑定时器用固定周期,对周期计数来决定输出高低,这样定时器就不会因为一些精度问题导致频率不一致