上一次我們簡單了解了單片機的中斷概念
這一次我們著重了解單片機的定時器中斷
先補充點知識
補 : 單片機的幾個周期
1:時鐘周期:也稱振蕩周期,就是外接晶振的倒數(shù),如12M的晶振,時鐘周期就是1/12um,他是最基本最小的時間單位。
2:狀態(tài)周期:時鐘周期的兩倍。
3:機器周期。單片機的基本操作周期,在一個周期內(nèi)單片機完成一項基本操作,他由12個時鐘周期組成,比如12M的晶振,那么機器周期就是1um。其實機器周期就是完成一個單指令的時間。
4:指令周期。他是指CPU執(zhí)行一條指令所需的時間。比如有單周期指令,雙周期指令三周期指令等等。
1 定時器簡單概念了解
1 定時器系統(tǒng)是單片機內(nèi)部獨立的一個硬件部分
2 定時器與晶振cpu相連
3 一但設(shè)置開始定時后,定時器在晶振的作用下自動開始計時
注意:1 TMOD 的字節(jié)地址位89H是不可尋位址
所以寫代碼的時候要不能位操作,只能TMOD = 0x01;這樣子
2 TMOD中高四位用于設(shè)置定時器1 低四位用于設(shè)置定時器0
3 TMOD常用的模式有方式1(常用) 2(偶爾)其余幾乎不用
4 TMOD 只控制定時器的工作方式和功能選擇
舉個栗子:
TMOD = 0x01;// 0000 0001
(定時器0,GATE=0 啟動僅受寄存器TRX控制 C/T=0 定時器模式 M1=0 M0=1 工作模式1 16位定時器)
2 TCON
注意:1 TCON字節(jié)地址位88H 可進行位尋址
2 單片機復(fù)位TCON全部被清零
這里我們先著重記幾個
1 TF1 定時器1溢出標(biāo)志位
2 TF0 定時器0溢出標(biāo)志位
3 TR1 定時器1運行控制位
4 TR0 定時器0運行控制位
3 工作原理
4 初值問題
注意 :1 沒有設(shè)置TH0和TL0 默認值都是0
所以要溢出需要65536個數(shù) 1111 1111 1111 1111
?。?5535達到滿值,65536則溢出將TF0 置1)
舉個栗子:
假如我們要定時50ms(較常用的一個時間)
單片機的晶振是12MHz 12個時鐘周期位1個機器周期 (1/12MHz )*12 = 1微秒
我們定時50ms一次 即裝完初值后,在(50/1)*10^3 =50000個數(shù)后溢出
所以初值為 65536-50000 = 15536個數(shù)
15536 又要化成16進制 先分出高八位和低八位
15536/256=60裝入TH0 15536%256=176裝入TL0
5 中斷服務(wù)程序的寫法
定時器中斷序號為3 定時器1
2 編程
1 目標(biāo) : 實現(xiàn)第一個發(fā)光二極管以1s亮滅閃爍
2 代碼
#include
2 #define uint unsigned int
3 #define uchar unsigned char
4 sbit LED1 = P1^0;
5 uchar num;
6 void main()
7 {
8 TMOD = 0x01; // 定時器0 工作方式1
9 TH0 = (65536 - 45872)%256;
10 TL0 = (65536 - 45872)/256;
11 EA = 1; //開關(guān)總斷
12 ET0 = 1; // 開定時器0中斷
13 TR0 = 1; //啟動定時器0
14 while(1); //程序停止等待中斷發(fā)生
15 }
16
17 void T0_time() interrupt 1
18 {
19 TH0 = (65536 - 45872)%256;
20 TL0 = (65536 - 45872)/256;
21 num++;
22 if(num == 20)
23 {
24 num = 0;
25 LED1 = ~LED1;
26 }
27
28 }
3 分析:
1 設(shè)置好TMOD后 要對應(yīng)ET0 TR0 TH0 TL0
2 不要省事情把45872 寫成 (5000/(12/11.0592))
11.0592是小數(shù),無法轉(zhuǎn)化成 16進制
3 為了確保定時器中斷每次都是50ms 我們需要在中斷函數(shù)中每次為TH0 和TL0
重新裝入初值
4 定的是50ms 用一個變量num統(tǒng)計每二十次執(zhí)行程序 即每1s亮滅
改良代碼:
#include2#defineuintunsignedint3#defineucharunsignedchar4sbitLED1=P1^0;5ucharnum;6voidmain()7{8TMOD=0x01;//定時器0工作方式19TH0=(65536-45872)%256;10TL0=(65536-45872)/256;11EA=1;//開關(guān)總斷12ET0=1;//開定時器0中斷13TR0=1;//啟動定時器014while(1);//程序停止等待中斷發(fā)生15if(num==20)16{17num=0;18LED1=~LED1;19}2021}2223voidT0_time()interrupt124{25TH0=(65536-45872)%256;26TL0=(65536-45872)/256;27num++;28}
留一個作業(yè) 大家可以自己寫寫看
用定時器0實現(xiàn)第一個發(fā)光二極管以200ms間隔閃爍 并且用定時器1 實現(xiàn)數(shù)碼管前兩位59s循環(huán)計時
以上的內(nèi)容都是博主看書,自己的一些思考。大家還是應(yīng)該多看些書籍才能夠理解的更好