STM32F030 中斷太頻繁導致死機

最近在忙一個項目,使用了STM32F030的單片機,定時器用系統定時器,每10us中斷一次。在程序少的時候,沒有發現死機情況,但是隨着功能的豐富,經常出現死機問題,具體表現爲while(1)循環無法執行,但是中斷函數正常或者按鍵不起作用,程序直接跑分。這時我認爲是死機,即程序跑分,但是有時中斷正常,這就證明程序依然正常運行,可能是其它原因造成。

首先,我懷疑是I2C讀寫DSP出錯,於是屏蔽掉DSP初始化,剛開始正常,多開機幾次就又不正常了,所以排除寫DSP。

接着,我懷疑讀Flash出錯,也發現仿真時,有時讀Flash,就假死在那兒,於是就又把讀Flash屏蔽掉,發現程序又正常了許多,但是多開機幾次就又出現假死,所以又排除寫Flash。但是仿真時,卻說發現程序假死在一些初始化時的延時函數裏。於是我仔細檢查延時函數是否出錯,發現沒有錯誤,這就導致很奇怪了。

然後,我把優化等級調到-O3,發現出現了局部變量沒有初始化就被使用和數組越界的情況(程序是拷貝別人的,沒有仔細檢查),以爲這次可以解決了,在修改掉Bug後,程序假死改善了許多,但是很不幸,多級開關機後,發現程序又假死了,問題還不在這裏,不過順便解決了兩個Bug。

最後,在同事的幫助下,開始檢查系統定時器的中斷函數,發現中斷是每10us觸發一次,並且在10us的中斷函數裏有調用了好幾個函數,並且還有對IO口的操作,所以很有可能是由於中斷過於頻繁,系統被拖死了,導致不停的進入中斷(這次中斷還沒有執行完成,下一次中斷事件就產生了),導致while(1)循環根本沒有時間執行,就出現了之前的假死現象。於是,在把中斷時間改爲1ms後,並把函數的操作放在了50ms的中斷函數裏處理,假死問題得以解決。

總結:

1、單片機不能把中斷設置的太頻繁,否則可能會消耗掉過多的MCU資源,導致while(1)執行的很慢,系統運行出現問題。

      單片機會隨着溫度的升高,速度回稍微變慢,這也是爲什麼程序在中斷太頻繁時,有時運行正常,有時又不正常的原因。

      中斷函數裏最好不要放函數調用,比較耗費時間,如果確實要用,就快進快出,並且不能在低於1ms的中斷函數裏調用函數。

      中斷函數裏最好不要操作IO口,檢測IO口的狀態可以,但是最好不要寫IO口,否則可能會消耗掉過多的MCU資源,導致系統假死。

      局部變量一定要記得在定義時初始化,否則可能會出現不初始化就使用,導致系統異常;數組一定要仔細檢查是否可能會出現越界,如果越界了怎麼處理,要有保護措施。

2、從發現問題,到解決問題,用了將近兩天的時間,不能不說這是一種浪費。首先,在發現問題後,沒有先做深入的分析,而是不停的懷疑這裏有問題,而沒有用“證據”來證明其一定有問題,這不說一種好的解決問題的思路。其次,在沒有串口打印時,沒有第一時間把串口焊好,又是自己獨自摸索懷疑,增加了調試的難度。最後,對單片機的執行速度沒有大致的概念,以爲8M晶振倍頻到48M,單片機速度非常快了,但是沒有考慮到多週期指令和C代碼翻譯成彙編再翻譯成機器碼後,會增加20%~30%的代碼量,綜合考慮,跑一次while(1)循環大概需要幾毫秒的時間(中等規模代碼,且沒有任何延時)。
--------------------- 
作者:飛魚灣 
來源:CSDN 
原文:https://blog.csdn.net/kelvinflying/article/details/46674339 
版權聲明:本文爲博主原創文章,轉載請附上博文鏈接!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章