中斷核心概念
- 中斷源: 引發中斷的事件 (如引腳電平變化、定時器溢出、串口收發完成)。
- 中斷請求: 源向 CPU 發出的服務信號 (由硬件置位對應標誌位)。
- 中斷響應: CPU 暫停主程序,保護現場 (PC 入棧),跳轉中斷向量地址執行 ISR。
- 中斷返回:
RETI 指令恢復現場 (PC 出棧),回主程序斷點繼續。
- 中斷系統: 實現上述功能的硬件電路總稱 (中斷控制器、向量表、優先級仲裁)。
80C51 五大中斷源與向量地址
| 中斷源 | 引腳/標誌 | 觸發條件 | 標誌位 | 向量地址 | 默認優先級 |
| 外部中斷 0 | INT0 (P3.2) | 低電平 / 下降沿 (由 IT0 決定) | IE0 (TCON.1) | 0003H | 1 (最高) |
| 定時器 0 溢出 | TF0 (TCON.5) | T0 計數溢出 | TF0 | 000BH | 2 |
| 外部中斷 1 | INT1 (P3.3) | 低電平 / 下降沿 (由 IT1 決定) | IE1 (TCON.3) | 0013H | 3 |
| 定時器 1 溢出 | TF1 (TCON.7) | T1 計數溢出 | TF1 | 001BH | 4 |
| 串口中斷 | RI (SCON.0) / TI (SCON.1) | 接收完成 / 發送完成 | RI / TI | 0023H | 5 (最低) |
中斷控制寄存器詳解
1. TCON (TCON SFR, 0x88) — 定時/計數器控制 & 外部中斷觸發/標誌
| 位 | 符號 | 說明 |
| TCON.0 | IT0 | 外部中斷 0 觸發模式:0=電平觸發,1=下降沿觸發 |
| TCON.1 | IE0 | 外部中斷 0 請求標誌 (硬件置位,CPU響應後硬件自動清零/沿觸發需軟件清零) |
| TCON.2 | IT1 | 外部中斷 1 觸發模式:0=電平觸發,1=下降沿觸發 |
| TCON.3 | IE1 | 外部中斷 1 請求標誌 |
| TCON.4 | TR0 | 定時器 0 運行控制 (1=啟動) |
| TCON.5 | TF0 | 定時器 0 溢出標誌 (硬件置位,進入 ISR 硬件自動清零) |
| TCON.6 | TR1 | 定時器 1 運行控制 |
| TCON.7 | TF1 | 定時器 1 溢出標誌 |
2. SCON (SCON SFR, 0x98) — 串口控制 & 中斷標誌
| 位 | 符號 | 說明 |
| SCON.0 | RI | 接收中斷標誌:收完一幀硬件置 1,**必須軟件清零** |
| SCON.1 | TI | 發送中斷標誌:發完一幀硬件置 1,**必須軟件清零** |
| SCON.7 | SM0 | 串口模式選擇位 (與 SM1 組合) |
3. IE (IE SFR, 0xA8) — 中斷允許控制 (總開關 + 分開關)
| 位 | 符號 | 說明 |
| IE.0 | EX0 | 外部中斷 0 允許 |
| IE.1 | ET0 | 定時器 0 中斷允許 |
| IE.2 | EX1 | 外部中斷 1 允許 |
| IE.3 | ET1 | 定時器 1 中斷允許 |
| IE.4 | ES | 串口中斷允許 |
| IE.7 | EA | **總中斷允許 (CPU 全局開關)**,0=屏蔽所有中斷 |
初始化模板: EA = 1; EX0 = 1; ET0 = 1; ES = 1; // 按需開啟
4. IP (IP SFR, 0xB8) — 中斷優先級控制 (兩級制)
| 位 | 符號 | 說明 |
| IP.0 | PX0 | 外部中斷 0 優先級 |
| IP.1 | PT0 | 定時器 0 優先級 |
| IP.2 | PX1 | 外部中斷 1 優先級 |
| IP.3 | PT1 | 定時器 1 優先級 |
| IP.4 | PS | 串口優先級 |
| IP.5 | PT2 | 定時器 2 優先級 (8052/增強型) |
置 1 = 高優先級,置 0 = 低優先級。默認全 0,按向量表順序仲裁。
中斷嵌套與優先級仲裁規則
- 同級不嵌套: 正在執行的中斷,不能被同級或低優先級中斷打斷。
- 高優先級可搶佔低優先級: 低優先級 ISR 執行中,來高優先級請求 → 保護現場 → 跳高優先級 ISR → 返回低優先級繼續。
- 同時到達: 硬件按「IP 設定優先級 > 默認向量表順序」仲裁,只響應最高者,其餘保留標誌等待。
- 二級嵌套上限: 80C51 只有兩級優先級,最多實現**二級嵌套** (高中斷低)。不支持三級以上。
中斷服務程序 (ISR) 編寫規範
// 外部中斷 0 ISR (下降沿觸發示例)
void INT0_ISR(void) interrupt 0 { // interrupt 0 對應 0003H
// 1. 讀取/處理數據 (儘量短)
// 2. 清除標誌 (沿觸發外部中斷需軟件清 IE0,電平觸發硬件自清)
// 3. 設置標誌位通知主循環 (避免 ISR 中做耗時操作)
P1_0 = ~P1_0; // 翻轉 LED 示例
}
// 定時器 0 ISR
void TIMER0_ISR(void) interrupt 1 { // 000BH
TH0 = TL0 = 0xXX; // 重裝初值 (模式 0/1 需手動)
// 任務...
}
// 串口 ISR (RI/TI 共用一個向量)
void UART_ISR(void) interrupt 4 { // 0023H
if (RI) {
RI = 0; // 必須軟件清零
rx_buf[rx_head++] = SBUF;
}
if (TI) {
TI = 0; // 必須軟件清零
// 發送完成處理
}
}
避坑檢查清單
- ✅
EA = 1 最後設置,防止初始化過程誤進中斷。
- ✅ 外部中斷沿觸發模式 (
IT0/IT1) 需在允許中斷前配置。
- ✅ 串口 RI/TI、外部中斷電平觸發標誌必須軟件清零,否則死循環進中斷。
- ✅ ISR 盡可能短,耗時操作 (延時、Flash 擦寫、複雜運算) 放主循環,用標誌位觸發。
- ✅ 共享變量 (ISR 與主循環) 用
volatile 修飾,必要時關中斷保護訪問。
- ✅ 優先級配置:時間關鍵 (定時器、外部邊沿) 設高;串口、非緊急設低。
- ✅ 使用
interrupt n 關鍵字 (Keil C51) 自動生成向量跳轉與現場保護,勿手寫汇編跳轉。
總結
51 單片機中斷系統 = 5 源 + 2 級優先級 + 3 大控制寄存器 (TCON/SCON/IE/IP)。掌握「標誌怎麼置、誰清零、優先級怎麼配、嵌套規則是啥」,配合規範 ISR 寫法,即可駕馭所有中斷應用場景。記住:中斷是雙刃劍,用好了實時性強,用不好系統亂套。