电子产业一站式赋能平台

PCB联盟网

搜索
查看: 298|回复: 0
收起左侧

一个通道如何捕获PWM的频率和占空比?

[复制链接]

397

主题

397

帖子

2463

积分

三级会员

Rank: 3Rank: 3

积分
2463
发表于 2023-12-29 21:00:00 | 显示全部楼层 |阅读模式

ng4fx2lx5ap64087483623.png

ng4fx2lx5ap64087483623.png
; V4 L) O% r& d1 W0 V

1 D3 Y3 Z# }  e# h6 c# H) ?7 D4 o一,前言
" w# a" X& x  B  M6 r( B2 V* }正常情况是双通道捕获PWM波,这种方法简单且准确,但是它占用的资源太多了,因为它使用定时器的两个通道,且这两个通道映射在一个通道上,同时配置一路捕获为触发定时器复位,所以只能使用2个通道来捕获。虽然也实现了捕获 PWM 的功能,但是代价也太大了,且很难同时捕获多个 PWM ,那有没有更好的方法呢?本文介绍了另一种捕获 PWM 的方法,只使用任何一路定时器的输入捕获,就可以测 PWM 的频率和占空比。0 \2 ]% x9 n' }4 A9 T% A3 p6 D
二、捕获PWM原理4 N; M3 `0 @& }, e- Q

pkbuygrpzwx64087483723.png

pkbuygrpzwx64087483723.png
: G3 I. z+ f6 h' j& p4 z
双通道就是上图的原理,利用两路输入捕获上升沿和下降沿,就能很简单的测出 PWM 频率和占空比。
' g2 M' }  ^$ x# V; t

tjxmpor3es264087483823.png

tjxmpor3es264087483823.png
6 f3 q( x$ @% s0 P) u
分析上图,最开始捕获上升沿,在上升沿到来后开始捕获,然后转为捕获下降沿,捕获接下来的两个下降沿,依据两个下降沿之间计数的差值即可计算出PWM的总脉宽,从而计算出PWM频率,然后由第一个下降沿的计数值可以计算得出PWM高电平的脉宽,即可计算出PWM的占空比。有的人可能会问,那我为什么不可以以上升沿开始捕获,然后连续捕获下降沿和下一个上升沿呢?理论上这样是绝对没问题的,但是你想过没有,既然可以这样,那么 《STM32参考手册》上为什么要用两路输入捕获来测PWM?问题就在于 PWM的占空比以及频率。当PWM频率很快的时候,上升沿和下降沿切换的速度很快,而用一路输入捕获在很短的时间内切换捕获上升沿以及下降沿,很可能导致上升沿或者下降沿没捕捉到的情况。就比如PWM高电平的时间很短,你刚捕获到上升沿,然后切换捕捉下降沿,结果PWM的下降沿已经过去了。使用我的方法测PWM波的时候,从图中可以看到,至少两个下降沿的捕获是不会有问题的,也就是说,PWM频率的测量是不会出错的。而在从捕获上升沿到切换捕获下降沿的时候,上述捕获不到的问题依然会发生,那为什么我的方法就可以而其他方法就不行呢。原因就在于,上面已经提到过,我的方法PWM脉宽测量是没问题的,那么我就可以比较第一个下降沿时的计数值CNT1和CNT2(PWM脉宽的计数值),如果CNT1大,那表示遗漏了一个下降沿,那么高电平的计数值为CNT1-CNT2,反之高电平的计数值为CNT1。
3 K8 i  q9 L6 K( ^/ R

bs321h04nng64087483923.png

bs321h04nng64087483923.png
* U! H. M$ X: M; x6 V4 i5 W; Y1 g
3 D% E( j. }5 G; x4 C, z2 l/ r
一路输入捕获的配置比两路的配置简单,就是普通的输入捕获。具体的代码这里就不贴出来了,可以去参考我上一篇文章。这里把关键的捕获中断服务函数贴出来:代码如下:
  • u8  TIM5CH1_CAPTURE_STA=0;  //输入捕获状态static u16 TIM5CH1_CNTTIME=0;u32  TIM5CH1_CAPTURE_VAL=0;  //输入捕获值u32 TIM5CH1_CAPTURE_HIGHVAL=0; //定时器5中断服务程序   void TIM5_IRQHandler(void){   if(!(TIM5CH1_CAPTURE_STA&0X80))//还未成功捕获{if (TIM_GetITStatus(TIM5, TIM_IT_Update) != RESET){if(TIM5CH1_CAPTURE_STA&0X40)//已经捕获到高电平了{TIM5CH1_CAPTURE_VAL+=65536;}TIM_ClearITPendingBit(TIM5, TIM_IT_Update); //清除中断标志位}if (TIM_GetITStatus(TIM5, TIM_IT_CC1) != RESET)//捕获1发生捕获事件{if(TIM5CH1_CAPTURE_STA&0x20)           //捕获到第二个下降沿{TIM5CH1_CAPTURE_STA|=0X80;TIM5CH1_CAPTURE_VAL+=TIM5->CCR1-TIM5CH1_CNTTIME-TIM5CH1_CAPTURE_HIGHVAL;if(TIM5CH1_CAPTURE_HIGHVAL>TIM5CH1_CAPTURE_VAL)TIM5CH1_CAPTURE_HIGHVAL-=TIM5CH1_CAPTURE_VAL;else if(TIM5CH1_CAPTURE_HIGHVAL==TIM5CH1_CAPTURE_VAL)TIM5CH1_CAPTURE_HIGHVAL=0;TIM5->CCER &= ~(11);         //CC1P=0 设置为上升沿捕获}else if(TIM5CH1_CAPTURE_STA&0X40)    //捕获到第一个下降沿{TIM5CH1_CAPTURE_STA|=0X20;    //标记成功捕获到一次下降沿TIM5CH1_CAPTURE_HIGHVAL=TIM5CH1_CAPTURE_VAL+TIM5->CCR1-TIM5CH1_CNTTIME;}else                            //还未开始,第一次捕获上升沿{TIM5CH1_CNTTIME=TIM5->CCR1;TIM5CH1_CAPTURE_VAL=0;TIM5CH1_CAPTURE_STA|=0X40;    //标记捕获到了上升沿TIM5->CCER |= (11);            //CC1P=1 设置为下降沿捕获}TIM5->SR&=0xfffd;//      TIM_ClearITPendingBit(TIM5, TIM_IT_CC1); //清除中断标志位}   }elseTIM_ClearITPendingBit(TIM5, TIM_IT_CC1|TIM_IT_Update); //清除中断标志位}
    * L1 T7 Y, f; Q) b==========
    , ~+ h5 c" E, P1 a7 x& Z往期回顾:
    ( W$ ]; Q* Z7 B) N  O1 cMCU需要去耦电容的原因
    , d* x0 d7 y" _3 BMCU厂商推荐的外围敏感电路设计
    - u( r% e- L5 d; X& \' X0 V国产单片机的输出比较是小思考+ ?& t2 ~1 J) K7 H: O9 K2 e1 r
    MCU厂商推荐的外围敏感电路设计/ i3 U' |. c% f
    GD32F470的RTC时间设置和获取
    $ s# i* c& p7 v  K6 X: D5 `2 r==========
    % ~  F) j) R7 L* {$ L原文:点击阅读原文
    4 G/ E. H0 z; I. |作者:崖tt
    ; x5 X- V6 j) L$ }1 E# k3 N平台:CSDN! ~' y  t; i& j( @

    katptb14mpz64087484023.png

    katptb14mpz64087484023.png

    7 \& L: Q: X' K( c
    2 P9 a8 h% c8 P

    w2czdwied3s64087484124.png

    w2czdwied3s64087484124.png
    & u0 q" }9 a" ~1 s

    ( S, ]5 K* ?$ F4 c: Q

    ling3e4lvcv64087484224.png

    ling3e4lvcv64087484224.png
  • 回复

    使用道具 举报

    发表回复

    您需要登录后才可以回帖 登录 | 立即注册

    本版积分规则


    联系客服 关注微信 下载APP 返回顶部 返回列表