1.你对占空比的理解是对的,但还有一点你漏了,就是频率,或者说一个高低电平的时长也是PWM波的关键参数. 2.你的程序写的效果,单片机只控制一个I/O口的高低电平变换,这样是可以产生PWM波的,但是占空比不稳定,原因在于你这个延时函数本身延时就是不精准的,可以放到中断里做高低电平的转换,这样PWM波的占空比和频率可以稳定一些.当然以上这些是建立在单片机只控制一个IO口也只做高低电平转换的情况下分析的 如果加入其他功能,你这样的程序根本产生不了PWM波, 3.你想问的是不是有些教材上标出了PWM引脚,原因是有些单片机是有硬件PWM,这样可以产生稳定且不受干扰的PWM波. 4.比如说你现在要产生占空比20%的频率固定的PWM波,你这个程序,最后跑出来的占空比可能在20%~50%波动.然后你加一些其他功能(比如按键,LED灯之类的),占空比就飘了,变成10%~90%, 如果改成中断,也就是你说的定时器,固定时间进来改变一下IO的电平,因为时间一样所以可以产生50%的占空比,实际跑出来可能就是48%~52%,同理加上其他一些功能,占空比可能就变成45%~55%,对一些要求不高的设备是可以用的 要是换到硬件PWM那你产生的占空比是固定的,不受你添加的功能影响,除非单片机程序跑飞了 |
不同的单片机具有不同的IO功能。 |
可以的,如果MCU不忙的话,不然会出错的: // 理论上本代码适用所有的51系列(或兼容型号)单片机,可用于制作小玩具之类。 //不使用计数器,不使用中断。。 //测试条件: KEILC51,STC12C5A60S,5V, 蓝色LED #include <reg51.H> #include <string.h> #include <INTRINS.H> #define uchar unsigned char //以下所有与脉冲相关的数值改变,均会影响变化的快慢,可适当调整 #define max_pluse 100 //最大脉宽,这里设为100,适当增减在LED表现为亮度变化的圆滑度 sbit led=P2^1; //LED的控制脚 void pwm_out(char pwm_h); /* void delay(char n)//简单延时,会影响LED变化的时间,看情况插入 { while (n--) { _nop_(); _nop_(); } } *///// void main() { char pwm; while(1) { for(pwm=0;pwm<max_pluse;pwm++) //从0%到100%脉宽变化,在LED上表现为从暗到亮 {pwm_out(pwm);} // for(pwm=max_pluse;pwm>0;pwm--) //从100%到0%脉宽变化,在LED上表现为从亮到暗 {pwm_out(pwm);} // } } void pwm_out(char pwm_h) //产生连续固定的脉宽波 { char j; char k; for (j=0;j<100;j++) //连续脉宽波个数,这里设为100个, { for (k=0;k<max_pluse;k++) //产生单个脉宽波 { ////////////////////////////// if (k<pwm_h) {led=0;} else {led=1;} ///////////////////////////// //led=k/pwm_h; //上面注释中的代码可用此行替代,但可能会增加代码空间 //delay(2); // 加入延时是为了拓宽单个脉冲宽度 } } } |
没什么实际用途,若是固定占空比或许可行,若结合其他功能,肯定存在问题. |
当然可以,只不过有点幼稚而已,受影响极大. |