學習單片機這門課的時候我們肯定會學習到中斷這節,然後就會瞭解到什麼是外部中斷和內部中斷還有串行口中斷,外部中斷包括:外部中斷0(INT0),外部中斷1(INT1);內部中斷包括:定時器/計數器0,定時器/計數器1;我們這裏只講關於定時器T0/T1的知識及使用方法,後面關於其他的知識我們會陸續講解。
標準的51裏邊只有定時器0和定時器1這兩個定時器,現在很多單片機也有多個定時器的,在這裏我們先講定時器0和1。那麼我前邊提到過,對於單片機的每一個功能模塊, 都是由他的SFR,也就是特殊功能寄存器來控制。而和定時器有關的特殊功能寄存器,有以下幾個,大家不需要去記憶這些寄存器的名字和作用,你只要大概知道就行,用的時候,隨時可以查手冊,找到每個寄存器的名字和每個寄存器所起到的作用。
T0有4種工作方式,T1有3種工作方式,每種工作方式都有定時和計數2種方式,故共有14種組合關係。見下表:
定時/計數器控制寄存器 TCON (可位尋址)
關於定時器控制位的描述如下:
*TF0/TF1使用中斷方式時,作爲中斷標誌位,中斷響應後由硬件自動清零;
*TF0/TF1使用查詢方式時,作爲狀態供查詢,查詢有效後應用軟件將該位自動清零。
工作方式控制寄存器 TMOD (不可位尋址)
關於工作方式寄存器的描述如下:
這個地方的意細心的同學會發現,TCON那個地方標註的是“可位尋址”,TMOD這裏標註的是“不可位尋址”。這個地方的意思就是比如TCON有一位TR1,我們可以在程序中直接進行TR1 = 1;這樣操作。但是(T1)M1 = 1;這樣的操作就是錯誤的。我們要操作就必須一次操作一個字節, 就是必須一次性對TMOD所有位操作,不能對其中某一位單獨進行操作。
接下來介紹一下關於定時器工作方式,以及計算公式和計數範圍。
工作方式
T1只有3種工作方式(T0的方式3中佔用了T1的部分資源)
T0
T1
計算公式
定時計數初值 a = 2^x- t×fosc/12
(t ≤2^x us, fosc=12MHz時)
各工作方式的計數範圍
工作方式0
N=2^13-計數初值
即 計數初值=2^13-N,計數範圍即位1~8192
定時時間 t=(2^13-計數初值)(振盪週期12)
假設晶振頻率位12MHz,則最大計數個數爲8192,最大定時時間則爲8.192ms。
由此可知
工作方式1的最大計數個數爲65536,最大定時時間爲65.536ms。
工作方式2的最大計數個數爲256,最大定時時間爲0.256ms。
工作方式3
當T0置成工作方式3時,TL0、TH0爲兩個獨立的計數器
(1)TL0的功能和操作與方式0、1完全相同(定時/計數),使用T0的所有控制位。
(2)TH0只能用作定時功能,並佔用了T1的控制位TR1和中斷標誌位TF1,其啓動僅受TR1的控制。
利用定時器做一個延時1s的流水燈設計
程序代碼如下:
#include"reg52.h" //頭文件
#define LED P1 //端口單片機P1端口名稱爲LED
unsigned char i; //定義一個無符號字符型變量 i
void Delay_50ms(unsigned char Times) //定義一個50ms的子函數
{
while(Times--)
{
/*這裏用的是定時器0,工作方式1,工作方式1的計數最大值是65536us,
1s的話是1000000us,顯然想要達到1s的效果,已經超出了工作方式一的
最大計數值,所以我們採用0.05s,讓它重複執行20次,依次來達到1s的效果,
0.05s也就是50000us,我們根據根據公式可以計算出它的計數初值爲16536,
轉換後換成16進制就是3cb0H*/
TH0 = 0x3C; //計數初值的高8位賦值給TH0
TL0 = 0xB0; //計數初值的低8位賦值給TH0
TR0 = 1; //啓動定時器0
while(!TF0); //判斷T0是否溢出,如果沒有則繼續計數
TF0 = 0; //溢出後清0
}
}
void main(void) //主函數
{
TMOD = 0x01; //設置TMOD的值,表示用的是定時器0,工作方式1
EA=1; //開中斷
ET0=1; //開定時器0中斷
while(1) //死循環
{
for(i=0;i<8;i++) //利用for循環,達到8個燈的流水效果
{
LED=~(0x01<<i); //LED向左循環一位
Delay_50ms(20); //延時1s
}
}
}
仿真電路圖如下:
本次分享就到這裏,喜歡的話可以關注我,一起玩轉單片機,希望我們都可以在這條路上走得越來越遠,路越來越寬❤~