中斷使得高低速設備能夠協調工做(低速設備完成工做後經過中斷的方式通知高速設備一次處理一批數據),中斷還能夠根據不一樣的優先級實現嵌套執行。web
定時器本質上是個 16 位的自增計數器,當發生溢出時,若是開啓了溢出中斷,單片機會自動向 CPU 報告這個溢出中斷,處理相應的中斷任務。svg
TCON 的低 4 位用做外部中斷,高 4 位用做定時控制。地址是 88H。spa
TCON 定時器控制寄存器各個位的意義以下:code
所在位 bit | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
---|---|---|---|---|---|---|---|---|
名稱 | TF1 | TR1 | TF0 | TR0 | IE1 | IT1 | IE0 | IT0 |
CPU 對中斷源的開啓或屏蔽的控制,是經過 IE 寄存器來設置的,IE 既可按字節地址尋址(其字節地址爲 A8H),又可按位尋址。某個中斷對應的位設爲 1 則表示容許中斷,不然禁止。xml
IE 中斷容許控制寄存器各個位的意義以下:blog
所在位 bit | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
---|---|---|---|---|---|---|---|---|
名稱 | EA | - | ET2 | ES | ET1 | EX1 | ET0 | EX0 |
定時器工做在中斷方式時,當定時器的值計滿溢出時,會觸發定時器溢出中斷。token
只要想使用中斷,就必須開啓 EA 總中斷。例如,若是想使用定時器/計數器0,須要添加下面一段 Keil C51 代碼來開啓 EA 和 ET0:事件
EA = 1; // 開啓總中斷 ET0 = 1; // 開啓定時器/計數器0 中斷
或者使用字節操做:圖片
IE |= 0x82; // 設置 IE 寄存器爲 10000010,即開啓總中斷和定時器/計數器0中斷
若是使用匯編語言,開啓外部中斷 0 的彙編代碼,字節操做爲:string
MOV IE,#81H ;MOV 0A8H,#81H; 這裏也能夠直接使用 IE 寄存器的地址 A8H
或者使用匯編語言的位操做:
SETB EA SETB EX0
TMOD 用於控制定時器的工做模式,低4位用於 T0,高4位用於 T1。各個位的意義以下:
所在位 bit | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
---|---|---|---|---|---|---|---|---|
名稱 | GATE | C/T | M1 | M0 | GATE | C/T | M1 | M0 |
所在位 bit | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
---|---|---|---|---|---|---|---|---|
名稱 | - | - | PT2 | PS | PT1 | PX1 | PT0 | PX0 |
所在位 bit | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
---|---|---|---|---|---|---|---|---|
名稱 | SM0 | SM1 | SM2 | REN | TB8 | RB8 | TI | RI |
SM0 | SM1 | 方式 | 說明 | 波特率 |
---|---|---|---|---|
0 | 0 | 0 | 8位數據發送 | fosc/12 |
0 | 1 | 1 | 10位數據發送,包括起始位,中止位 | 可變 |
1 | 0 | 2 | 11位數據發送,包括起始位,中止位 ,校驗位 | fosc/64 |
1 | 1 | 3 | 同方式2 |
51單片機有5箇中斷源,5箇中斷源分別是:
中斷能夠根據優先級實現嵌套,51 系列能夠實現 2 級嵌套(對應優先級寄存器 IP),52 系列能夠實現 4 級嵌套(對應優先級寄存器 IP 和 IPH)。
中斷名稱 | 中斷標誌位 | 中斷號 | 默認優先級 | 中斷入口地址 |
---|---|---|---|---|
外部中斷0 | IE0 | 0 | 高 | 0003H |
定時/計數器0溢出中斷 | TF0 | 2 | ↓ | 000BH |
外部中斷1 | IE1 | 1 | ↓ | 0013H |
定時/計數器1溢出中斷 | TF1 | 3 | ↓ | 001BH |
串口發送或接收中斷 | RI/TI | 4 | 低 | 0023H |
任何中斷的使用都要知足 3 個條件:
EX = 1
EX0=1
中斷系統有一個總的開關 EA(IE 寄存器中),若是想使用中斷,必須打開總開關。
每一箇中斷都有一個單獨的開關,這些單獨的開關跟總開關 EA 同樣,都在 IE 寄存器中。
假設我要每計數 24 次觸發一次溢出中斷,定時器工做在模式 1,則計數初始值爲 65536 - 24 = 65512。
下面代碼使用了外部中斷0,上電後 P1 端口 0 號引腳的 LED 會一直閃爍,首次觸發外部中斷時,P1 端口全部 LED 點亮,再次觸發外部中斷時,0號引腳的 LED 再次開始閃爍,以此循環:
#include <reg52.h> int flag = 1; void delay() { unsigned int a = 50000; while(a--); } void main() { EA = 1;// 開啓中斷總開關 IT0 = 1;// 設置外部中斷0觸發方式,降低沿觸發 EX0 = 1;// 開啓外部中斷0 while(1) { while(flag & 0x01 == 1) { P1 = 0xfe; delay(); P1 = 0xff; delay(); } P1 = 0x00; } } void externelInterrupt() interrupt 0 { flag++; }
電路圖:
/*9600@11.0592M*/ #include <reg52.h> void InitUART(void) { TMOD = 0x20; SCON = 0x50; TH1 = 0xFD; TL1 = TH1; PCON = 0x00; EA = 1; ES = 1; TR1 = 1; } void SendOneByte(unsigned char c) { SBUF = c; while(!TI); TI = 0; } void main(void) { InitUART(); } void UARTInterrupt(void) interrupt 4 { if(RI) { RI = 0; } else TI = 0; }