【STM32】HAL庫 STM32CubeMX教程---定時器輸入捕獲

前言:
本系列教程將外設原理,HAL庫與STM32CubeMX結合在一起講解,使您可以更快速的學會各個模塊的使用

 

所用工具:

1、芯片: STM32F407ZET6/STM32F103ZET6

2、STM32CubeMx軟件

3、IDE: MDK-Keil軟件

4、STM32F1xx/STM32F4xxHAL庫 

5

知識概括:

通過本篇博客您將學到:

SMT32定時器輸入捕獲

 測量PWM頻率和佔空比

輸入捕獲
 

輸入捕獲概念
輸入捕獲模式可以用來測量脈衝寬度或者測量頻率。STM32的定時器,除了TIM6、TIM7,其他的定時器都有輸入捕獲的功能。

具體請參看《【STM32】HAL庫 STM32CubeMX教程六----定時器中斷》

輸入捕獲的工作原理


①先設置輸入捕獲爲上升沿檢測,

②記錄發生上升沿時TIMx_CNT(計數器)的值

③配置捕獲信號爲下降沿捕獲,當下降沿到來的時候發生捕獲

④記錄此時的TIMx_CN(計數器)T的值

⑤前後兩次TIMx_CNT(計數器)的值之差就是高電平的脈寬。同時根據TIM的計數頻率,我們就能知道高電平脈寬的準確時間。

 

簡單說:

當你設置的捕獲開始的時候,cpu會將計數寄存器的值複製到捕獲比較寄存器中並開始計數,當再次捕捉到電平變化時,這是計數寄存器中的值減去剛纔複製的值就是這段電平的持續時間,你可以設置上升沿捕獲、下降沿捕獲、或者上升沿下降沿都捕獲,

 

輸入捕獲的工作流程(對應CubeMx的四個選項)


設置輸入捕獲濾波器
STM32在很多功能中都提供了濾波器,濾波器的功能簡單來說就是多次檢測視爲一次有效,達到濾波效果,

數字濾波器由一個事件計數器組成,假設我們是檢測高電平,濾波N次,那麼記錄到N個事件後計數器會產生一個輸出的跳變。也就是說連續N次採樣檢測,如果都是高電平,則說明這是一個有效的電平信號,這樣便可以過濾掉那些因爲某些而干擾產生的一些信號        

輸入捕獲濾波器IC1F[3:0],這個用於設置採樣頻率和數字濾波器長度。其中:fCK_INT是定時器的輸入頻率,fDTS是根據TIMx_CR1的CKD[1:0]的設置來確定的。

設置輸入捕獲極性
設置具體爲那種捕獲事件

可以設置上升沿捕獲、下降沿捕獲、或者上升沿下降沿都捕獲

 

設置輸入捕獲映射關係
STM32爲了更好的優化使用,TIMx_CH1通道1捕捉到的信號可以傳輸到IC1,TIMx_CH1捕捉到的信號也可以連接到IC2,TIMx_CH2捕捉到的信號也可以連接到IC2,也可以連接到IC2

 
設置輸入捕獲分頻器
設置每N個事件觸發一次捕獲,可以設置爲1/2/4/8次檢測到電平變化才觸發捕獲

 

 

溢出時間計算:


t1時刻檢測到高電平,發生中斷,在中斷裏將計數值置0,開始記溢出次數N,

其中每計數0xFFFF次溢出一次,直到t2時刻跳變回低電平,

獲取最後一次溢出時到t2時刻的計數值TIM5CH1_CAPTURE_VAL

則  高電平時間 = 溢出次數*65535+TIM5CH1_CAPTURE_VAL     us ;根據定時器初始化時的頻率即可計算出溢出總次數所佔用的時間,即爲高電平時間。

如果計數器值爲 32 bit   那麼最大爲0xFFFFFFFF      

高電平時間:

           

 

輸入捕獲的工作框圖


 

工程創建
設置RCC

設置高速外部時鐘HSE 選擇外部時鐘源

2設置時鐘

我的是  外部晶振爲8MHz 

1選擇外部時鐘HSE 8MHz   
2PLL鎖相環倍頻72倍
3系統時鐘來源選擇爲PLL
4設置APB1分頻器爲 /2
5 這時候定時器的時鐘頻率爲72Mhz
32的時鐘樹框圖  如果不懂的話請看《【STM32】系統時鐘RCC詳解(超詳細,超全面)》

3定時器配置

這裏我們選擇TIM5的通道1

預分頻係數爲71   計數時鐘頻率就是 72MHz/(71+1) = 1MHz        此時1us計數一次
自動加載值設置爲32bit最大值  0xFFFFFFFF          
上升沿捕獲
不分頻
濾波值爲8
同時在NVIC一欄使能TIM5的中斷

對應引腳設置下拉電阻,保證沒有信號輸入的時候電平穩定

4項目文件設置

          

1 設置項目名稱
2 設置存儲路徑
3 選擇所用IDE
   

5創建工程文件

然後點擊GENERATE CODE  創建工程

配置下載工具
新建的工程所有配置都是默認的  我們需要自行選擇下載模式,勾選上下載後復位運行


例程實現:
定義變量:

/* USER CODE BEGIN 0 */
    uint32_t capture_Buf[3] = {0};   //存放計數值
    uint8_t capture_Cnt = 0;    //狀態標誌位
    uint32_t high_time;   //高電平時間
/* USER CODE END 0 */
在 while(1)中的用戶代碼區 3,寫入TIM2 CH1通道的輸入捕獲控制和數據處理

while (1)
{
    /* USER CODE END WHILE */
 
    /* USER CODE BEGIN 3 */
  switch (capture_Cnt){
    case 0:
        capture_Cnt++;
        __HAL_TIM_SET_CAPTUREPOLARITY(&htim5, TIM_CHANNEL_1, TIM_INPUTCHANNELPOLARITY_RISING);
        HAL_TIM_IC_Start_IT(&htim5, TIM_CHANNEL_1);    //啓動輸入捕獲       或者: __HAL_TIM_ENABLE(&htim5);
        break;
    case 3:
        high_time = capture_Buf[1]- capture_Buf[0];    //高電平時間
        HAL_UART_Transmit(&huart1, (uint8_t *)high_time, 1, 0xffff);   //發送高電平時間
                
                
        HAL_Delay(1000);   //延時1S
        capture_Cnt = 0;  //清空標誌位
        break;
                
    }
}
/* USER CODE END 3 */
在main函數下方添加中斷回調函數:

/* USER CODE BEGIN 4 */
void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim)
{
    
    if(TIM5 == htim->Instance)
    {
        switch(capture_Cnt){
            case 1:
                capture_Buf[0] = HAL_TIM_ReadCapturedValue(&htim5,TIM_CHANNEL_1);//獲取當前的捕獲值.
                __HAL_TIM_SET_CAPTUREPOLARITY(&htim5,TIM_CHANNEL_1,TIM_ICPOLARITY_FALLING);  //設置爲下降沿捕獲
                capture_Cnt++;
                break;
            case 2:
                capture_Buf[1] = HAL_TIM_ReadCapturedValue(&htim5,TIM_CHANNEL_1);//獲取當前的捕獲值.
                HAL_TIM_IC_Stop_IT(&htim5,TIM_CHANNEL_1); //停止捕獲   或者: __HAL_TIM_DISABLE(&htim5);
                capture_Cnt++;    
        }
    
    }
    
}
/* USER CODE END 4 */
具體流程:

1.設置TIM5 CH1爲輸入捕獲功能;  

2.設置上升沿捕獲; 

3.使能TIM2 CH1捕獲功能;  

4.捕獲到上升沿後,定時器當前計數值存入capture_buf[0],改爲捕獲下降沿;   

 5.捕獲到下降沿後,定時器當前計數值存入存入capture_buf[1],關閉TIM2 CH1捕獲功能;  capture_Cnt=3;

6.  高電平時間: capture_buf[1] - capture_buf[0]        發送到上位機  重新啓動輸入捕獲

 

 

__HAL_TIM_SET_COUNTER(&TIM5_Handler,0);   //設置計數寄存器的值變爲0

HAL_TIM_PWM_Start()              函數用於使能定時器某一通道的PWM輸出。

HAL_TIM_IC_Start_IT()                  函數用於使能定時器某一通道的輸入捕獲功能,並使能相應的中斷

HAL_TIM_IC_Stop_IT()                 函數和開啓功能相反,是關閉定時器某一通道的輸入捕獲功能和相應中斷

 

__HAL_TIM_SET_CAPTUREPOLARITY不是函數,而是底層操作的一個宏定義

在stm32f4xx_hal_tim.h文件中可以找到。其作用是修改定時器某一通道的輸入捕獲極性

其中有兩個函數,第一個爲清除清除原來的捕獲極性,第二個爲設置通道捕捉極性

等價於:

TIM_RESET_CAPTUREPOLARITY(&TIM5_Handler,TIM_CHANNEL_1);   //一定要先清除原來的捕獲極性!!
TIM_SET_CAPTUREPOLARITY(&TIM5_Handler,TIM_CHANNEL_1,TIM_ICPOLARITY_FALLING);//定時器5通道1設置爲下降沿捕獲(重設捕獲極性)
在修改定時器某一通道的輸入捕獲極性時,一定要先清除該通道之前捕獲極性

 

__HAL_TIM_GET_COMPARE也是一個宏定義。 
在stm32f4xx_hal_tim.h文件中可以找到。其作用是獲取定時器某一通道的捕獲/比較寄存器值

等價於 :  HAL_TIM_ReadCapturedValue(&htim5,TIM_CHANNEL_1);

  兩者都是直接讀取對應CCRx寄存器的值
 

發佈了17 篇原創文章 · 獲贊 16 · 訪問量 2461
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章