文 |阿飛
寫于2020-1-25
從名稱上就可以看出來,這部分內容有兩個主要功能模式:定時模式和計數模式。
工作在定時模式時,每經過一個機械周期,內部的16位計數寄存器數值就會加1單片機定時器里寫程序,寄存器裝滿時就會溢出,對應的標志位就會被置高,計時會從我們存放的初值開始計時,一直到16位的寄存器存滿時產生溢出,因此在最大計時范圍內,我們只要計算出需要存放的初值,就可以準確的產生任意時間的定時。
工作在計數模式時,對應的計數器輸入引腳每產生一個脈沖,計數寄存器就會加1。
使用定時/計數器步驟主要分為以下幾步:
這節課我們主要講解一下定時器的基礎知識:
我們先來看TCON寄存器高四位的使用:以定時器0為例,圖中可以看到,TR0是定時器0的運行控制位,在TOMD.3 = 0的情況下(這也是我們常用的):當TR0 = 1時,定時器0會開始計時單片機定時器里寫程序,TR0 = 0時,定時器0會禁止計時,因此,在啟用定時器時,需要將TR0置高,“TR0 = 1”。TF0是定時器0的溢出標志,圖中也可以看到,定時器0計滿時,此標志位會被置高,在打開了定時器0中斷的情況下,標志位會在響應中斷后被硬件清0,也可以在程序的循環掃描中通過程序查詢標志位并清0。(定時器1也是類似的)
再來看一下TMOD寄存器的使用:
從圖中可以看到,TMOD寄存器是不可位尋址的,因此在使用時只能對此寄存器進行整體賦值(例:TMOD = 0x01;)圖中的高四位(4~7)是定時器1的控制位,低四位(0~3)是定時器0的控制位,以下介紹仍然以定時器0為例(定時器1也是類似的):
GATE(TMOD.3)控制定時器0的打開方式(前邊講過的,這里我們一般配置為0,不做太多講解)
C/T(TMOD.2)用來控制定時/計數器是工作在定時模式還是計數模式(當TMOD.2 = 1時工作在計數模式,TMOD.2 = 0時工作在定時模式)
M1(TMOD.1)與M0(TMOD.0)共同控制定時器0的定時模式,共有4種工作模式(0、1、2、3),這里我們常用的是模式1(M1 = 0、M0 = 1時),此時定時器的高8位與低8位全用,溢出值為65535,因此,當使用定時器0時,TMOD寄存器應配置為:“TMOD = 0x01; ”。(其它三個模式如果用到了會再講,大家也可以去問一下百度)
現在就只剩下了最后一步:存放定時器初值,因為51單片機定時器默認為12分頻的,因此,單片機的機械頻率 = 晶振頻率 / 12,機械周期 = 12 / 晶振頻率,外接的晶振是11.的頻率,因此可計算出機械周期 = 12 / 11.0592 = 1.085(us)。也就是說,每隔1.085us,計數值會加1,我們只要用目標時間除以1.085us就是需要計數多少次,再用溢出值(65535)減去計數次數就得到了我們的需要存放的初值,我舉個栗子:假設計時5ms, 5ms / 1.085us = 4608 ;65535 - 4608 = 60927;這個60927就是我們需要存放的初值,把高8位存放到TH0中,低8位存放到TL0中就可以啦,因此:TH0 = 0xed; TL0 = 0x14;每次計時結束后進行下次計時時,初值會被清零,因此我們需要在查詢TF標志位時重裝初值。
好的,現在用程序來實現以下以上講到的內容(led間隔500ms閃爍,假設LED直接由P1端口控制):
接下來我們把定時器與中斷配合起來使用(依然以定時器0為例):
結合這兩張圖與上次講的內容我們知道,打開定時器0中斷時需要配置:“ EA = 1; ET0 = 1;”
配置好以后,每次定時器計滿溢出時,程序會響應對應的中斷,前邊講的,當打開了定時器對應的中斷時,每次定時滿響應了溢出中斷以后,溢出標志位TF會被硬件清零,因此,我們就不需要在程序中編寫 “掃描TF狀態” 與 “清零TF標志” 的操作。
編寫中斷服務函數時需要在函數名后邊加上中斷編號: 1(定時器0),別忘了在中斷服務函數中重放初值哦
在這里要強調一點:在中斷服務函數里邊不要放延時函數和死循環,也很好理解的,假如說我定時2ms,定時時間到了以后會執行中斷服務函數,同時定時器會重新計時,當這里有延時函數與死循環時很容易造成這次中斷服務函數還沒有執行完,下一次又該開始了,程序很容易會跑飛的,因此,加了松手檢測與按鍵消抖的按鍵掃描函數一定不能放里邊
好的,接下來我們用程序來實現一下(與上一程序功能相同的):
小練習
(1)使用定時器控制數碼管任意一位顯示數值0~9(每隔1秒數值加1)。
(2)把我們將機械按鍵時寫的那個用延時函數實現的秒表程序改為定時器計時。
▼更多藍橋杯文章▼
掃碼入群
掃碼添加管理員微信
加入“電子產品世界”粉絲交流群