有人使用STM32G4系列的通用型TIMER基于捕獲功能對(duì)外來(lái)信號(hào)進(jìn)行周期及占空比的測(cè)量。他用TIM3產(chǎn)生頻率、占空比可調(diào)的PWM輸出做為被測(cè)信號(hào)。TIM4用來(lái)進(jìn)行頻率測(cè)量,工作在復(fù)位從模式,被測(cè)信號(hào)接到其通道2的輸入腳。然后經(jīng)內(nèi)部邊沿檢測(cè)和內(nèi)部濾波電路后,兵分兩路分別連接到IC1和IC2。顯然IC2使用直接輸入模式,IC1使用間接輸入模式,如下圖功能框圖示意。
但他發(fā)現(xiàn)被測(cè)信號(hào)頻率較高時(shí),誤差就明顯變大了。當(dāng)然,他也知道,任何測(cè)量肯定是有極限的。他現(xiàn)在就是想知道,能否基于現(xiàn)有方案將測(cè)量極限拉高點(diǎn)。比方說(shuō),他現(xiàn)在測(cè)量20KHz信號(hào)時(shí)就明顯誤差過(guò)大,導(dǎo)致測(cè)算結(jié)果難以采用。是否可以將可靠的測(cè)量結(jié)果提升到25KHz或更高呢。
我們不妨一起看看這個(gè)問(wèn)題。依然保持相同的測(cè)量方案,TIM4工作在復(fù)位從模式,TIM3輸出的被測(cè)信號(hào)連接到TIM4的CH2,然后兵分兩路連接都TIM4的IC1與IC2。
顯然,我們先要確定測(cè)量的計(jì)時(shí)起點(diǎn)??梢圆捎肐C2的上沿捕獲事件作為測(cè)量起點(diǎn),即進(jìn)入測(cè)試狀態(tài)。也可以基于上沿觸發(fā)信號(hào)產(chǎn)生定時(shí)器復(fù)位導(dǎo)致的更新事件加觸發(fā)事件作為測(cè)量起點(diǎn),我在下面就是使用后者來(lái)進(jìn)行測(cè)量并組織相應(yīng)代碼。
IC1的下降沿觸發(fā)捕獲,捕獲到的計(jì)數(shù)器值存放于變量Value_1stCap【結(jié)合上圖來(lái)看】。
IC2的上升沿作為TIM4的觸發(fā)復(fù)位信號(hào),且基于上升沿事件進(jìn)行捕獲, 捕獲值存于Value_2ndCap。
從發(fā)生復(fù)位事件到發(fā)生第2次捕獲期間,對(duì)TIM4的更新事件次數(shù)進(jìn)行統(tǒng)計(jì),總的更新事件次數(shù)計(jì)為Total_Num_OvEvent。
從發(fā)生復(fù)位事件到發(fā)生第1次捕獲期間,對(duì)TIM4的更新事件次數(shù)進(jìn)行統(tǒng)計(jì)后,計(jì)為Front_Num_OvEvent。
現(xiàn)在使用STM32CubeMx進(jìn)行配置。重點(diǎn)關(guān)注TIM4的配置。TIM4的時(shí)基和捕獲配置參數(shù)如下:
結(jié)合上面配置我們不難看出,TIM4的溢出周期為20ms,TI2FP2作為TIM4的復(fù)位觸發(fā)信號(hào),上沿觸發(fā),同時(shí)IC2針對(duì)輸入信號(hào)的上沿進(jìn)行捕獲。IC1針對(duì)輸入信號(hào)的下沿進(jìn)行捕獲。
至于TIM3的配置沒(méi)啥特別的,就是產(chǎn)生PWM輸出信號(hào),在代碼里將調(diào)整其PSC分頻系數(shù)和ARR參數(shù)以及CCR參數(shù),以改變其頻率和占空比。選擇其通道1做PWM輸出。下面測(cè)試中,TIM3輸出的PWM波形的占空比固定為40%。
另外,STM32G4的系統(tǒng)主頻配置為170MHz,使用HSE 時(shí)鐘源。開啟TIM4的中斷響應(yīng)使能。完成配置后創(chuàng)建工程。添加必要的用戶初始及啟動(dòng)代碼。
__IO uint32_t Vaule_2ndCap = 0u; __IO uint32_t Vaule_1stCap = 0u; __IO float Signal_Cycle= 0.0f; __IO float Signal_Duty = 0.0f; __IO float Signal_Freq = 0.0f; __IO uint32_t Total_Num_OvEvent=0u; __IO uint32_t Front_Num_OvEvent=0u; __IO uint32_t Num_OvEvent =0u ; __IO uint32_t Measure_State = 0u; __IO uint32_t Clk_Internal; __HAL_TIM_CLEAR_IT(&htim4, TIM_IT_UPDATE); __HAL_TIM_ENABLE_IT(&htim4, TIM_IT_UPDATE); HAL_TIM_IC_Start_IT(&htim4, TIM_CHANNEL_2); //enable IC1 interrupt of TIM4 HAL_TIM_IC_Start_IT(&htim4, TIM_CHANNEL_1); //enable IC2 interrupt of TIM4 __HAL_TIM_CLEAR_IT(&htim4, TIM_IT_UPDATE); __HAL_TIM_CLEAR_IT(&htim4, TIM_IT_TRIGGER);//enable Update interrupt of TIM4 Clk_Internal=HAL_RCC_GetHCLKFreq();//170MHzforG4Series Measure_State = 0x00; //initial state of Measuring Num_OvEvent = 0x00; //initial value of update count of TIM4 HAL_TIM_PWM_Start(&htim3, TIM_CHANNEL_1);
TIM4事件的所有中斷共用同一個(gè)中斷矢量入口。為了盡可能地測(cè)得較高的信號(hào)頻率,中斷處理代碼盡量要簡(jiǎn)潔些,避免過(guò)多、過(guò)深的函數(shù)調(diào)用。
有關(guān)TIM4的捕獲中斷及更新中斷的處理代碼如下,包括IC1、IC2的捕獲中斷處理和更新中斷處理代碼,以及相關(guān)計(jì)算處理代碼。
void HAL_TIM4_PWM_Measure_IRQ(TIM_HandleTypeDef *htim) { if(__HAL_TIM_GET_FLAG(htim, TIM_FLAG_UPDATE) != RESET) { __HAL_TIM_CLEAR_IT(htim, TIM_IT_UPDATE); if(__HAL_TIM_GET_FLAG(htim, TIM_FLAG_TRIGGER) != RESET) { __HAL_TIM_CLEAR_IT(htim, TIM_IT_TRIGGER); if (Measure_State == 0) { Num_OvEvent = 0; // prepare count overflow events Measure_State = 0x01; //start measurement } } else { if(Measure_State != 0) { Num_OvEvent++; } } } /* Capture compare 1 event */ if(__HAL_TIM_GET_FLAG(htim, TIM_FLAG_CC1) != RESET) { __HAL_TIM_CLEAR_IT(htim, TIM_IT_CC1); if (Measure_State == 0x01) { Front_Num_OvEvent = Num_OvEvent; Measure_State =0x02; } } /* Capture compare 2 event */ if(__HAL_TIM_GET_FLAG(htim, TIM_FLAG_CC2) != RESET) { __HAL_TIM_CLEAR_IT(htim, TIM_IT_CC2); if(Measure_State == 0x02) { Measure_State =0x03; Total_Num_OvEvent = Num_OvEvent; HAL_TIM4_IC_CaptureCallback(htim); //go to calculate pulse width and duty } } } void HAL_TIM4_IC_CaptureCallback(TIM_HandleTypeDef *htim) { /* Get the Input Capture value */ Vaule_1stCap = TIM4->CCR1;//HAL_TIM_ReadCapturedValue(htim, TIM_CHANNEL_1); Vaule_2ndCap = TIM4->CCR2;//HAL_TIM_ReadCapturedValue(htim, TIM_CHANNEL_2); Signal_Duty =(float)((Vaule_1stCap+(Front_Num_OvEvent*(TIM4_PERIOD+1)))*100u)/ (float)(Vaule_2ndCap+(Total_Num_OvEvent*(TIM4_PERIOD+1))); // Clk_Internal = HAL_RCC_GetHCLKFreq(); Signal_Freq =(float)(Clk_Internal/(TIM4_PSC+1))/(float)((Vaule_2ndCap+(Total_Num_OvEvent*(TIM4_PERIOD+1)))); Signal_Cycle = (float) (1.000f/Signal_Freq) ; Measure_State = 0x00; Num_OvEvent = 0x00; __HAL_TIM_CLEAR_IT(htim, TIM_IT_CC1); __HAL_TIM_CLEAR_IT(htim, TIM_IT_CC2); __HAL_TIM_CLEAR_IT(htim, TIM_IT_UPDATE); __HAL_TIM_CLEAR_IT(htim, TIM_IT_TRIGGER); }
現(xiàn)在基于上面的配置及用戶代碼進(jìn)行測(cè)量驗(yàn)證。我們發(fā)現(xiàn)當(dāng)TIM3輸出的待測(cè)信號(hào)頻率達(dá)到25KHz時(shí),測(cè)得的頻率及占空比就發(fā)生了明顯的偏差。見下圖標(biāo)注問(wèn)號(hào)的第4欄信息。
即當(dāng)被測(cè)頻率為25KHz,占空比為40%時(shí),測(cè)得結(jié)果是下面的樣子,明顯偏差過(guò)大。
如果說(shuō)被測(cè)信號(hào)頻率進(jìn)一步提升的話,誤差會(huì)變得更大。那么,這種情形是否有改善機(jī)會(huì)呢?即在當(dāng)前的測(cè)試方案下,可準(zhǔn)確測(cè)量的被測(cè)信號(hào)頻率是否可以提高。
目前的中斷處理代碼應(yīng)該說(shuō)比較精簡(jiǎn),沒(méi)有什么可以優(yōu)化的余地了。
聊到這里,有人可能發(fā)現(xiàn)了,我前面配置TIM4時(shí),它是用來(lái)完成測(cè)量任務(wù)的,它的分頻系數(shù)PSC為169。即TIM4的計(jì)數(shù)器計(jì)數(shù)時(shí)鐘為1MHz,其計(jì)數(shù)分辨率為1us。不難理解,這個(gè)PSC系數(shù)應(yīng)該會(huì)直接影響TIM4的計(jì)數(shù)精度,按理會(huì)影響到測(cè)量結(jié)果,尤其被測(cè)信號(hào)頻率較高時(shí)。
既然這樣,我們將TIM4的PSC系數(shù)改為0,并適當(dāng)調(diào)整其ARR值再來(lái)實(shí)施測(cè)量,看看結(jié)果會(huì)怎么樣。見下圖,TIM3輸出的信號(hào)頻率仍然是占空比為40% 、頻率為25KHz的PWM信號(hào)。測(cè)量結(jié)果顯著地明顯改善,應(yīng)該說(shuō)此時(shí)結(jié)果是可以接受的,畢竟浮點(diǎn)運(yùn)算也會(huì)帶來(lái)些偏差。
我們不妨在保持TIM3的PSC為0的條件下,將輸出頻率提升到50KHz、100KHz。繼續(xù)看看測(cè)量結(jié)果,見下圖:
從測(cè)試結(jié)果來(lái)看,當(dāng)被測(cè)信號(hào)頻率提升到50KHz,測(cè)量結(jié)果仍然很好,完全可以采用。即使當(dāng)被測(cè)信號(hào)頻率提升到100KHz時(shí),測(cè)量結(jié)果雖發(fā)生了一些偏差,但此時(shí)的偏差相比PSC=169、被測(cè)信號(hào)為25KHz時(shí)的測(cè)試結(jié)果還要好得多。我把二者單列出來(lái)一起比較,見下圖:
經(jīng)過(guò)上面的討論和驗(yàn)證,我們知道,在使用TIMER做信號(hào)的頻率及占空比的測(cè)量時(shí),當(dāng)確定好測(cè)試方案后,為了盡可能地提升可以準(zhǔn)確測(cè)試信號(hào)的頻率,一方面代碼要盡可能精簡(jiǎn)、優(yōu)化,另一方面,因測(cè)試TIMER的分頻系數(shù)會(huì)影響測(cè)試結(jié)果的精度及準(zhǔn)確性,此時(shí)測(cè)試TIMER的分頻系數(shù)要盡可能設(shè)置小、或不做分頻,這點(diǎn)結(jié)合具體應(yīng)用場(chǎng)景來(lái)定。
關(guān)于上面的的話題,其實(shí)還可以有很多繼續(xù)延伸的空間,因時(shí)間和篇幅問(wèn)題,就先聊到這里。有興趣的話,可以基于上面配置和分享的參考源碼做些快速測(cè)試驗(yàn)證,也歡迎進(jìn)一步地討論交流。
審核編輯:湯梓紅
-
mcu
+關(guān)注
關(guān)注
146文章
17917瀏覽量
362721 -
占空比
+關(guān)注
關(guān)注
0文章
112瀏覽量
29517 -
定時(shí)器
+關(guān)注
關(guān)注
23文章
3297瀏覽量
117599 -
Timer
+關(guān)注
關(guān)注
1文章
64瀏覽量
13161
原文標(biāo)題:利用TIMER測(cè)量信號(hào)周期及占空比的精度話題
文章出處:【微信號(hào):stmcu832,微信公眾號(hào):茶話MCU】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。
發(fā)布評(píng)論請(qǐng)先 登錄
多周期測(cè)量頻率的方法及應(yīng)用

怎么設(shè)置TIMER周期
如何利用LabVIEW測(cè)量一個(gè)心電信號(hào)的周期?
求有償求購(gòu)周期方波信號(hào)頻率周期測(cè)量設(shè)計(jì)
測(cè)量方波周期以及占空比的方法是什么
如何測(cè)量PWM信號(hào)的占空比和周期?
如何采用MSP430單片機(jī)實(shí)現(xiàn)PWM信號(hào)
測(cè)量方波周期以及占空比的兩種方法介紹

怎樣利用示波器測(cè)量信號(hào)的周期

評(píng)論