[其他ST产品] STM32实现PWM输出与PWM输入捕获(HAL库)

[复制链接]
 楼主| 大鹏2365 发表于 2023-10-29 00:11 | 显示全部楼层
若有效电平为Low,则上述(3)、(4)公式变为1-Duty,计数方式(向上向下计数)并不影响占空比的计算公式 。
 楼主| 大鹏2365 发表于 2023-10-29 00:12 | 显示全部楼层
其中TimerClock为对应定时器的时钟频率;Prescaler为预分频系数;CounterPeriod为重装载值;CCRx为比较寄存器的值,在代码工程中可以使用函数__HAL_TIM_SetCompare()修改CCRx的值从而修改PWM的占空比。
 楼主| 大鹏2365 发表于 2023-10-29 00:12 | 显示全部楼层
PWM模式一: 在PWM1模式下,无论是向上计数还是向下计数,TIMx_CNT<TIMx_CCR1时通道1为有效电平,有效电平可以在 CH Polarity 参数中设置。
 楼主| 大鹏2365 发表于 2023-10-29 00:12 | 显示全部楼层
PWM模式二: 在PWM2模式下,无论是向上计数还是向下计数,TIMx_CNT>TIMx_CCR1时通道1为有效电平。
 楼主| 大鹏2365 发表于 2023-10-29 00:12 | 显示全部楼层
初始脉冲宽度(Pulse): 脉冲宽度即高电平持续的时间,Pluse与CounterPeriod+1的比值即为PWM的初始占空比。
 楼主| 大鹏2365 发表于 2023-10-29 00:13 | 显示全部楼层
自动预重装载(auto-reload preload): 当使能自动预重装载时,自动重装载寄存器写入新值后,计数器立即产生计数溢出,然后开始新的计数周期;当不使能自动预重装载时,自动重装载寄存器写入新值后,计数器完成当前旧的计数后,再开始新的计数周期。
 楼主| 大鹏2365 发表于 2023-10-29 00:13 | 显示全部楼层
假设采用如上配置,配置TIM2通道一作为PWM输出,只需在代码工程中调用如下两条函数便可以实现PWM的控制。
 楼主| 大鹏2365 发表于 2023-10-29 00:14 | 显示全部楼层
HAL_TIM_PWM_Start(&htim2,TIM_CHANNEL_1);//初始化,开启PWM

__HAL_TIM_SetCompare(&htim2, TIM_CHANNEL_1,1000);//设置比较寄存器CCRx的值,占空比=CCRx/ARRx 此处 CCRx=1000,ARRx=65536
 楼主| 大鹏2365 发表于 2023-10-29 00:14 | 显示全部楼层
STM32 PWM输入捕获
定时器的PWM输入捕获的框图如下,由通用定时器的框图剪裁得到(去掉了一些与输入捕获无关的功能):

99695653d335e43933.png
 楼主| 大鹏2365 发表于 2023-10-29 00:14 | 显示全部楼层
PWM输入捕获流程如下:
1. PWM信号由TIMx_CH1进入,依据是上升沿还是是下降沿从而触发TI1FP1或TI1FP2。
 楼主| 大鹏2365 发表于 2023-10-29 00:14 | 显示全部楼层
2. 当捕捉到第一次上升沿时,触发TI1FP1,计数器复位,计数值CNT清零。

 楼主| 大鹏2365 发表于 2023-10-29 00:15 | 显示全部楼层
3. 当捕捉到下降沿时,触发TI1FP2,CNT计数值在TIMx_CH2中被记录到TIMx_CCR2寄存器中。
 楼主| 大鹏2365 发表于 2023-10-29 00:15 | 显示全部楼层
4. 当再次捕捉到上升沿时,触发TI1FP1,CNT计数值在TIMx_CH1中被记录到TIMx_CCR1寄存器中,同时计数器复位,计数值清零。
 楼主| 大鹏2365 发表于 2023-10-29 00:15 | 显示全部楼层
5. 依据TIMx_CCR1、TIMx_CCR2的值便可以计算PWM的周期、频率、占空比。TIMx_CCR1的值就是周期,T I M x C C R 2 T I M x C C R 1 \frac{TIMxCCR2}{TIMxCCR1}
TIMxCCR1
TIMxCCR2

的值就是占空比。
 楼主| 大鹏2365 发表于 2023-10-29 00:15 | 显示全部楼层
关于PWM的输入捕获,有两种CubeMX的配置方式,虽然配置方式不一样但是效果和原理都是完全一致的。
 楼主| 大鹏2365 发表于 2023-10-29 00:19 | 显示全部楼层
方法一:
这是网上大多数帖子的推荐配置,非常麻烦,这里不推荐使用。

 楼主| 大鹏2365 发表于 2023-10-29 00:19 | 显示全部楼层
 楼主| 大鹏2365 发表于 2023-10-29 00:19 | 显示全部楼层
方法二(推荐使用):

方法二与方法一原理与效果是一样的,只不过ST官方考虑到PWM输入捕获较为常用,可以一键配置。只需在Combined Channels中选择PWM Input on CH1同时打开定时器中断即可。

72427653d348f6f8e2.png
 楼主| 大鹏2365 发表于 2023-10-29 00:19 | 显示全部楼层
配置完成后在代码中完成定时器的中断回调函数,便可计算PWM的占空比、频率、周期。

  1. /**
  2. *  [url=home.php?mod=space&uid=247401]@brief[/url] 定时器中断回调函数
  3. *  [url=home.php?mod=space&uid=536309]@NOTE[/url]  htim 定时器句柄
  4. */

  5. void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim)
  6. {
  7.         if(htim == &htim2)
  8.         {
  9.                 if(htim2.Channel == HAL_TIM_ACTIVE_CHANNEL_1)   
  10.                 {
  11.                         /* 记录TIM2_CCR1的值 */
  12.                         PWM_RisingCount = HAL_TIM_ReadCapturedValue(&htim2,TIM_CHANNEL_1);
  13.                        
  14.                         if(PWM_RisingCount != 0 && PWM_FallingCount!= 0)
  15.                         {
  16.                                 PWM_Duty        = (float)(PWM_FallingCount / PWM_RisingCount);//占空比
  17.                                 PWM_Period      = PWM_RisingCount*0.000001f;                  //周期
  18.                                 PWM_Frequency   = 1/PWM_Period;                               //频率
  19.                         }
  20.                 }
  21.                 else if(htim2.Channel == HAL_TIM_ACTIVE_CHANNEL_2)
  22.                 {       
  23.                         /* 记录TIM2_CCR2的值 */
  24.                         PWM_FallingCount = HAL_TIM_ReadCapturedValue(&htim2,TIM_CHANNEL_2);
  25.                 }
  26.         }
  27. }
 楼主| 大鹏2365 发表于 2023-10-29 00:20 | 显示全部楼层
实战项目
45547653d34af0e56c.png
您需要登录后才可以回帖 登录 | 注册

本版积分规则

快速回复 在线客服 返回列表 返回顶部