0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

阻塞方式、中断方式以及定时器捕获功能

电子设计 来源:电子设计 作者:电子设计 2022-02-10 10:12 次阅读

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 (PWM_IN()) //等待下降沿

{

if (TH1 》= T1_TIMEOUT) //下降沿没有到来,判定为100%占空比

{

duty = 100;

return duty;

}

}

TH1 = 0;

TL1 = 0;

while (!PWM_IN()) //等待上升沿

{

if (TH1 》= T1_TIMEOUT) //上升沿没有到来,判定为0%占空比

{

duty = 0;

return duty;

}

}

pwm_L = (TH1 《《 8) | TL1;

TH1 = 0;

TL1 = 0;

while (PWM_IN()) //等待下降沿

{

if (TH1 》= T1_TIMEOUT) //下降沿没有到来,判定为100%占空比

{

duty = 100;

return duty;

}

}

pwm_H = (TH1 《《 8) | TL1;

duty = pwm_H * 100 / (pwm_H + pwm_L);

return duty;

}

else //当前为低电平,则开始等待高电平

{

TH1 = 0;

while (!PWM_IN()) //等待上升沿

{

if (TH1 》= T1_TIMEOUT) //上升沿没有到来,判定为0%占空比

{

duty = 0;

return duty;

}

}

TH1 = 0;

TL1 = 0;

while (PWM_IN()) //等待下降沿

{

if (TH1 》= T1_TIMEOUT) //下降沿没有到来,判定为100%占空比

{

duty = 100;

return duty;

}

}

pwm_H = (TH1 《《 8) | TL1;

TH1 = 0;

TL1 = 0;

while (!PWM_IN()) //等待上升沿

{

if (TH1 》= T1_TIMEOUT) //上升沿没有到来,判定为0%占空比

{

duty = 0;

return duty;

}

}

pwm_L = (TH1 《《 8) | TL1;

duty = pwm_H * 100 / (pwm_H + pwm_L);

return duty;

}

return 0xFF;

}

2. 中断方式

中断方式的PWM采集原理与阻塞方式相同,只是将判定移动至外部中断中。开启MCU端口的外部中断(上升沿和下降沿中断);如果MCU外部中断触发不支持上升和下降沿中断,则先开启上升沿中断,在中断处理中切换中断触发条件。

处理方法:在中断处理函数中,根据当前电平状态,记录下定时器的值,并清零定时器的值,重新开始下一轮计时。

0%和100%的处理:设定一个定时递增的变量,同时在外部中断中执行清零操作。若该变量超过一定值(说明外部中断有较长时间没有触发),则判定为0%或100%。

uint16_t pwm_H = 0;

uint16_t pwm_L = 0;

uint16_t pwm_time_out = 0;

void EXT1_ISR(void) interrupt EXTI1_VECTOR

{

if (PWM_IN())

{

pwm_L = (TH1 《《 8) | TL1; //记录低电平时间

TH1 = 0;

TL1 = 0;

}

else

{

pwm_H = (TH1 《《 8) | TL1; //记录高电平时间

TH1 = 0;

TL1 = 0;

}

//该变量定时递增(如1ms递增1),在外部中断中清零

//在主程序中判断,超过一定值时认为PWM占空比为0%或100%

pwm_time_out = 0;

return;

}

注:使用中断方式,则占空比计算不建议放在中断中处理;同时,为了保证占空比的准确性,可以连续2-3次计算结果一致时,再确定当前占空比的结果。

3. MCU捕获方式

采用捕获方式的前提是MCU支持捕获功能。当前部分厂家推出的51内核单片机,会包含一个定时器2,其拥有捕获功能;或者采用32位单片机,一般都带有捕获功能。捕获的原理很简单,当上升沿或下降沿来临时,MCU硬件将定时器/计数器的值保存在一个影子寄存器中,并产生捕获中断。

通过固定每次上升/下降沿的计数器值,相减即可分别得出高电平值和低电平值,从而计算出占空比。

100058870-112761-1.png

下面以某颗51内核的MCU为例,提供示例代码:

unsigned int pwm_fall = 0, pwm_rise = 0;

volatile unsigned int pwm_H;

volatile unsigned int pwm_L;

volatile unsigned char pwm_time_out;

//------------------------------------------------------------

void T2_interrupt(void) interrupt 5 //定时器2中断;

{

if (CCCON & 0x02) //CC1中断标志位

{

CCCON &= 0xFD; //清除中断标志

if (PWM_IN()) //上升沿触发

{

pwm_rise = CC1; //获取捕获寄存器中的值

pwm_L = pwm_rise - pwm_fall;

}

else

{

pwm_fall = CC1; //获取捕获寄存器中的值

pwm_H = pwm_fall - pwm_rise;

}

//该变量定时递增(如1ms递增1),在外部中断中清零

//在主程序中判断,超过一定值时认为PWM占空比为0%或100%

pwm_time_out = 0;

}

}

注: pwm_rise/pwm_fall/pwm_L/pwm_H都必须使用无符号数,否则相减时可能得到错误的值。

总结

方式一:任何单片机都可以实现,但是阻塞方式会使系统的实时性变差;

方式二:在使用时,需要保证外部中断的最高优先级,不可以被其他中断打断,以保证其准确性;

方式三:的稳定性和准确性都较高,但是需要MCU硬件支持。

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。

本文链接:https://blog.csdn.net/crazy_kismet/article/details/102756206

审核编辑:何安

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 单片机
    +关注

    关注

    6030

    文章

    44505

    浏览量

    632424
  • PWM
    PWM
    +关注

    关注

    114

    文章

    5125

    浏览量

    213301
  • 占空比
    +关注

    关注

    0

    文章

    97

    浏览量

    29030
收藏 人收藏

    评论

    相关推荐

    STM32CUBEMX(5)--自定义红外NEC解码,定时器TIM捕获方式

    (TIM_HandleTypeDef *htim) { uint32_t fallingCount = 0 ; // 下降沿计数 uint8_t temp = 0 ; // 判断是否是定时器1的外部捕获口2
    发表于 09-05 16:19

    定时器的基本组成和工作模式

    定时器是计算机或电子设备中常见的一个硬件或软件组件,其主要功能是测量和控制时间的流逝。它在各种应用中起着至关重要的作用,如操作系统调度、多媒体播放、网络通信、工业自动化控制以及家电设备的定时
    的头像 发表于 08-19 18:28 919次阅读

    定时器的工作方式介绍

    定时器是计算机和嵌入式系统中常见的一种硬件模块,用于实现定时和计数功能定时器的工作方式通常由一组寄存
    的头像 发表于 07-12 10:29 686次阅读

    定时器相关的寄存有哪些类型

    在微控制编程中,定时器是一种非常常见的功能模块,用于实现各种定时和计数功能定时器的工作原理是
    的头像 发表于 07-12 10:25 722次阅读

    STM32的GPIO引脚能同时用作外部中断定时器输入捕获吗?

    今天突然在项目中想到一种用法,将GPIO的某一个引脚,同时配置外部中断(在中断中做一些逻辑)和复用为定时器的输入捕获引脚。 查看GPIO的原理框图,感觉可行。找个机会试试这种用法,于是
    发表于 05-09 08:22

    如何实现一个软件定时器

    在Linux,uC/OS,FreeRTOS等操作系统中,都带有软件定时器,原理大同小异。典型的实现方法是:通过一个硬件定时器产生固定的时钟节拍,每次硬件定时器中断到,就对一个全局的时间
    的头像 发表于 04-29 11:00 576次阅读

    使用dma的方式来传输定时器输入捕获的数据,是不是每隔100ms会触发dma的传输完成中断?

    目前使用dma的方式来传输定时器输入捕获的数据,内存数据大小为2,使用normal模式,100ms打开dma模式,请问,这种情况下,是不是每隔100ms会触发dma的传输完成中断? 这
    发表于 04-18 07:47

    如果STM32定时器外接了正交编码,该剩余通道是否能做PWM输出呢?

    其实,对于STM32芯片,编码输入信号就是定时器的计数时钟源之一。定时器外接了编码输入,若还有剩余通道的话,剩余通道依然可以实现输入捕获或输出比较功能
    的头像 发表于 03-21 09:06 1379次阅读
    如果STM32<b class='flag-5'>定时器</b>外接了正交编码<b class='flag-5'>器</b>,该剩余通道是否能做PWM输出呢?

    单片机外部中断定时器中断的区别和用法

    单片机外部中断定时器中断在触发来源、应用场景以及功能特点上存在明显差异** **。
    的头像 发表于 01-28 17:35 2821次阅读

    555定时器的基本功能 555定时器的工作原理及其应用

    555定时器是一种非常常见和常用的集成电路,它具有广泛的应用领域,例如计时、频率分频、脉冲宽度调制等。本文将详细介绍555定时器的基本功能、工作原理以及应用。 一、555
    的头像 发表于 01-18 11:12 1.4w次阅读

    通用定时器具有什么功能和作用

    通用定时器是一种常见的电子设备,具有广泛的应用领域。它的主要功能是根据设定的时间参数,控制和管理各种电气设备的开关,并按照预定时间进行操作。通用定时器的作用十分重要,不仅在日常生活中有
    的头像 发表于 12-29 10:21 3038次阅读

    51单片机定时器定时1秒程序流水灯结果分析

    流水灯的设计原理、实现步骤和结果分析。 一、设计原理 在51单片机中,定时器常用的工作方式有两种:定时器模式和计数模式。定时器模式是指
    的头像 发表于 12-26 14:57 6478次阅读

    定时器阻塞线程吗 定时器指令有哪几种

    定时器阻塞线程吗 定时器指令有哪几种  定时器一般不会阻塞线程,但具体是否会阻塞取决于所使用的
    的头像 发表于 12-19 14:03 877次阅读

    STM32定时器时间计算方法

    STM32微控制定时器模块在嵌入式系统中非常常见,它被用于产生精确的时间延迟,或者用于实时时钟(RTC)等功能。为了充分利用STM32的定时器
    的头像 发表于 12-19 11:31 1.1w次阅读

    间歇定时器怎么使用?定时器时间间隔程序浅析

    间歇定时器的作用是重复执行一个函数,且不会阻塞主线程。这种类型的定时器常用于间隔性地自动执行代码,例如网页中的倒计时。
    的头像 发表于 12-14 15:16 1279次阅读