STM32输入捕获PWM频率和占空比(HAL库)

53 阅读2分钟

占空比和频率的计算思路

pwm.png 如上图所示的一个PWM波,占空比可通过高电平所占时间和周期之间的比值计算的得出

占空比=t1/t

PWM频率计算则为:

频率=定时器时钟频率 /(分频系数*周期t)

本次将使用单通道捕获上升沿和下降沿获取高电平所占时间t1和周期t。

实现流程

  1. 在第一次捕获上升沿时将计数器清零,并将下一次捕获设置为下降沿捕获;
  2. 在捕获到下降沿后,将计数器里的值保存起来(这是计数器里的值就是高电平t1),并将下一次捕获设置为上升沿捕获;
  3. 在第二次捕获道上升沿后将计数器里的值保存起来(这时计数器里的值就是周期t)。

后续就可以通过获取到的t1t计算出PWM波的频率和周期了。

CubeMX配置

我使用的时stm32f103c8t6的实验板,先将时钟频率调整为72MHz。

屏幕截图 2026-01-22 151855.png 然后选择TIM2,通道1,将分频系数设置为72-1

屏幕截图 2026-01-22 152208.png 打开中断

屏幕截图 2026-01-22 152431.png

代码部分

生成代码后为我们在中断回调函数中添加以下内容

volatile uint32_t falltime = 0; // 下降沿捕获值
volatile uint32_t periodValue = 0;      // 周期值
volatile uint8_t dutyCycle = 0;        // 占空比(0-100%)
volatile uint8_t captureState = 0;      //电平捕获
volatile uint8_t measurementReady = 0;  // 测量完成标志
void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim)
{
  if (htim->Instance == TIM2){
    switch (captureState){
      case 0: // 捕获到上升沿
        __HAL_TIM_SET_COUNTER(htim,2);//计数器设置为2,(这里按理来说应该设置为0的,但我通过调试发现设置为2准确)
        captureState = 1;
        
        // 切换为下降沿捕获
        __HAL_TIM_SET_CAPTUREPOLARITY(htim, TIM_CHANNEL_1, TIM_INPUTCHANNELPOLARITY_FALLING);
        break;
      case 1: // 捕获到下降沿
        falltime =  HAL_TIM_ReadCapturedValue(htim, TIM_CHANNEL_1);
        captureState = 2;
        
        // 切换为上升沿捕获
        __HAL_TIM_SET_CAPTUREPOLARITY(htim, TIM_CHANNEL_1, TIM_INPUTCHANNELPOLARITY_RISING);
        break;
      case 2: // 第二个上升沿,计算周期
        periodValue = HAL_TIM_ReadCapturedValue(htim, TIM_CHANNEL_1);//周期
        captureState = 0; 
        measurementReady = 1; // 设置测量完成标志
        break;
    }
  }
}

main函数

while (1)
  {
     if (measurementReady){
        // 计算占空比
        if (periodValue != 0){
          dutyCycle = (falltime* 100 / periodValue) ;
          frequency = 72000000 / (72*periodValue);
          // 打印结果
          printf("ZK %d Hz\r\n,PL%d%%\r\n",dutyCycle,frequency);
        }
        measurementReady = 0; // 清除标志
      }
    /* USER CODE END WHILE */
 
    /* USER CODE BEGIN 3 */
  }

测试部分

为了方便拍视频就将结果显示到OLED显示屏上

用示波器生成不同频率,不同占空比的波形供开发板捕获

测试视频