新聞中心

EEPW首頁(yè) > 嵌入式系統(tǒng) > 設(shè)計(jì)應(yīng)用 > TQ2440之定時(shí)器中斷0——volatile關(guān)鍵字的重要作用

TQ2440之定時(shí)器中斷0——volatile關(guān)鍵字的重要作用

作者: 時(shí)間:2016-11-19 來(lái)源:網(wǎng)絡(luò) 收藏
近日,在學(xué)習(xí)《ARM處理器裸機(jī)開(kāi)發(fā)實(shí)戰(zhàn)——機(jī)制而非策略》一書(shū),在TQ2440開(kāi)發(fā)板上,按照書(shū)中實(shí)例以及光盤配套程序源代碼進(jìn)行Timer0中斷試驗(yàn),編譯成功后燒寫到開(kāi)發(fā)板上,沒(méi)有任何反應(yīng),反復(fù)檢查代碼,一直沒(méi)有找出哪里有問(wèn)題,就是到開(kāi)發(fā)板上沒(méi)有預(yù)期效果。(讓人糾結(jié)的很)

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

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

后來(lái),經(jīng)過(guò)代碼對(duì)比,發(fā)現(xiàn)兩個(gè)可疑的地方:

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


而后來(lái)參考TQ2440之定時(shí)器中斷0中的代碼是有這條語(yǔ)句的。


后來(lái)經(jīng)過(guò)驗(yàn)證,這里無(wú)關(guān)緊要。

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


而后來(lái)參考的TQ2440之定時(shí)器中斷0中是將這段代碼放在了中斷服務(wù)函數(shù)當(dāng)中:


不過(guò),按道理來(lái)講,這個(gè)地方不加修改應(yīng)該是可以的。

暫且先總結(jié)這樣一條經(jīng)驗(yàn)吧:如果一些控制語(yǔ)句(比如控制Led燈亮、滅)是要通過(guò)中斷來(lái)驅(qū)動(dòng)執(zhí)行,那么最好將這些控制語(yǔ)句放在中斷服務(wù)程序(也叫中斷處理程序)中。如果只是在中斷服務(wù)程序中控制一個(gè)全局變量(比如flag),而在Main函數(shù)中根據(jù)flag來(lái)驅(qū)動(dòng)控制語(yǔ)句的執(zhí)行,可能得不到預(yù)期效果。

為什么代碼邏輯合情合理卻得不到預(yù)期效果呢?其根源在于,在定義flag時(shí)沒(méi)有加volatile關(guān)鍵字。

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

這里有一篇文章:http://www.cnblogs.com/yc_sunniwell/archive/2010/06/24/1764231.html徹徹底底的解釋了volatile。也正是對(duì)于我在Timer0中斷實(shí)例中遇到的問(wèn)題的詳細(xì)解答。其中關(guān)鍵點(diǎn)如下:

volatile提醒編譯器它后面所定義的變量隨時(shí)都有可能改變,因此編譯后的程序每次需要存儲(chǔ)或讀取這個(gè)變量的時(shí)候,都會(huì)直接從變量地址中讀取數(shù)據(jù)。如果沒(méi)有volatile關(guān)鍵字,則編譯器可能優(yōu)化讀取和存儲(chǔ),可能暫時(shí)使用寄存器中的值,如果這個(gè)變量由別的程序更新了的話,將出現(xiàn)不一致的現(xiàn)象。



評(píng)論


技術(shù)專區(qū)

關(guān)閉