定時器輸入捕獲功能
1 輸入捕獲功能概述
1.1 輸入捕獲功能的用途和工作原理
- 用途:用于測量信號的參數,比如周期和頻率。
- 工作原理:在輸入捕獲模式下,當捕獲單元捕捉到外部信號的有效邊沿(上升沿/下降 沿/雙邊沿)時,將計數器的當前值鎖存到捕獲/比較寄存器TIMx_CCR, 供用戶讀取。
1.2 捕獲通道的內部結構
1.3 捕獲過程示意圖
將兩次捕獲值相減,再乘以計數時間可計算出信號周期
1.4 信號參數計算公式
信號參數計算公式
周期
頻率
當待測信號不大于定時器的一個完整計數周期(從0到ARR)時。假設兩次連續的捕獲值分別為CCRx_1 和 CCRx_2,則捕獲差值可以按照如下方法計算:
- 如果 CCRx_1 < CCRx_2:捕獲差值 = CCRx_2 - CCRx_1
- 如果 CCRx_1 > CCRx_2:捕獲差值 = (ARR + 1 - CCRx_1) + CCRx_2
注意:如果待測信號大于定時器的一個完整計數周期,則需要結合定時器的更新中斷次數來計算捕獲差值。
1.5 輸入捕獲功能的數據類型和接口函數
成員變量ICPolarity的取值范圍
宏常量定義 | 含義 |
---|---|
TIM_ICPOLARITY_RISING | 上升沿捕獲 |
TIM_ICPOLARITY_FALLING | 下降沿捕獲 |
TIM_ICPOLARITY_BOTHEDGE | 雙邊沿捕獲 |
成員變量ICSelection的取值范圍
宏常量定義 | 含義 |
---|---|
TIM_ICSELECTION_DIRECTTI | 直接輸入模式:捕獲通道CH1和CH2分別與IC1和IC2連接.捕獲通道CH3和CH4分別與IC3和IC4連接. |
TIM_ICSELECTION_DIRECTT2 | 間接輸入模式:捕獲通道CH1和CH2分別與IC2和IC1連接.捕獲通道CH3和CH4分別與IC4和IC3連接. |
TIM_ICSELECTION_TRC | 選擇從模式管理器的觸發信號TRC 作獲信號. |
成員變量ICPrescaler的取值范圍
宏常量定義 | 含義 |
---|---|
TIM_ICPSC_DIV1 | 檢測到輸入信號的每1個有效邊沿觸發1次捕獲 |
TIM_ICPSC_DIV2 | 檢測到輸入信號的每2個有效邊沿觸發1次捕獲 |
TIM_ICPSC_DIV3 | 檢測到輸入信號的每4個有效邊沿觸發1次捕獲 |
TIM_ICPSC_DIV4 | 檢測到輸入信號的每8個有效邊沿觸發1次捕獲 |
輸入捕獲啟動函數:
HAL_TIM_IC_Start_IT
函數原型 uint32_t HAL_TIM_IC_Start_IT(TIM_HandleTypeDef *htim, uint32_t Channel)
功能描述 用于在中斷方式下啟動定時器的輸入捕獲功能 入口參數 htim:定時器句柄的地址Channel:定時器通道號,取值范圍是TIM_CHANNEL_1~TIM_CHANNEL_4 返回值 HAL狀態值 注意事項 1. 該函數在定時器初始化完成之后調用2. 函數需要由用戶調用,用于使能定時器的捕獲中斷,并啟動定時器運行 輸入捕獲停止函數:
HAL_TIM_IC_Stop_IT
函數原型 HAL_StatusTypeDef HAL_TIM_IC_Stop_IT(TIM_HandleTypeDef *htim, uint32_t Channel)
功能描述 用于停止在中斷方式下定時器的輸入捕獲功能 入口參數 htim:定時器句柄的地址Channel:定時器通道號,取值范圍是TIM_CHANNEL_1~TIM_CHANNEL_4 返回值 HAL狀態值 注意事項 1. 該函數需要由用戶調用,用于禁止捕獲中斷,關閉輸入捕獲通道,停止 定時器運行 輸入捕獲中斷回調函數:
HAL_TIM_IC_CaptureCallback
函數原型 void HAL_TIM_IC_CaptureCallback (TIM_HandleTypeDef *htim)
功能描述 用于處理所有定時器的輸入捕獲中斷,用戶在該函數內編寫實際的任務處理程序 入口參數 htim:定時器句柄的地址 返回值 無 注意事項 1. 該函數由定時器中斷通用處理函數HAL_TIM_IRQHandler調用,完成所 有定時器輸入捕獲中斷的任務處理2. 函數內部需要根據定時器句柄的實例來判斷是哪一個定時器的哪一個通道 產生的本次輸入捕獲中斷3. 函數由用戶根據具體的處理任務編寫 捕獲值讀取函數:
HAL_TIM_ReadCapturedValue
函數原型 uint32_t HAL_TIM_ReadCapturedValue(TIM_HandleTypeDef *htim, uint32_t Channel)
功能描述 用于處理所有定時器的輸入捕獲中斷,用戶在該函數內編寫實際的任務處理程序 入口參數 htim:定時器句柄的地址Channel:定時器通道號,取值范圍是TIM_CHANNEL_1~TIM_CHANNEL_4 返回值 捕獲值 注意事項 1. 函數需要由用戶調用,用于讀取發生捕獲時的捕獲值 捕獲邊沿設置函數:
__HAL_TIM_SET_CAPTUREPOLARITY
函數原型 __HAL_TIM_SET_CAPTUREPOLARITY(__HANDLE__, __CHANNEL__, __POLARITY__
功能描述 用于設置輸入信號的捕獲邊沿 入口參數 HANDLE :定時器句柄的地址__Channel__:定時器通道號, 取值范圍是TIM_CHANNEL_1~TIM_CHANNEL_4__POLARITY__ :捕獲邊沿, 取值范圍是TIM_INPUTCHANNELPOLARITY_RISING/FALLING/BOTHEDGE 返回值 無 注意事項 1. 該函數是宏函數,進行宏替換,不發生函數調用2. 函數需要由用戶調用,用于設置輸入信號的有效捕獲邊沿
2 任務實踐
利用定時器2的通道1(對應引腳PA0)來測量一個外部脈沖信號的周期和頻率,外部脈沖信號利用引腳PA6輸入。
- 配置定時器2時鐘源為內部時鐘源(8MHz),通道一為輸入捕獲方式。
配置時基單元- 預分頻系數PSC為0,即計數時鐘CK_CNT為8MHz,便于擴大測量頻率的范圍。
- 設置自動重載值ARR為最長的計數周期,便于擴大測量頻率的脈寬。
配置輸入捕獲通道采用默認參數
- 捕獲有效邊沿為上升沿
- 捕獲通道為直接輸入方式
- 捕獲信號不分頻
- 捕獲信號不進行濾波
使能定時器2的全局中斷,中斷優先級使用默認值
- 配置定時器3時鐘源為內部時鐘源(8MHz),通道一為PWM輸出模式。
設置預分頻系數PSC為399,自動重載值 ARR為199,表示PWM信號的周期為10ms。
設置捕獲/比較值CRR為100, 表示PWM信號的占空比為50% - 打開串口USART1,并在工程中添加頭文件和prinrf函數重定義,Keil中勾選USE MicroLIB。
在CubeMX中配置串口,在Keil中使用“Use MicroLIB”并在代碼中重定向printf函數的方法在STM32基礎:定時器的定時計數功能中有詳細講解。 - 編寫程序
/* USER CODE BEGIN PV */ uint32_t Diff = 0; // 存放捕獲差值 uint32_t Period = 0; // 存放計算所得周期 uint8_t MeasureFlag = 0; // 測量完成標志: 0表示未完成, 1表示完成 uint8_t CapIndex = 0; // 捕獲指示: 0表示沒有開始捕獲, 1表示完成一次捕獲 uint32_t CapVal1 = 0; // 存放第一次捕獲值 uint32_t CapVal2 = 0; // 存放第二次捕獲值 /* USER CODE END PV */ /* USER CODE BEGIN 2 */ printf("Timer Capture Function Test: n"); HAL_TIM_IC_Start_IT(&htim2, TIM_CHANNEL_1); HAL_TIM_PWM_Start(&htim3, TIM_CHANNEL_1); /* USER CODE END 2 */ /* USER CODE BEGIN 3 */ if(MeasureFlag == 1) { if(CapVal2 >= CapVal1) { Diff = CapVal2 - CapVal1; } else { Diff = ((65535 + 1 - CapVal1) + CapVal2) ; } } Period = Diff/20000; printf ("Period is: %.4fmsrn", Diff/20000.0); printf ("Frequency is: %dHzrn", 8000000/Period); printf ("/*****************************/rn"); MeasureFlag = 0; HAL_Delay(1000); HAL_TIM_IC_Start_IT(&htim2, TIM_CHANNEL_1); } /* USER CODE END 3 */ /* USER CODE BEGIN 4 */ int fputc (int ch, FILE *f) { HAL_UART_Transmit(&huart1, (uint8_t *)&ch, 1, HAL_MAX_DELAY); return ch; } int fgetc(FILE *f) { uint8_t ch = 0; HAL_UART_Receive(&huart1, (uint8_t *)&ch, 1, HAL_MAX_DELAY); return ch; } void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim) { if (htim- >Instance == TIM2) { if (htim- >Channel == HAL_TIM_ACTIVE_CHANNEL_1) { if (CapIndex == 0) { CapVal1 = HAL_TIM_ReadCapturedValue(htim, TIM_CHANNEL_1); CapIndex = 1; } if (CapIndex == 1) { CapVal2 = HAL_TIM_ReadCapturedValue(htim, TIM_CHANNEL_1); CapIndex = 0; MeasureFlag = 1; } else { Error_Handler(); } } } } /* USER CODE END 4 */
-
寄存器
+關注
關注
31文章
5343瀏覽量
120368 -
STM32
+關注
關注
2270文章
10900瀏覽量
356012 -
計數器
+關注
關注
32文章
2256瀏覽量
94570 -
定時器
+關注
關注
23文章
3248瀏覽量
114803
發布評論請先 登錄
相關推薦
評論