51单片机基础-外部中断INT
第十三章 外部中断
1. 导入
在前几章中,我们通过轮询方式检测按键、控制电机等,但这种方式占用CPU资源,且响应不及时。为实现快速响应外部事件(如紧急停止、按键触发),本章引入外部中断功能。
51单片机提供两个外部中断源:INT0(P3.2)和 INT1(P3.3),当引脚电平发生变化时,可立即暂停当前程序,执行中断服务程序,处理完后再返回原任务。
本章目标:
- 理解中断的基本概念与工作流程;
- 掌握51单片机外部中断的触发方式;
- 配置INT0和INT1为下降沿或低电平触发;
- 实现按键通过中断控制LED或电机;
- 为后续学习实时系统、事件驱动编程打下基础。
2. 硬件设计
2.1 中断引脚
中断源 | 对应引脚 | 特殊功能 |
---|---|---|
INT0 | P3.2 | 外部中断0 |
INT1 | P3.3 | 外部中断1 |
2.2 典型电路(以INT0为例)
- 按键K1一端接地;
- 另一端接P3.2(INT0);
- P3.2内部有上拉电阻,可省略外部上拉;
- 按下按键时,P3.2变为低电平,触发中断。
建议添加100nF电容接地,进行硬件消抖(虽软件仍需处理)。
3. 软件设计
3.1 中断相关寄存器
51单片机通过以下寄存器控制中断:
寄存器 | 位 | 说明 |
---|---|---|
TCON | IT0(TCON.0) | INT0触发方式:0=低电平触发,1=下降沿触发 |
IE0(TCON.1) | INT0中断标志,自动置1,中断响应后自动清零 | |
IT1(TCON.2) | INT1触发方式 | |
IE1(TCON.3) | INT1中断标志 | |
IE | EX0(IE.0) | 允许INT0中断 |
EX1(IE.1) | 允许INT1中断 | |
EA(IE.7) | 总中断使能 |
3.2 中断初始化函数
#include <reg52.h>sbit LED = P1^0;void exti0_init() {IT0 = 1; // 下降沿触发(推荐,避免重复触发)EX0 = 1; // 使能INT0中断EA = 1; // 开启总中断
}// 外部中断0服务程序
void int0_isr() interrupt 0 {LED = ~LED; // 每次中断翻转LED
}
interrupt 0
表示这是外部中断0的中断服务函数(INT0的中断号为0)。
3.3 完整示例:按键中断控制LED
#include <reg52.h>sbit LED = P1^0;void delay_ms(unsigned int ms) {unsigned int i, j;for (i = 0; i < ms; i++)for (j = 0; j < 125; j++);
}void exti0_init() {IT0 = 1; // 下降沿触发EX0 = 1; // 使能INT0EA = 1; // 全局中断开启
}void main() {LED = 0; // 初始LED亮exti0_init();while(1) {// 主程序可执行其他任务// 如:电机控制、显示刷新等}
}// 外部中断0服务函数
void int0_isr() interrupt 0 {delay_ms(10); // 软件消抖if (P3 & 0x04) == 0) { // 再次确认P3.2为低(按键按下)LED = ~LED;}// IE0由硬件自动清零
}
3.4 外部中断1(INT1)示例
void exti1_init() {IT1 = 1; // 下降沿触发EX1 = 1; // 使能INT1EA = 1;
}void main() {exti1_init();while(1);
}// 外部中断1服务函数
void int1_isr() interrupt 2 {// INT1的中断号为2P1 = 0x00; // 触发后关闭所有输出(如紧急停止)
}
3.5 中断触发方式对比
触发方式 | 配置 | 特点 |
---|---|---|
低电平触发 | IT0=0 | 只要为低就触发,可能重复触发 |
下降沿触发 | IT0=1 | 仅在高→低跳变时触发一次,推荐使用 |
推荐使用下降沿触发,配合软件消抖,避免误触发。
3.6 应用:紧急停止电机
假设电机正在运行,通过INT1实现紧急停止:
sbit IN1 = P2^0;
sbit IN2 = P2^1;
sbit ENA = P2^2;void motor_stop() {IN1 = 0; IN2 = 0; ENA = 1;
}void exti1_init() {IT1 = 1;EX1 = 1;EA = 1;
}void main() {// 启动电机正转IN1 = 1; IN2 = 0; ENA = 1;exti1_init();while(1);
}void int1_isr() interrupt 2 {motor_stop(); // 紧急停止
}
按键接P3.3,按下后立即停止电机,响应速度快。
3.7 编译与下载
- Keil中创建工程;
- 确保按键接P3.2或P3.3;
- 编译生成HEX;
- 下载至单片机;
- 按下按键,观察是否立即响应。
若中断不触发:
- 检查
EA
、EX0
/EX1
是否开启;- 确认
IT0
/IT1
设置正确;- 检查按键是否接地,引脚是否为低电平。
4. 小结
本章通过引入外部中断,掌握了事件驱动编程的核心技术,主要内容包括:
- 中断机制:理解中断的触发、响应与返回过程;
- 寄存器配置:掌握TCON、IE等关键寄存器的设置;
- 软件实现:编写中断服务程序,实现快速响应;
- 应用场景:用于按键检测、紧急停止、实时控制;
- 系统优化:解放主程序,提高响应速度与系统稳定性。
4.1 常见问题与解决
问题 | 原因 | 解决方法 |
---|---|---|
中断不响应 | EA未开启或EX0=0 | 检查中断使能设置 |
多次触发 | 未消抖或使用低电平触发 | 改为下降沿触发 + 软件消抖 |
程序跑飞 | 中断函数中使用长延时或递归 | 中断函数应短小精悍 |
标志未清 | 一般由硬件自动清零 | 不建议手动清除IE0/IE1 |
4.2 下一步学习建议
- 结合定时器中断实现多任务系统;
- 使用外部中断实现计数功能(如转速测量);
- 引入中断优先级(IP寄存器)管理多个中断;
- 应用于工业控制、智能报警等实时系统。
本章标志着你已掌握实时响应能力,下一章将进入定时器/计数器的深入学习,实现精准延时与周期性任务调度。