一、引言
AS32系列MCU芯片集成4個高級定時器,每個定時器包含一個32位自動重載計數(shù)器,該計數(shù)器由可編程預分頻器驅(qū)動,支持遞增、遞減、中心計數(shù)、編碼器模式等計數(shù)方式。
高級定時器具有6個獨立通道,可實現(xiàn)測量輸入信號的脈沖寬度、可編程PWM輸出、帶死區(qū)插入的互補PWM等功能。
二、PWM簡介
PWM,全稱脈沖寬度調(diào)制。它是一種用數(shù)字信號來模擬模擬電壓的技術(shù)。簡單來說,就是快速地在“開”(高電平)和“關(guān)”(低電平)之間切換,通過改變一個周期內(nèi)“開”的時間比例,來控制平均電壓。
2.1****輸出比較模式
定時器被配置為PWM模式時,會用到比較寄存器。
周期: 由自動重載寄存器決定。計數(shù)器從0計數(shù)到這個值,然后歸零,這個過程就是一個PWM周期。
占空比: 由比較寄存器決定。它設(shè)定了電平翻轉(zhuǎn)的閾值。
工作流程:
1.計數(shù)器從0開始向上計數(shù)。
2.當計數(shù)器的值 小于 比較寄存器的值時,輸出高電平(例如)。
3.當計數(shù)器的值 達到或超過 比較寄存器的值時,輸出翻轉(zhuǎn)為低電平。
4.計數(shù)器到達自動重載值后歸零,輸出重新變?yōu)楦唠娖?,開始下一個周期。
通過修改比較寄存器的值,就改變了高電平在一個周期內(nèi)持續(xù)的時間,從而改變了 占空比 。
輸出比較可用于:
控制LED亮度: 占空比越大,LED越亮。
驅(qū)動舵機: 舵機的角度由PWM脈沖的寬度精確控制。
控制電機速度: 通過改變平均電壓來調(diào)節(jié)直流電機轉(zhuǎn)速。
音頻輸出: 通過極高頻率的PWM,經(jīng)過濾波后可以生成簡單的音頻信號。
2.2****輸入捕獲
輸入捕獲功能就像一個“高速抓拍機”。當外部引腳上發(fā)生一個特定事件(如上升沿)時,它立刻“抓拍”下當前計數(shù)器的值,并保存起來。通過分析兩次“抓拍”的值,我們就能計算出這個事件的時間參
定時器配置為輸入捕獲模式時,會用到 捕獲寄存器 。
工作流程:
1.定時器的計數(shù)器一直在自由運行。
2.當輸入引腳上出現(xiàn)第一個上升沿時,硬件會立即將計數(shù)器當前的值復制到捕獲寄存器中,并產(chǎn)生一個中斷。
3.在中斷服務(wù)程序里,程序讀取這個捕獲值(記為t1),并同時將捕獲邊沿設(shè)置為 下降沿 。
4.當引腳出現(xiàn)下降沿時,硬件再次將計數(shù)器的當前值捕獲(記為t2)。
5.程序計算 t2 - t1,這個差值就是高電平期間計數(shù)器計數(shù)的次數(shù),再乘以計數(shù)周期,就得到了高電平脈沖的精確寬度。
6.同理,可以再捕獲下一個上升沿,計算出整個信號的周期。
輸入捕獲可用于:
測量脈沖寬度和頻率: 例如解碼紅外遙控信號(NEC協(xié)議)、測量超聲波測距模塊返回的脈沖寬度。
解碼編碼器信號: 讀取旋轉(zhuǎn)編碼器的位置和速度。
測量數(shù)字信號的占空比。
三、軟件設(shè)計
本文同時啟用定時器HTIM1與HTIM5的通道1與通道2。其中,兩個定時器的通道1均配置為PWM輸出模式,以生成PWM信號;相應(yīng)的通道2則工作在輸入捕獲模式,并采用中斷驅(qū)動方式,以精確測量PWM信號的頻率與占空比。最終,測量數(shù)據(jù)將通過串口打印輸出。引腳連線如下:PD4->PH9, PC9->PD5

3.1軟件分析
HTIM1初始化函數(shù): void User_TIM1_Config(uint32_t arr, uint32_t psc, uint32_t rcr);
硬件使能與準備
- GPIOD_CLK_ENABLE(); // 使能GPIOD時鐘
- HTIM1_CLK_ENABLE(); // 使能HTIM1時鐘
定時器時基配置
- TIM_TimeBaseInitStructure.TIM_CounterMode = TIM_CounterMode_Up; // 向上計數(shù)
- TIM_TimeBaseInitStructure.TIM_Period = arr; // 設(shè)定周期
- TIM_TimeBaseInitStructure.TIM_Prescaler = psc; // 設(shè)定預分頻
- TIM_TimeBaseInitStructure.TIM_RepetitionCounter = rcr; // 重復計數(shù)
輸入捕獲配置(通道2)
- TIM_IC_InitStructure.TIM_Channel = TIM_Channel_2; // 使用通道2
- TIM_IC_InitStructure.TIM_ICPolarity = TIM_ICPolarity_Rising; // 上升沿捕獲
- TIM_IC_InitStructure.TIM_ICSelection = TIM_ICSelection_DirectTI; // 直接輸入
- TIM_IC_InitStructure.TIM_ICFilter = 0x0; // 無濾波器
- TIM_IC_InitStructure.TIM_ICPrescaler = 0x0; // 每個事件都捕獲
中斷與PWM輸出配置
中斷使能:
- TIM_IT_Update://定時器溢出更新中斷
- TIM_IT_CC2://通道2捕獲/比較中斷
PWM****輸出配置(通道1):
- TIM_OC_InitStructure.TIM_OCMode = TIM_OCMode_PWM1; // PWM模式1
- TIM_OC_InitStructure.TIM_Pulse = arr/2; // 初始占空比50%
- TIM_OC_InitStructure.TIM_OCPolarity = TIM_OCPolarity_High; // 高電平有效
注:HTIM5配置除GPIO引腳外其余配置通HTIM1,此外HTIM5和HTIM1掛在不同總線下,讀者使用時需自行計算外設(shè)時鐘
在輸入捕獲模式下,當相應(yīng)的 ICx 信號檢測到跳變沿后,將使用捕獲/比較寄存器(TIMx_CCRx)來鎖存計數(shù)器的值。簡單的說就是通過檢測 TIMx_CHx 上的邊沿信號,在邊沿信號發(fā)生跳變(比如上升沿/下降沿)的時候,將當前定時器的值(TIMx_CNT)存放到對應(yīng)的通道的捕獲/比較寄存(TIMx_CCRx)里面,完成一次捕獲。

從上圖可以看出,t1-t2 時間就是需要測量的高電平時間,假如定時器工作在向上計數(shù)模式,測量方法是:首先設(shè)置定時器通道 x 為上升沿捕獲,這樣在 t1 時刻,就會捕獲到當前的 CNT 值,然后立即清零 CNT,并設(shè)置通道 x 為下降沿捕獲,這樣到 t2 時刻,又會發(fā)生捕獲事件,得到此時的 CNT 值,記為 CCRx2。根據(jù)定時器的計數(shù)頻率,就可以算出 t1-t2 的時間,從而得到高電平脈寬。在 t1-t2 時間內(nèi)可能會出現(xiàn) N 次定時器溢出,因此還需要對定時器溢出進行處理,防止因高電平時間過長發(fā)生溢出導致測量數(shù)據(jù)不準。CNT計數(shù)的次數(shù)等于:N*ARR+CCRx2,有了這個計數(shù)次數(shù),再乘以 CNT 的計數(shù)周期,即可得到 t2-t1 的時間長度,即高電平持續(xù)時間。部分邏輯在中斷函數(shù)中實現(xiàn):
- void TIM1_IRQ_Handler()
- {
- static uint32_t TIM1_counter=0;
- /* Get the value of TIM_CNT*/
- if (TIM1_GetComplete==0)
- {
- if (TIM_GetITStatus(TIM1, TIM_IT_Update)!= RESET)
- {
- TIM1_Update_counter++;
- TIM_ClearITPendingBit(TIM1, TIM_IT_Update);
- }
- if (TIM_GetITStatus(TIM1, TIM_IT_CC2)!= RESET)
- {
- TIM1_counter++;
- if (TIM1_counter==1)
- {
- TIM1_Update_counter=0;
- TIM1_Value1=TIM_GetCounter(TIM1);
- }
- if (TIM1_counter==2)
- {
- TIM1_Value2=TIM_GetCounter(TIM1);
- TIM1_counter=0;
- TIM1_GetComplete=1;
- }
- TIM_ClearITPendingBit(TIM1, TIM_IT_CC2);
- }
- }
- else
- {
- TIM_ClearITPendingBit(TIM1, TIM_IT_Update | TIM_IT_CC2);
- }
- }
計算并輸出PWM信號周期和頻率的函數(shù)
- /* Calculate the input frequency and period */
- TIM1_Input_Poriod=(10000*TIM1_Update_counter-TIM1_Value1+TIM1_Value2);
- TIM1_Input_Poriod = TIM1_Input_Poriod/20;
- Printf("TIM1 Input_Poriod: %d usrn", (uint32_t)TIM1_Input_Poriod);
- Printf("TIM1 Frequence: %d hzrn", (uint32_t)(1000000/TIM1_Input_Poriod));
- TIM1_Update_counter=0;
- TIM1_GetComplete=0;
- ClearCache();
其中第三行的20 為 HTIM1的時鐘頻率為20M。
四、開發(fā)板驗證:

審核編輯 黃宇
-
mcu
+關(guān)注
關(guān)注
147文章
18934瀏覽量
398539 -
MCU芯片
+關(guān)注
關(guān)注
3文章
260瀏覽量
12904
發(fā)布評論請先 登錄
智能顯示MCU D12x系列芯片在家電HMI上的應(yīng)用
LAT1202+TIM DMA burst 輸出變頻 PWM 波形應(yīng)用筆記
AS32系列MCU芯片中CRC計算模塊的應(yīng)用介紹
FreeRTOS 在 AS32系列RISC-V 架構(gòu)MCU電機驅(qū)動中的應(yīng)用實踐與優(yōu)化
32位MCU芯片國產(chǎn)品牌(32系列單片機常用型號有哪些)
基于 AS32X601 微控制器的定時器模塊(TIM)技術(shù)研究與應(yīng)用實踐
抗輻照MCU芯片:衛(wèi)星互聯(lián)網(wǎng)光模塊選型的關(guān)鍵考量
AS32系列MCU芯片I2C模塊性能解析與調(diào)試
第二十二章 TIM——高級定時器
第二十一章 TIM——通用定時器
靈動微電子MM32MCU的主流型芯片選型
AS32系列MCU芯片TIM模塊的捕獲和比較
評論