版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。
单片机测量PWM占空比的三种方法
PWM(Pulse Width Modulation),一般指脉冲宽度调节,是利用微处理器的数字输出来对模拟电路进行控制的一种非常有效的技术,广泛应用在从测量、通信到功率控制与变换的许多领域中,比如LED亮度调节、电机转速控制等。
而在某些特殊应用中,我们也需要通过测量输入PWM的占空比,来实现不同的输出控制,这就需要使用到PWM占空比的测量方法。这里介绍三种不同的测量方法:阻塞方式、中断方式以及定时器捕获功能。
1. 阻塞方式
MCU阻塞方式测量PWM占空比的原理比较简单,也只需要使用到一个普通的IO端口(设置为输入模式,对于51而言那就是一个普通的双向口)。具体实现流程为:
等待上升沿到来,然后开启定时器,开始计时;等待下降沿到来,记录下定时器的计数值,即得到PWM的高电平时间H;同时,清零定时器,重新开始计数;等待上升沿到来,记录下定时器的计数值,即得到PWM的低电平时间L;计算得出占空比:duty = H / (H + L);
阻塞方式原理简单,而且只需要MCU有一个定时器的资源即可实现;但采集时阻塞CPU运行,阻塞的时间和输入PWM的周期相关,只适用于实时性较低的系统。
另外,上述流程中存在着一个严重的BUG,即当输入的PWM占空比为0%或者100%时,程序会被一直阻塞,等待上升沿/下降沿的到来。所以解决方法是,在等待上升沿/下降沿的过程中,实时提取定时器的值,一旦定时时间超过1个周期的限定(一般可定义为2-3个周期时间),即退出等待,并根据端口电平判断此时占空比为0%(低电平)或100%(高电平)。
示例代码,仅供参考:
//获取PWM输入脚的电平 #define PWM_IN() xxxxxx //定义超时时间(如2-3倍PWM周期) #define T1_TIMEOUT xxxxxx uint8_t PWM_Analyse(void) { uint8_t duty = 0xFF; uint16_t pwm_H = 0; uint16_t pwm_L = 0; if (PWM_IN()) //初始为高电平,则开始等待低电平 { TH1 = 0; while