1. 程式人生 > >關於STM32定時器使用的一個註意事項(以此為前車之鑒,重要!)

關於STM32定時器使用的一個註意事項(以此為前車之鑒,重要!)

https disable 執行 pen 調試 處理 輸出 tail 鏈接

轉自:https://blog.csdn.net/ludaoyi88/article/details/51934122

我們平時使用定時器的時候多數都是處於開啟狀態,平時的定時中斷書寫格式一般是:

void TIM3_IRQHandler(void)
{
if(TIM_GetITStatus(TIM3, TIM_IT_Update) == SET)
{

TIM_ClearITPendingBit(TIM3, TIM_IT_Update);
//要處理的事件內容。。。。

}

}


但是,項目的實驗過程中,我使用的定時器處理事件稍微有點特殊,即,定時器不是一直處於開啟狀態, 而且關閉時候也是在中斷裏關閉。大概形式這樣:

void TIM3_IRQHandler(void)
{
if(TIM_GetITStatus(TIM3, TIM_IT_Update) == SET)
{

TIM_ClearITPendingBit(TIM3, TIM_IT_Update);
//要處理的事件內容。。。。

TIM_Cmd(TIM3, DISABLE); //失能(函數外使能)

}

}

看似沒錯,而且也看似正常。但是,處理的事件內容出現了很多未知錯誤(由於我的這個處理事件有很強的時序性,開始和結束都比較嚴格),無法正常執行。通過後來的調試中發現(把處理時間改為點燈或者打印輸出方式),發現是:TIM_Cmd(TIM3, DISABLE); 擾亂了時序關系。當失能後,其實中斷並沒有真正失能,還會再進入一次中斷,因此事件又被執行了一次,對於時序比較嚴格的事件,就產生了問題!

找到了原因,因此,我猜測雖然定時器失能並且關閉了定時器,但是可能中斷標誌位並沒真正清除,雖然中斷開始已經清除過一次,但估計因為失能使得標誌位又被置位了,因此,我在失能前面加了句清除中斷更新標誌位,如下:


void TIM3_IRQHandler(void)
{
if(TIM_GetITStatus(TIM3, TIM_IT_Update) == SET)
{

TIM_ClearITPendingBit(TIM3, TIM_IT_Update);
//要處理的事件內容。。。。

TIM_ClearITPendingBit(TIM3, TIM_IT_Update);//再清除標誌位

TIM_Cmd(TIM3, DISABLE); //失能(函數外使能)

}

}


果然,程序可以正常的時序運行。

比較納悶關定時器前又得清下標誌位,因此引起了另一個好奇心,是不是在其他地方關閉定時器(如主函數),也得這樣做才可以。所以對這個好奇心進行了下測試。發現:如果把關閉定時器放到了主函數後,不用再清中斷標誌位。能正常把定時器關閉,並不會進入中斷。

通過這次的問題,浪費了很多時間解決,不過也吸取到了點經驗,但對於內在真正原因:在中斷裏失能和中斷外失能效果為什麽不一樣,暫時還沒搞清楚。。。但這個可以作為以後的前車之鑒,以及大家的前車之鑒,少走彎路。
---------------------
作者:ludaoyi123
來源:CSDN
原文:https://blog.csdn.net/ludaoyi88/article/details/51934122
版權聲明:本文為博主原創文章,轉載請附上博文鏈接!

關於STM32定時器使用的一個註意事項(以此為前車之鑒,重要!)