(C51學習四)外部中斷和定時器中斷
1.什麼是中斷
2.中斷有什麼用
3.雙重功能的P3引腳
4.8051的 中斷體系
5.中斷特殊暫存器
6.中斷的優先順序
7.中斷服務程式的編寫
8.外部中斷實現程式碼
9.定時器/計數器中斷工作原理
10.定時器/計數器定時值的計算
11.定時器/計數器實現程式碼
1.什麼是中斷
中斷就是指CPU正在執行一項任務A,然後突然停止任務A去執行任務B,執行完任務B再回來繼續執行任務A的過程。
例如:你正在看電視,然後電話響了,你就停止看電視,跑去接電話,接完電話後由回來繼續看電視。這個過程叫中斷。
中斷跟硬體有關。可以說是硬體來讓微控制器中斷。
2.中斷有什麼用
1.中斷能讓CPU同時執行多項任務,例如CPU在執行流水燈程式,就無法執行 按下按鍵時,蜂鳴器發聲了。
2.當然上面的例子可以用軟體輪詢檢擦案件是否按下來實現,但這樣就消耗了CPU一部分資源來輪詢檢測 按鍵是否有按下了,所以中斷的另一個優點就是
節省CPU資源
3.雙重功能的P3引腳
由最小系統板的原理圖可知,P3.0~P3.7的引腳對應著RXD,TXD,INTO,INT1,T0,T1等,說明P3引腳既是 I/O口,由有別的功能,這個功能就是中斷功能。
4.8051中斷體系
8051的微控制器有5箇中斷源,2個優先順序
由上圖可知,INT0是通過引腳P3.2,INI1時通過引腳P3.3,定時器T0和T1是分別通過引腳P3.4和P3.5的
中斷源:INT0(外部中斷0),INT1(外部中斷1),T0(定時器0),T1(定時器1),RXD和TXD(同屬串列埠中斷)
中斷相關的特殊暫存器:
(1)中斷允許控制暫存器(IE)--------控制各中斷的開放和遮蔽
(2)定時器/計數器控制暫存器(TCON)-------定時器和外部中斷的控制
(3)序列口控制暫存器(SCON)-------序列中斷的控制
(4)中斷優先順序控制暫存器(IP)-------設定各中斷的優先順序
各暫存器的控制範圍如下圖:
從上圖可看出從中斷源產生請求到請求進入CPU的過程:
以INT0為例,INT0產生中斷源,經過TCON暫存器中的IT0為選擇是下邊沿觸發的還是低電平觸發的中斷請求(當然IT0是程式人工設定的),當中斷請求到達IE0的時候,
IE0會被硬體置1(當CPU響應此中斷請求時,IE0被硬體置0),然後就到 IE暫存器的地方了,EX0是外部中斷INT0的開關,而 EA 是所有中斷的總開關,這都由 IE暫存器
控制,最後經過 IP暫存器 設定優先順序,這個一般比較少用,預設的優先順序為,INT0 > T0 > INT1 > T1 >串列埠中斷。最後把中斷請求傳給CPU。
5.中斷特暫存器
TCON暫存器
IE暫存器
EA:中斷的總開關,EA=1才能允許中斷傳給CPU
ES:序列口中斷開關
ET1:定時器1中斷開關
EX1:外部中斷1開關
ET0:定時器0中斷開關
EX0:外部中斷0開關
IP優先順序暫存器(對應為設定成1說明優先順序設定成高,8051只有高低兩種優先順序)
6.中斷的優先順序
8051只有高低兩種優先順序,預設下優先順序從高到低:INT0 > T0 > INT1 > T1 > 序列中斷。
1.高優先順序的中斷可以打斷低優先順序的中斷。
2.正在響應的中斷,不能被同級或者低階的中斷打斷。
3.同時發生幾個中斷,先響應優先順序高的中斷
7.中斷服務程式的編寫
中斷服務程式就是中斷髮生後,CPU去執行的函式。
1.中斷服務函式沒有返回值
2.中斷服務函式不能傳入引數
例如:
void 函式名 (void) interrupt x using y
{
}
x 範圍為0~4,分別代表5箇中斷源,例如外部中斷INT0就是0,T0就是1,INT1就是2,T1就是3,序列中斷就是4
y 的範圍為0~3,分別表示4組工作暫存器,不寫就用0. 不寫也可以
8.外部中斷實現程式碼
#include<reg52.h>
sbit LED=P1^0;
void main()
{
IT0=0; //中斷觸發方式為低電平觸發,IT0=1則為下邊沿觸發
EX0=1; //開啟外部中斷0
EA=1; //開啟中斷總開關
while(1)
{
LED=1; //在沒有中斷髮生時,LED關閉
}
}
void INTERR(void) interrupt 0
{
LED=0;//有中斷髮生時,LED亮起
}
把開發板的P3.2用杜邦線接到GND上,就會觸發中斷,發現LED亮起來了。(為什麼是P3.2?因為由最上面的原理圖可知道INT0的引腳是P3.2)
9.定時器/計數器中斷工作原理
1.由最上面的最小系統原理圖可以看出,定時器T0和T1分別對應的引腳是P3.4和P3.5
2.定時器/計數器 的計數脈衝來源可以有兩個,一個是晶片內部晶振振盪器輸出脈衝12分頻後的脈衝,一個是從外部接入的外部脈衝
3.TLx和THx暫存器,x=0,1。
以TL0和TH0為例,TL0和TH0 都是8位暫存器(8051的暫存器都是8位),所以TL0和TH0形成高八位和低八位暫存器,用於計數,一共16位。
2^16=65536,所以 TL0和TH0加一起最大能計數的值是0~65536,一共65536.
4.定時器/計數器的兩個暫存器:TCON和TMOD,其中TCON用於開啟定時器/計數器中斷,TMOD用於設定定時器/計數器的工作方式(TCON上面 已經說過了)
TMOD暫存器:
(由圖:低八位為定時器T0,高八位為定時器T1)
GATE:門控制。
當GATE=1:INTx引腳為高電平且TRx 要同時為1,定時器Tx才啟動。
當GATE=0:只要TRx =1,定時器Tx就啟動,不用理會INTx引腳的電平高低。
C/T:決定是使用 定時功能,還是 計數功能
當C/T=0:定時功能。加1計數器對晶片晶振12分頻的脈衝計數,一個脈衝過來,就加一,直到 TFx 加滿了溢位。(TFx在TCON暫存器中)
當C/T=1:計數功能。加1計數器對來自輸入引腳T0(P3.4)或T1(P3.5)的外部脈衝進行計數,一個脈衝加一,直到TFx加滿溢位。
M1和M0:工作方式選擇位
M0 | M1 | 工作方式 | 功能說明 |
0 | 0 | 方式0 | 13位定時器/計數器,最大計數為2^13 = 8192 |
0 | 1 | 方式1 | 16位定時器/計數器,最大計數為2^16 = 65536 |
1 | 0 | 方式2 | 自動過載8位定時器/計數器,最大計數為 2^8 = 256 |
1 | 1 | 方式3 | T0分為2個獨立的8位獨立計數器,T1停止工作 |
10.定時器/計數器定時數值的計算
例:我要定時10ms。晶振頻率是12M,工作模式在方式1
f = 12M/12 =1M (因為要12分頻),也就是說 1秒 1000000個機器週期,10ms有10000個機器週期。
65536 - 10000 = 55536 ,意思是 計數器從65536 一直減到 55536 所用的時間就是10ms。
55536的十六進位制是0xD8F0
所以設定 TH0 = 0XD8,TL0=0XF0
下面給出程式碼
或者直接下載一個C51定時器計算器:
11.定時器/計數器程式碼
#include<reg52.h>
sbit LED0=P1^0;
unsigned char i;
void main()
{
TMOD=0X01; //設定使用定時器0,16位的定時/計數暫存器
TL0=0xD8; //低八位賦初值
TH0=0XF0; //高八位賦初值
ET0=1; //開啟定時器0中斷
TR0=1; //執行定時器0
EA=1; //開啟中斷總開關
while(1);
}
void Delay(void) interrupt 1 using 0
{
i++;
TR0=0; //進入中斷函式時,關閉定時器
TL0=0XD8; //重新賦初值
TH0=0XF0;
if(i==20) //因為10ms一次處罰看不出明顯結果,所以讓20次觸發才讓燈變一次
{
LED0=~LED0;
}
TR0=1; //重新開啟定時器
}