#define uchar unsigned char
uchar pwm=50,cnt
sbit pluse=P1^0
sbit keyu=P1^4
sbit keyd=P1^5
void t0isr() interrupt 1
{
TH0=(65536-100)/256
TL0=(65536-100)%256
cnt++
if(pwm>0)
{
if(cnt>旅滑100)cnt=0
if(cnt<=pwm)pluse=1
else pluse=0
}
else pluse=0
}
main()
{
TMOD=0x01
TH0=(65536-100)/256
TL0=(65536-100)%256
TR0=1
ET0=1
EA=1
while(1)
{
if(keyu==0)
{
while(keyu==0)
pwm++
if(pwm>100)pwm=100
}
if(keyd==0)
{
while(keyd==0)
if(pwm>0)pwm--
}
}
}
80S52没有硬件PWM功能,靠定时器中断很简单,只不过频率不能太高,或调
节精度比较差
下面是双定时器产生PWM主要语句:
TMOD=0X11
TH0=(65536-20000)/256//
定时20ms
TL0=(65536-20000)%256
TH1=(65536-b)/256//定时要小于20ms,改变b的值即改变占空比
TL1=(65536-b)%256
ET0=1
EA=1
TR0=1
PWM=1
b=2000
while(1)
void
timer0()interrupt
1
{
TH0=(65536-20000)/256
TL0=(65536-20000)%256
PWM=1
TR1=1
ET1=1
}
void
timer1()interrupt
3
{
TH1=(65536-b)/256
TL1=(65536-b)%256
PWM=0
TR1=0
ET1=0
}
定时器0中断负蔽早神责每
20ms将管脚置
1,定时1负责在20ms之内的某一时间将该管脚清0
当然也可以采用自动宏亏重装方式,中断可以更频繁一些,产生的PWM频率要高一些
也可以只用一个定时器,这时产生PWM波要么频率低,要么调节精度差睁此,因中断一次至少10US,你就不用指望一次调节步距10us以下了
哥们,这个已经很详细了;大概说说吧,PWM[54]是定义的一组PWM脉宽输出数组,PWM脉宽输出是0-255;0的时候脉宽输出最大,255的时候脉宽输出最小;
然后那个初始化PCA,初始化定时器0就不说了,你自己下一个手册看下就明白;
然后是中断,每中断一次index加1,然后判断index是不是等于54,意思就是PWM[54]整个数组里面的PWM是不是都送了一次CCAP寄存器;如果都数组都送了一次,将index置零,从头开始送;标志位取反,如果标志位zf=1,让P14输出PWM,P13关闭;,如果zf=0,让P13输出PWM,P14关闭;if(zf==0)后面的语句就是让PWM[54]中的每一个数都送CCAP寄存器一次;
其实按这个程序注释的话,他本意是PWM波形从小变大P14输出,PWM波形有大变小P13输出;但是这个程序的实际效果是P14由小巧戚芹变大再由大变小。然后P14关闭,P13由小变大再由大变小
如此循环;
你最关心的PWM怎么输出:就是这两个语句,CCAP0H=pwm[index] CCAP1H=pwm[index] index每中断一次加1,那么index是由0加到54,假如说index=0 ,那孝毕么CCAP0H=pwm[0],pwm[0]对应数字里面的255,寄存器CCAP0H=255;这个寄存器等于255,PWM输出就是一个小脉宽;下一次中断CCAP0H=240了,脉宽有增加了一点;至于CCAP0H送一个数据就有脉宽输出,这个是由单片机硬件本身仔氏决定的;你看看手册就知道了;
这个已经说得很明白了吧;累死,打字都打了20分钟;
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)