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