三、中断系统
下面讲复习提纲第三部分:三、中断系统。这一部分常考中断概念、5个中断源、优先级、中断开启三要素、中断程序编写,也经常和定时器、串口、按键控制结合在一起出程序题。
1. 什么是中断
Section titled “1. 什么是中断”复习提纲中的意思是:
单片机正在执行主程序时,遇到紧急突发事件,暂停主程序,跳转执行中断服务程序,执行完返回主程序继续运行。
可以拆成三个动作理解。
第一层:主程序正在正常运行
Section titled “第一层:主程序正在正常运行”比如单片机正在执行流水灯程序:
LED0亮 -> 延时 -> LED1亮 -> 延时 -> LED2亮 -> 延时主程序按原定顺序一条一条执行。
第二层:突然有事件发生
Section titled “第二层:突然有事件发生”例如:
外部按键按下定时器计满溢出串口收到一个字节外部传感器产生脉冲这些事件不一定刚好发生在主程序查询它们的时候。如果只靠主程序循环查询,响应可能会很慢。
第三层:CPU暂停当前任务,先处理紧急事件
Section titled “第三层:CPU暂停当前任务,先处理紧急事件”中断发生后,CPU 会临时放下主程序,转去执行对应的中断服务程序。
主程序执行中 ↓中断请求发生 ↓保存主程序断点 ↓执行中断服务程序 ↓中断返回 ↓继续执行主程序所以中断不是把主程序取消,而是临时插队处理更紧急的事情。
考试定义可以这样写:
中断是指CPU在执行当前程序过程中,因内部或外部事件请求,暂停当前程序,转去执行相应的中断服务程序,处理完毕后再返回原程序继续执行的过程。2. 为什么需要中断
Section titled “2. 为什么需要中断”如果没有中断,单片机只能用查询方式:
while (1){ if (key == 0) { ... } if (TF0 == 1) { ... } if (RI == 1) { ... }}这种方式的问题是:
CPU要不断检查每个事件没有事件发生时也在浪费时间如果主程序某处延时很长,响应就会变慢中断的好处是:
事件不发生时,CPU正常执行主程序事件发生时,硬件自动通知CPUCPU能及时响应突发事件提高实时性减少无意义查询PPT 第6章也强调,中断技术主要用于实时监测与控制,可以避免大量定时查询操作,提高单片机工作效率和实时性。
3. 51 单片机的 5 个中断源
Section titled “3. 51 单片机的 5 个中断源”复习提纲要求掌握 5 个中断源:
外部中断0 INT0定时器0中断 T0外部中断1 INT1定时器1中断 T1串口中断 UART整理成表:
| 中断源 | 标志位 | C51中断号 | 入口地址 | 典型用途 |
|---|---|---|---|---|
| 外部中断0 INT0 | IE0 | interrupt 0 | 0003H | 按键、外部紧急信号 |
| 定时器0 T0 | TF0 | interrupt 1 | 000BH | 周期定时、延时、计时 |
| 外部中断1 INT1 | IE1 | interrupt 2 | 0013H | 第二路外部事件 |
| 定时器1 T1 | TF1 | interrupt 3 | 001BH | 定时、计数、串口波特率相关 |
| 串行口 UART | RI/TI | interrupt 4 | 0023H | 串口接收和发送 |
PPT 讲的是 AT89S52,它比基础 51 多了定时器2中断,所以 AT89S52 有 6 个中断源。但如果题目问“51单片机5个中断源”,就按上面 5 个答。
考试注意:
标准51:常说5个中断源AT89S52:可说6个中断源,多了T24. 中断源逐个理解
Section titled “4. 中断源逐个理解”4.1 外部中断0 INT0
Section titled “4.1 外部中断0 INT0”外部中断0来自 P3.2 引脚,也就是:
P3.2 / INT0它适合接外部按键、传感器、紧急信号。
例如交通灯系统中:
救护车紧急按钮按下 -> INT0触发 -> 单片机立即进入紧急通行状态4.2 定时器0中断 T0
Section titled “4.2 定时器0中断 T0”定时器0计数溢出后产生中断,对应标志是 TF0。
典型用途:
每1ms中断一次累计1000次得到1秒控制LED闪烁控制交通灯倒计时扫描按键刷新显示这类题常和定时器初值计算一起考。
4.3 外部中断1 INT1
Section titled “4.3 外部中断1 INT1”外部中断1来自 P3.3 引脚:
P3.3 / INT1作用和 INT0 类似,只是多一路外部事件输入。
4.4 定时器1中断 T1
Section titled “4.4 定时器1中断 T1”定时器1溢出后产生中断,对应标志是 TF1。
用途与 T0 类似,但 T1 在串口通信中常被用作波特率发生器,所以在串口题中经常看到:
TMOD = 0x20; // T1方式2TH1 = 0xFD; // 产生9600波特率TR1 = 1;此时 T1 不一定开中断,而是给串口提供波特率。
4.5 串口中断 UART
Section titled “4.5 串口中断 UART”串口中断比较特殊,它同时包含发送和接收:
RI = 1:接收完成TI = 1:发送完成它们共用同一个中断入口:
void uart_isr(void) interrupt 4所以中断服务程序中必须判断到底是 RI 还是 TI:
void uart_isr(void) interrupt 4{ if (RI) { RI = 0; // 读取SBUF }
if (TI) { TI = 0; // 发送完成处理 }}特别注意:
串口中断标志RI、TI必须由软件清0。5. 中断请求标志
Section titled “5. 中断请求标志”中断源发生事件后,不是凭空进入中断,而是先置位对应的中断请求标志。
5.1 TCON 中的标志
Section titled “5.1 TCON 中的标志”TCON 既和定时器有关,也和外部中断有关。
常用位:
| 位 | 名称 | 作用 |
|---|---|---|
| TF1 | T1溢出标志 | T1溢出时置1 |
| TR1 | T1运行控制 | 1启动T1,0停止T1 |
| TF0 | T0溢出标志 | T0溢出时置1 |
| TR0 | T0运行控制 | 1启动T0,0停止T0 |
| IE1 | INT1中断请求标志 | 外部中断1触发时置1 |
| IT1 | INT1触发方式 | 0电平触发,1下降沿触发 |
| IE0 | INT0中断请求标志 | 外部中断0触发时置1 |
| IT0 | INT0触发方式 | 0电平触发,1下降沿触发 |
例如:
IT0 = 1; // 设置INT0为下降沿触发5.2 SCON 中的串口标志
Section titled “5.2 SCON 中的串口标志”串口控制寄存器 SCON 中的低两位是:
TI:发送中断标志RI:接收中断标志接收一帧数据完成后:
RI = 1发送一帧数据完成后:
TI = 1但它们不会自动清零,所以必须写:
RI = 0;TI = 0;6. 中断开启三要素
Section titled “6. 中断开启三要素”复习提纲中“中断开启三要素”非常重要,程序题几乎都要用。
可以记成:
总开关 + 分开关 + 触发/模块设置6.1 第一要素:开总中断 EA
Section titled “6.1 第一要素:开总中断 EA”EA 是总中断开关。
EA = 1; // 允许总中断EA = 0; // 禁止所有中断如果 EA=0,即使某个中断源自己的允许位开了,也不会响应中断。
6.2 第二要素:开对应中断允许位
Section titled “6.2 第二要素:开对应中断允许位”不同中断源有不同允许位。
| 中断源 | 允许位 |
|---|---|
| 外部中断0 | EX0 |
| 定时器0 | ET0 |
| 外部中断1 | EX1 |
| 定时器1 | ET1 |
| 串口 | ES |
例如开 T0 中断:
ET0 = 1;EA = 1;开串口中断:
ES = 1;EA = 1;6.3 第三要素:设置触发方式或模块工作方式
Section titled “6.3 第三要素:设置触发方式或模块工作方式”不同中断还要做不同初始化。
外部中断要设置触发方式:
IT0 = 1; // INT0下降沿触发定时器中断要设置定时器方式、初值、启动:
TMOD = 0x01;TH0 = 0xFC;TL0 = 0x18;TR0 = 1;串口中断要设置串口方式、允许接收、波特率:
SCON = 0x50;TMOD |= 0x20;TH1 = 0xFD;TR1 = 1;7. IE 中断允许寄存器
Section titled “7. IE 中断允许寄存器”IE 是中断允许寄存器,控制中断是否开放。
常用位:
| 位 | 名称 | 含义 |
|---|---|---|
| IE.7 | EA | 总中断允许 |
| IE.4 | ES | 串口中断允许 |
| IE.3 | ET1 | 定时器1中断允许 |
| IE.2 | EX1 | 外部中断1允许 |
| IE.1 | ET0 | 定时器0中断允许 |
| IE.0 | EX0 | 外部中断0允许 |
如果用位操作:
EA = 1;EX0 = 1;如果用字节操作,要能看懂:
IE = 0x81; // 1000 0001,EA=1,EX0=1IE = 0x82; // 1000 0010,EA=1,ET0=1IE = 0x90; // 1001 0000,EA=1,ES=1复位后 IE 通常为 0,所以所有中断默认关闭。
8. 中断优先级
Section titled “8. 中断优先级”复习提纲给出的默认优先级是:
外部中断0 > 定时器0 > 外部中断1 > 定时器1 > 串口这句话要背。
8.1 为什么需要优先级
Section titled “8.1 为什么需要优先级”如果两个中断几乎同时发生,CPU 必须决定先处理谁。
例如:
定时器0刚好溢出同时外部中断0按键触发如果优先级相同或默认情况下,会按内部查询顺序响应。外部中断0排在前面。
8.2 高低优先级规则
Section titled “8.2 高低优先级规则”PPT 第6章总结的规则可以这样记:
低优先级可以被高优先级打断高优先级不能被低优先级打断同级中断之间不能互相打断例如:
CPU正在执行低优先级T0中断此时高优先级INT0到来CPU可以暂停T0中断,先执行INT0中断但如果正在执行高优先级 INT0,中途来了低优先级串口中断,就不会立刻打断 INT0。
8.3 IP 中断优先级寄存器
Section titled “8.3 IP 中断优先级寄存器”IP 用于设置哪些中断为高优先级。
常用位:
| 位 | 名称 | 作用 |
|---|---|---|
| PS | 串口优先级 | |
| PT1 | 定时器1优先级 | |
| PX1 | 外部中断1优先级 | |
| PT0 | 定时器0优先级 | |
| PX0 | 外部中断0优先级 |
例如设置外部中断0为高优先级:
PX0 = 1;设置 T0 为高优先级:
PT0 = 1;如果不设置 IP,复位后各中断默认低优先级。
9. 中断响应过程
Section titled “9. 中断响应过程”中断响应不是“跳过去就完事”,内部有一套过程。
可以按下面顺序理解:
1. 中断源产生中断请求,置位标志2. CPU检查EA和对应允许位3. 判断优先级和当前是否允许响应4. 当前指令执行完毕5. 保存断点地址到堆栈6. 跳转到对应中断入口7. 执行中断服务程序8. 执行RETI返回9. 从堆栈取回断点,继续主程序这里有两个重要点。
当前指令执行完才响应
Section titled “当前指令执行完才响应”CPU 不会把正在执行的一条指令切成两半。一般是当前指令执行完后才响应中断。
返回要用 RETI
Section titled “返回要用 RETI”汇编中断服务程序结尾用 RETI,不是普通 RET。C51 中写 interrupt n 后,编译器会自动生成正确的中断返回代码。
10. C51 中断函数写法
Section titled “10. C51 中断函数写法”C51 中断函数格式:
void 函数名(void) interrupt 中断号{ // 中断服务程序}常用中断号:
0:外部中断01:定时器02:外部中断13:定时器14:串口例子:外部中断0控制 LED 翻转。
#include <reg51.h>
sbit LED = P1^0;
void main(void){ LED = 1; // 低电平点亮,初始熄灭 IT0 = 1; // INT0下降沿触发 EX0 = 1; // 开外部中断0 EA = 1; // 开总中断
while (1) { // 主程序可执行其他任务 }}
void int0_isr(void) interrupt 0{ LED = !LED; // 每触发一次翻转LED}11. 中断程序编写注意事项
Section titled “11. 中断程序编写注意事项”11.1 中断服务程序要短
Section titled “11.1 中断服务程序要短”中断用于快速处理紧急事件,不适合写长延时。
不推荐:
void int0_isr(void) interrupt 0{ delay(50000); // 不推荐在中断里长时间延时}更推荐:
void int0_isr(void) interrupt 0{ key_flag = 1; // 设置标志,主程序再处理}11.2 中断和主程序共享变量要小心
Section titled “11.2 中断和主程序共享变量要小心”例如:
volatile unsigned char key_flag = 0;volatile 的意思是这个变量可能在中断中被改变,提醒编译器不要错误优化。
11.3 串口中断必须清 RI/TI
Section titled “11.3 串口中断必须清 RI/TI”if (RI){ RI = 0;}if (TI){ TI = 0;}忘记清零会导致中断反复进入。
11.4 定时器方式1通常要重装初值
Section titled “11.4 定时器方式1通常要重装初值”定时器方式1溢出后从 0 开始,如果要周期定时,需要在中断里重新装初值:
void timer0_isr(void) interrupt 1{ TH0 = 0xFC; TL0 = 0x18;}方式2自动重装则不需要手动重装 TLx。
12. 常见考法
Section titled “12. 常见考法”考法1:问中断概念
Section titled “考法1:问中断概念”题目:
什么是中断?答案:
中断是CPU执行当前程序时,由于内部或外部事件请求,暂停当前程序,转去执行相应中断服务程序,处理完后再返回原程序继续执行的过程。考法2:写 5 个中断源
Section titled “考法2:写 5 个中断源”答案:
外部中断0、定时器0中断、外部中断1、定时器1中断、串行口中断。考法3:问默认优先级
Section titled “考法3:问默认优先级”答案:
外部中断0 > 定时器0 > 外部中断1 > 定时器1 > 串行口。考法4:问开中断三要素
Section titled “考法4:问开中断三要素”答案:
开总中断EA,开对应中断允许位,如EX0、ET0、ES等,并设置中断触发方式或相关功能模块工作方式。考法5:写 T0 中断初始化
Section titled “考法5:写 T0 中断初始化”TMOD = 0x01;TH0 = 0xFC;TL0 = 0x18;ET0 = 1;EA = 1;TR0 = 1;考法6:写串口中断服务程序
Section titled “考法6:写串口中断服务程序”要点:
判断RI读取SBUF清RI判断TI清TI13. 易混点
Section titled “13. 易混点”1. EA 和 EX0/ET0/ES 不是一回事
Section titled “1. EA 和 EX0/ET0/ES 不是一回事”EA:总开关EX0/ET0/ES:分开关只有总开关和分开关都打开,中断才可能响应。
2. 中断标志和中断允许位不是一回事
Section titled “2. 中断标志和中断允许位不是一回事”标志位:事件是否发生允许位:是否允许CPU响应这个事件例如 TF0=1 表示 T0 溢出,但如果 ET0=0,CPU 仍不会进入 T0 中断。
3. 串口中断源只有一个入口
Section titled “3. 串口中断源只有一个入口”虽然有 RI 和 TI 两个标志,但它们共用:
interrupt 4所以程序里必须判断来源。
4. 外部中断触发方式要分清
Section titled “4. 外部中断触发方式要分清”IT0=0:低电平触发IT0=1:下降沿触发按键中断常用下降沿触发。
5. 中断函数不要写返回值和参数
Section titled “5. 中断函数不要写返回值和参数”C51 中断函数通常写:
void timer0_isr(void) interrupt 1不要写成:
int timer0_isr(int x)第三部分背诵版
Section titled “第三部分背诵版”中断是指CPU在执行主程序过程中,由于内部或外部事件请求,暂停当前程序,转去执行相应的中断服务程序,处理完后再返回原程序继续执行的过程。中断可以提高系统实时性,减少CPU查询等待。
51单片机常见5个中断源为:外部中断0、定时器0中断、外部中断1、定时器1中断和串行口中断。其默认优先级顺序为:外部中断0 > 定时器0 > 外部中断1 > 定时器1 > 串口。外部中断0对应P3.2/INT0,外部中断1对应P3.3/INT1,串口中断由RI和TI共同触发。
开启中断通常需要三个条件:开总中断EA,开对应中断允许位,如EX0、ET0、ES等,并设置触发方式或相关模块工作方式。外部中断触发方式由IT0、IT1设置,0为低电平触发,1为下降沿触发。串口中断服务程序中必须判断RI和TI,并用软件清零。