關(guān)于STM32定時器使用的一個注意事項(xiàng)
我們平時使用定時器的時候多數(shù)都是處于開啟狀態(tài),平時的定時中斷書寫格式一般是:
void TIM3_IRQHandler(void)
{
if(TIM_GetITStatus(TIM3, TIM_IT_Update) == SET)
{
TIM_ClearITPendingBit(TIM3, TIM_IT_Update);
//要處理的事件內(nèi)容。。。。
}
}
但是,項(xiàng)目的實(shí)驗(yàn)過程中,我使用的定時器處理事件稍微有點(diǎn)特殊,即,定時器不是一直處于開啟狀態(tài), 而且關(guān)閉時候也是在中斷里關(guān)閉。大概形式這樣:
void TIM3_IRQHandler(void)
{
if(TIM_GetITStatus(TIM3, TIM_IT_Update) == SET)
{
TIM_ClearITPendingBit(TIM3, TIM_IT_Update);
//要處理的事件內(nèi)容。。。。
TIM_Cmd(TIM3, DISABLE); //失能(函數(shù)外使能)
}
}
看似沒錯,而且也看似正常。但是,處理的事件內(nèi)容出現(xiàn)了很多未知錯誤(由于我的這個處理事件有很強(qiáng)的時序性,開始和結(jié)束都比較嚴(yán)格),無法正常執(zhí)行。通過后來的調(diào)試中發(fā)現(xiàn)(把處理時間改為點(diǎn)燈或者打印輸出方式),發(fā)現(xiàn)是:TIM_Cmd(TIM3, DISABLE); 擾亂了時序關(guān)系。當(dāng)失能后,其實(shí)中斷并沒有真正失能,還會再進(jìn)入一次中斷,因此事件又被執(zhí)行了一次,對于時序比較嚴(yán)格的事件,就產(chǎn)生了問題!
找到了原因,因此,我猜測雖然定時器失能并且關(guān)閉了定時器,但是可能中斷標(biāo)志位并沒真正清除,雖然中斷開始已經(jīng)清除過一次,但估計(jì)因?yàn)槭苁沟脴?biāo)志位又被置位了,因此,我在失能前面加了句清除中斷更新標(biāo)志位,如下:
void TIM3_IRQHandler(void)
{
if(TIM_GetITStatus(TIM3, TIM_IT_Update) == SET)
{
TIM_ClearITPendingBit(TIM3, TIM_IT_Update);
//要處理的事件內(nèi)容。。。。
TIM_ClearITPendingBit(TIM3, TIM_IT_Update);//再清除標(biāo)志位
TIM_Cmd(TIM3, DISABLE); //失能(函數(shù)外使能)
}
}
果然,程序可以正常的時序運(yùn)行。
比較納悶關(guān)定時器前又得清下標(biāo)志位,因此引起了另一個好奇心,是不是在其他地方關(guān)閉定時器(如主函數(shù)),也得這樣做才可以。所以對這個好奇心進(jìn)行了下測試。發(fā)現(xiàn):如果把關(guān)閉定時器放到了主函數(shù)后,不用再清中斷標(biāo)志位。能正常把定時器關(guān)閉,并不會進(jìn)入中斷。
通過這次的問題,浪費(fèi)了很多時間解決,不過也吸取到了點(diǎn)經(jīng)驗(yàn),但對于內(nèi)在真正原因:在中斷里失能和中斷外失能效果為什么不一樣,暫時還沒搞清楚。。。但這個可以作為以后的前車之鑒,以及大家的前車之鑒,少走彎路。





