> 文档中心 > 【51】PWM控制使用

【51】PWM控制使用


PWM,英文名Pulse Width Modulation,是脉冲宽度调制缩写,它是通过对一系列脉冲的宽度进行调制,等效出所需要的波形(包含形状以及幅值)。

通过调节占空比的变化来调节信号、能量等的变化,占空比就是指在一个周期内,信号处于高电平的时间占据整个信号周期的百分比,例如方波的占空比就是50%(周期T - 低电平T2 = 占空比)

2.怎么实现单片机的PWM引脚输出呢?

(1)可以通过芯片的PWM引脚输出。这种自带有PWM输出功能的芯片在程序设计方面更加简便,同时数据更精确,输出更加平滑,一般来说芯片都会标注明PWM引脚。

(2)对于没有PWM引脚的芯片可以通过模拟输出PWM信号实现。其实PWM 信号其实就是一高一低不同时间的一系列电平组合在一起,可以通过定时器计数来实现此类功能。这类方法对于精度、频率等要求不是很高的场合可以这样做。

 PWM信号通常应用于很多场景,比如蜂鸣器驱动,直流电机调试,灯光调光等。

比如呼吸灯,其实就是利用了余辉效应:

呼吸灯的开关频率速度非常快,人眼捕抓的速度有限,通过PWM(脉宽调制)输出驱动LED,逐渐增加PWM的占空比(高电平时间)从而实现LED模拟呼吸的过程,即渐亮再渐暗再渐亮再渐暗.......如此往复,再利用LED的余辉和人眼的暂留效应,所以看上去就和人的呼吸一样。

3.应用实例(通过51演示)

8051系列的单片机由于是没有PWM引脚的,所以我们通过普通引脚输出信号模拟PWM的方式实现呼吸灯效果。

3.1呼吸灯

#include //8051单片机呼吸灯程序 (简易版) sbit LED = P2^0;//定义接LED的IO口 void Delay(unsigned int t)    //一个非常快的延时函数,用于改变LED亮灭的时间 {while(t--);}void main(){while(1){  unsigned int Time;  for(Time=0;Time=600 结束   LED=0;    //LED灭 ,使用开发板P2口LED这里改成=1  Delay(600-Time);//总的时间 - 亮的时间 = 灭的时间  }  for(Time=600;Time>0;Time--)  //由亮到暗     {  LED=1;//LED亮 ,使用开发板P2口LED这里改成=0  Delay(Time);//亮的时间从600开始减,一直到0结束   LED=0;    //LED灭 ,使用开发板P2口LED这里改成=1  Delay(600-Time);//总的时间 - 亮的时间 = 灭的时间  } }}

3.2 按键调档位(定时器方式)

#include sbit LED = P2^0;//定义电机sbit Key_1 = P3^1; //定义按键 unsigned char Counter,Compare;//计数值和比较值,用于输出PWMunsigned char KeyNum,Speed;//全局变量存放按键返回值,占空比速度/**  * @brief  延时函数,1ms@11.0592MHz 误差 -0.651041666667us  * @param  无  * @retval 无  */void Delay(unsigned int i)  {   unsigned char a,b;    for(;i>0;i--)      for(b=102;b>0;b--) for(a=3;a>0;a--);}/**  * @brief  定时器0初始化,100us@11.0592MHz  * @param  无  * @retval 无  */void Timer0_Init(void){TMOD &= 0xF0;//设置定时器模式TMOD |= 0x01;//设置定时器模式TL0 = 0xA4;    //设置定时初始值TH0 = 0xFF;    //设置定时初始值   高八位低八位0xFFA4 组成 100us TF0 = 0;    //清除TF0标志TR0 = 1;    //定时器0开始计时ET0=1;    //允许定时器T0中断EA=1;     //开启总中断PT0=0;     //优先级为低}/**  * @brief  获取独立按键键码  * @param  无  * @retval 按下按键的键码,范围:0~1,无按键按下时返回值为0  */   unsigned char Key(){unsigned char KeyNumber = 0;//键码初始值为0 if(Key_1 == 0)//按键按下 {    Delay(20);//按键消抖 Delay(20) = 20ms   while(Key_1 == 0);//等待按键释放   Delay(20);   KeyNumber = 1;//键码值变为 1 }return KeyNumber;   //返回键码值}/**  * @brief  主程序  * @param  无  * @retval 无  */void main(){Timer0_Init();//定时器初始化while(1){KeyNum=Key();if(KeyNum==1)//按键按下{Speed++;//速度加1Speed%=4;//速度范围0~3,等于4的时候清0if(Speed==0) {Compare=0;}   //速度0档,PWM占空比为0if(Speed==1) {Compare=25;}  //速度1档,PWM占空比为25if(Speed==2) {Compare=60;}  //速度2档,PWM占空比为60if(Speed==3) {Compare=100;}    //速度3档,PWM占空比全速}}}void Timer0() interrupt 1 //进入定时器中断{TL0 = 0xA4;    //重新赋初始值 TH0 = 0xFF;Counter++; //计数值自加 Counter%=100; //计数值变化范围限制在0~99if(Counter < Compare) //计数值小于比较值 LED = 1; //输出高电平 点亮 (注意:51开发板LED为低电平点亮)    else//计数值大于比较值   LED = 0; //输出低电平 熄灭 }

相关资料链接:

延时函数的计算方法http://t.csdn.cn/4yiAb

51定时器详解http://t.csdn.cn/lYJOY

由于工作问题,博客也很少更了,在这里也希望自己的一些文章能帮到大家。

【51】PWM控制使用 《新程序员》:云原生和全面数字化实践 【51】PWM控制使用 50位技术专家共同创作,文字、视频、音频交互阅读