久久ER99热精品一区二区-久久精品99国产精品日本-久久精品免费一区二区三区-久久综合九色综合欧美狠狠

新聞中心

EEPW首頁 > 嵌入式系統 > 設計應用 > TQ2440之定時器中斷0——volatile關鍵字的重要作用

TQ2440之定時器中斷0——volatile關鍵字的重要作用

作者: 時間:2016-11-19 來源:網絡 收藏
近日,在學習《ARM處理器裸機開發實戰——機制而非策略》一書,在TQ2440開發板上,按照書中實例以及光盤配套程序源代碼進行Timer0中斷試驗,編譯成功后燒寫到開發板上,沒有任何反應,反復檢查代碼,一直沒有找出哪里有問題,就是到開發板上沒有預期效果。(讓人糾結的很)

最終參考了TQ2440之定時器中斷0的程序代碼,編譯成功后,燒寫到板子上,驚喜出現了。絕對是久旱逢甘霖的感覺,在這里對TQ2440之定時器中斷0的原創作者表示感謝。

本文引用地址:http://cqxgywz.com/article/201611/318239.htm

后來,經過代碼對比,發現兩個可疑的地方:

(1)之前的Timer0的初始化中沒有rTCMPB0 = 0;這條語句。


而后來參考TQ2440之定時器中斷0中的代碼是有這條語句的。


后來經過驗證,這里無關緊要。

(2)之前對于Led1燈亮滅控制語句是放在Main函數中的:


而后來參考的TQ2440之定時器中斷0中是將這段代碼放在了中斷服務函數當中:


不過,按道理來講,這個地方不加修改應該是可以的。

暫且先總結這樣一條經驗吧:如果一些控制語句(比如控制Led燈亮、滅)是要通過中斷來驅動執行,那么最好將這些控制語句放在中斷服務程序(也叫中斷處理程序)中。如果只是在中斷服務程序中控制一個全局變量(比如flag),而在Main函數中根據flag來驅動控制語句的執行,可能得不到預期效果。

為什么代碼邏輯合情合理卻得不到預期效果呢?其根源在于,在定義flag時沒有加volatile關鍵字

volatile關鍵字的作用:當一個變量用volatile關鍵字修飾,表示該變量可能被硬件更改,因此每次讀取這個變量值的時候都要重新從內存中讀取這個變量,而不是使用保存在寄存器里的備份。

這里有一篇文章:http://www.cnblogs.com/yc_sunniwell/archive/2010/06/24/1764231.html徹徹底底的解釋了volatile。也正是對于我在Timer0中斷實例中遇到的問題的詳細解答。其中關鍵點如下:

volatile提醒編譯器它后面所定義的變量隨時都有可能改變,因此編譯后的程序每次需要存儲或讀取這個變量的時候,都會直接從變量地址中讀取數據。如果沒有volatile關鍵字,則編譯器可能優化讀取和存儲,可能暫時使用寄存器中的值,如果這個變量由別的程序更新了的話,將出現不一致的現象。



評論


技術專區

關閉