先看下上一篇的步驟,按照步驟寫出代碼。
1,晶振是12M。
2,一個機器周期時間是1微秒。
3,定時最小分度為50毫秒。
4,所需的初始值是15536.
5,計算出對應初始值的十六位十六進位數是:0x3C B0
6,得出TH0=0x3C,TL0=0xB0。
7,工作模式是定時器,工作方式是16位定時。TMOD=0x01。
8,打開T0定時器開關,ET0=1;TR0=1;
9,打開中斷總開關,EA=1;
10,設置中斷響應函數。void T0_Routine() interrupt 1{}
打開軟體,開始寫程序。
(經過一段時間,程序寫完了)
首先是定義一個用於顯示中斷的LED燈,通過控制閃爍來讓我們看到定時器的工作。
然後是一個用來計算進入定時器多少次的變量,因為我們定時一次是50毫秒,而需要定時一秒的時間,就要定時20次才行,所以需要一個變量,來累積,查著是否到了20次,也就是1秒。
主函數就是設置中斷的參數。
然後是中斷函數,需要注意,每次進入中斷都需要對初始值進行重新賦值,不然進入中斷後的TH0和TL0是空的,都是0x00,會導致計數出現錯誤,進而定時不正確。
定時函數中需要寫入中斷完成需要響應的函數,不然就無法動作。
當然也可以進行其他設置。
寫完後通過仿真看下效果。
示波器中的波形就是小燈的輸出波形,一個是0.25秒,可以看出一個高電位佔了四格,也就是1秒,小燈是亮1秒滅1秒。很精確的。
看完這個案例,有沒有什麼想法呢?
第一個就是為什麼定義變量要定義到最開始,而不是定義到中斷中呢?
第二個是定時器的函數只能在定時器中書寫嗎?
第三個是定時器還有其他用途嗎?
首先看第一個問題,為什麼定義變量要定義到最開始,而不是定義到中斷中呢?
在主程序中,一般都是把用到的變量定義到主程序的內部,為什麼這回吧變量定義到了最開始呢?主程序也沒有用,只有中斷程序用到了,不用定義全局變量的。當我們把這個變量定義到中斷中,會發生什麼呢?
有興趣可以測試下,會發現,中斷沒有輸出,為什麼會發生這種情況?
可以這麼理解一下,當程序進入中斷後,會逐句運行,首先是運行變量的賦值i=0;然後是高低八位數據的重置,接著是i++,累積次數,然後是判斷i是否達到要求,因為此時等於1,所以沒有達到要求,就退出中斷了,主程序繼續運行。然後時間到,進入中斷,進入中斷後,就又是對變量i賦值i=0,這時問題就來了,我們如果每進入一次中斷,就賦值一次,那麼到什麼時候,也無法加到20,也就無法完成led=~led這句指令,對外就無法輸出。
那就沒有辦法了嗎?一個內部變量,定義到全局,會佔用系統資源,明顯的其他程序用不到,只有中斷才能用到。
是有辦法可以解決的,在編程中,有這樣一個方法,當我們定義完變量後,不希望再次讀取該變量時,變量被重複賦值的話,可以使用一個關鍵字,用來說明這個變量是靜態變量,僅定義一次,無需再次賦值,就是說,這個變量的賦值,只會在第一次進入程序時賦值一次,之後就不會再初始化了。
這個關鍵字是「static」,如果把賦值語句前加上static,就會收穫不一樣的效果。
當我們再次運行程序時,就會發現輸出正常了,因為儘管不斷的進入中斷,但對於static unsigned char i=0這條語句,只在第一次進入時讀取了一次,其他時間,進入中斷,都不再做出反應了。這樣以後的i就正常累積了。到了20,才會歸零。
這就是為什麼普通的定義變量只能放在最前邊了。