使用stm32的HAL庫完成pwm輸入模式測量頻率和佔空比的詳細教程

STM32定時器具有PWM輸入捕獲模式。

PWM輸入捕獲是定時器輸入捕獲的一個特例,單通道的輸入捕獲只能獲取波形的頻率,但是PWM輸入捕獲可以獲取到頻率和佔空比,對應的高低電平寬度也就能獲取到。 它的時序如下圖所示:

 使用cubemx配置方法:

 就是使用TIM2的ch1和ch2來捕獲一個pwm信號。

這裏只測試了update event,我測試55khz使用該分頻與計數值可以正常工作,不過第一次捕獲的數據是隨機數,需要丟棄。另外這裏分頻值我改成89的時候不太正常,捕獲到的佔空比出現錯誤,更改爲0之後正常。這裏需要注意的是F429的TIM2是在APB1下,時鐘頻率90Mhz。而TIM1/TIM8則是在APB2下。

 然後使能TIM2的中斷

接下來添加代碼:

main.c 中開啓捕獲中斷

    /* USER CODE BEGIN 2 */
    HAL_TIM_IC_Start_IT(&htim2, TIM_CHANNEL_1);
    HAL_TIM_IC_Start_IT(&htim2, TIM_CHANNEL_2);//如果不需要佔空比和頻率數據就只開通道2即可。第一次的數據是不正確的,實際工作中要將第一次的數據丟棄
    /* USER CODE END 2 */    

  /* USER CODE BEGIN WHILE */
  while (1)
  {

    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
    if (tmp1 == 0)
    {
        duty = 0;
        freq = 0;
    }
    else
    {
        duty = tmp2 * 100.0f / tmp1 + 0.5f;
        freq = 90000000.0f / tmp1;
    }
			
    printf ("freq: %d Hz\tduty: %d %%\r\n", freq, duty);
    printf ("tmp1: %d\t%d\r\n", tmp1, tmp2);
    printf ("pos pulse= %lf\r\n", tmp1 * 1.111111111111111e-8);// 這個1.xe-8就是90M時鐘分之一
    HAL_Delay(500);
  }
  /* USER CODE END 3 */

 然後添加TIM2的中斷回調函數:

/* USER CODE BEGIN 1 */

uint32_t duty = 0;
uint32_t freq = 0;

void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim)
{
    volatile static uint32_t tmp1 = 0, tmp2 = 0;
    
    if (htim->Channel == HAL_TIM_ACTIVE_CHANNEL_1)
    {
        tmp1 = HAL_TIM_ReadCapturedValue(&htim2, TIM_CHANNEL_1);//週期
    }
    else if (htim->Channel == HAL_TIM_ACTIVE_CHANNEL_2)
    {
        tmp2 = HAL_TIM_ReadCapturedValue(&htim2, TIM_CHANNEL_2);//佔空比
    }
    
    
}
/* USER CODE END 1 */

 這裏計算出的duty和freq就是佔空比和頻率,下邊加上0.5只是爲了四捨五入,不需要的可以去掉。

這裏的90000000就是定時器的時鐘源,因爲我使用的是F429的TIM2且分頻值配置的爲0, 所以用90000000來除以tmp1就得到頻率,如果用其他定時器或者分頻值的話需要更改這個90000000爲實際的時鐘源頻率

 

這裏有個問題是,當檢測引腳上的PWM信號突然丟失的時候,程序不會將頻率和佔空比清零。可以添加一個計數值,main中累加,檢測中斷中清零,當累加到一定的值就表示外部沒有pwm輸入了,從而判斷出外部中斷的狀態。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章