目录
0案例视频效果展示
0.1例子1:INT0控制LED闪烁
0.2例子2:INT0中断控制数码管计数
0.3例子3:INT0中断实现秒表功能
0.4例子4:INT0INT1中断控制数码管计数
1基础知识补充——中断系统
1.1 中断源一览
1.2 控制寄存器
1.3 优先级与嵌套规则
1.4 外部中断细节
1.5定时器中断
1.6串行口中断
1.7 中断响应流程(精简记忆版)
1.8 使用技巧
2例子1: INT0控制LED闪烁
2.1电路原理图
2.1.1电路组成及接线
2.2控制程序
2.2.1控制程序步骤
2.2.3源代码
3例子2:INT0中断控制数码管计数
3.1电路原理图
3.1.1电路组成及接线
3.2控制程序
3.2.1控制程序步骤
3.2.3源代码
4例子3:INT0中断实现秒表功能
4.1电路原理图
4.1.1电路组成及接线
4.2控制程序
4.2.1控制程序步骤
4.2.3源代码
5例子4:INT0INT1中断控制数码管计数
5.1电路原理图
5.1.1电路组成及接线
5.2控制程序
5.2.1控制程序步骤
5.2.3源代码
6 硬件工程师笔试面试相关文章链接(部分链接)
摘要:本文介绍了基于51单片机外部中断(INT0/INT1)的四个实践案例:1)INT0控制LED开关;2)INT0中断实现数码管计数/清零;3)INT0中断构建秒表功能(启动/暂停/清零);4)INT0/INT1双中断独立控制两组数码管计数。每个案例包含电路原理图、接线说明及完整源代码,重点演示了外部中断在硬件控制中的应用方法。附加硬件工程师笔试面试资料链接,涵盖器件知识、Multisim教程等内容,适合嵌入式学习者参考实践。
0案例视频效果展示
0.1例子1:INT0控制LED闪烁
例子25:INT0控制LED闪烁
0.2例子2:INT0中断控制数码管计数
例子26:INT0中断控制数码管计数
0.3例子3:INT0中断实现秒表功能
例子27:INT0中断实现秒表功能
0.4例子4:INT0INT1中断控制数码管计数
例子28:INT0INT1中断控制数码管计数
1基础知识补充——中断系统
AT89C52的中断系统=“6 组固定中断向量 + 1 组共用中断向量 + 2 级优先级管理”
1.1 中断源一览
编号 | 向量地址 | 标志位 | 源/功能 | 触发方式 |
0 | 0003H | IE0 | 外部中断 0 (INT0) | 低电平 / 下降沿 |
1 | 000BH | TF0 | 定时器 0 溢出 | 内部计数溢出 |
2 | 0013H | IE1 | 外部中断 1 (INT1) | 低电平 / 下降沿 |
3 | 001BH | TF1 | 定时器 1 溢出 | 内部计数溢出 |
4 | 0023H | RI/TI | 串行口 (UART) | 收完/发完 1 字节 |
5 | 002BH | TF2+EXF2 | 定时器 2 | 溢出或捕获/重载 |
共 8 个“物理”中断源,但向量只有 6 个(T2 两个标志共用 002BH)。
1.2 控制寄存器
1. IE(A8H)——总中断允许
EA ES ET2 ES ET1 EX1 ET0 EX0
1 = 允许;0 = 屏蔽
2. IP(B8H)——优先级(1 = 高优先级,0 = 低优先级)
— — PT2 PS PT1 PX1 PT0 PX0
8052 新增 PT2,其余位含义同 8051。
3. T2CON(C8H)——T2 专用
TF2、EXF2 由软件清 0。
1.3 优先级与嵌套规则
两级:高优先级可打断低优先级,同级不嵌套。
同优先级内部再按自然序号 0→5 排队。
1.4 外部中断细节
IT0/IT1(TCON.0/TCON.2)
0 = 低电平触发(需手动撤除低电平才能再次触发)
1 = 下降沿触发(自动锁存,脉冲宽度 ≥ 1 机器周期即可)
1.5定时器中断
TF0/TF1 在计数器溢出时置 1,CPU 响应后硬件自动清 0。
TF2/EXF2 共用向量,中断服务程序需判断是溢出还是捕获/重载,再分别清 0。
1.6串行口中断
RI 和 TI 共用向量,进入服务程序后先读 SCON 判定是“接收完”还是“发送完”,再清相应标志。
1.7 中断响应流程(精简记忆版)
1. 标志置位 → 2. 总中断 EA=1 且对应位允许 → 3. 优先级仲裁 → 4. 完成当前指令 → 5. 自动把 PC 压栈 → 6. 装入向量地址 → 7. 执行 ISR → 8. RETI 返回。
1.8 使用技巧
下降沿触发外部中断时,ITn=1 可避免“电平保持”误触发。
高优先级 ISR 里可再被更高优先级打断,但同级或低优先级不能打断。
T2 的 TF2/EXF2 必须软件清 0,否则会不停地进入中断。
2例子1: INT0控制LED闪烁
实现功能:(外部INT0中断控制LED):每次按键都会触发INT0中断,中断发生时将LED状态取反,产生LED状态由按键控制的效果
本质:按键每次触发INT0中断,中断服务程序将LED电平取反,实现按键控制LED开关。
2.1电路原理图
2.1.1电路组成及接线
名称 | 接线 |
AT89C51单片机 | XTAL1/XTAL2—>连接晶振电路 RST—>连接复位电路 P0.0—>LED灯 P3.2—>按键开关 |
复位电路 | |
晶振电路 | |
LED灯 | |
按键开关 |
2.2控制程序
2.2.1控制程序步骤
库文件和引脚定义
主程序(LED闪烁)
INT0中断函数
2.2.3源代码
//(外部INT0中断控制LED):每次按键都会触发INT0中断,中断发生时将LED状态取反,产生LED状态由按键控制的效果#include<reg51.h>#define uchar unsigned char#define uint unsigned intsbit LED=P0^0;//主程序void main(){LED=1;EA=1;EX0=1;IT0=1;while(1);}//INT0中断函数void EX_INT0() interrupt 0{LED=~LED; //控制LED亮灭}
3例子2:INT0中断控制数码管计数
实现功能:每次按下计数键时触发INT0中断,中断程序累加计数, 计数值显示在3只数码管上,按下清零键时数码管清零
本质:按键触发INT0中断即计数并刷新数码管,清零键直接归零。
3.1电路原理图
3.1.1电路组成及接线
名称 | 接线 |
AT89C51单片机 | XTAL1/XTAL2—>连接晶振电路 RST—>连接复位电路 P0.0-P0.7—>计数数码管 P1.0-P1.7—>计数数码管 P2.0-P2.7—>计数数码管 P3.2/P3.6—>按键开关 |
复位电路 | |
晶振电路 | |
计数数码管 | |
按键开关 | |
排阻 |
3.2控制程序
3.2.1控制程序步骤
库文件
段码
分解显示数位
示数
主程序(数值显示)
INT0中断函数
3.2.3源代码
//计数:每次按下计数键时触发INT0中断,中断程序累加计数, 计数值显示在3只数码管上,按下清零键时数码管清零#include<reg51.h>#define uchar unsigned char#define uint unsigned int//0~9的段码uchar code DSY_CODE[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x00};//计数值分解后各个待显示的数位uchar DSY_Buffer[]={0,0,0};uchar Count=0;sbit Clear_Key=P3^6;//数码管上显示计数值void Show_Count_ON_DSY(){DSY_Buffer[2]=Count/100; //获取3个数DSY_Buffer[1]=Count%100/10;DSY_Buffer[0]=Count%10;if(DSY_Buffer[2]==0) //高位为0时不显示{DSY_Buffer[2]=0x0a;if(DSY_Buffer[1]==0) //高位为0,若第二位为0同样不显示DSY_Buffer[1]=0x0a;}P0=DSY_CODE[DSY_Buffer[0]];P1=DSY_CODE[DSY_Buffer[1]];P2=DSY_CODE[DSY_Buffer[2]];}//主程序void main(){P0=0x00;P1=0x00;P2=0x00;IE=0x81; //允许INT0中断IT0=1; //下降沿触发while(1){if(Clear_Key==0) Count=0; //清0Show_Count_ON_DSY();}}//INT0中断函数void EX_INT0() interrupt 0{Count++; //计数值递增}
4例子3:INT0中断实现秒表功能
实现功能:能够实现秒表作用,首次按键计时开始,再次按键暂停,第三次按键清零。
本质:按键循环控制:首次启动计,再次暂停,第三次清零,实现秒表功能。
4.1电路原理图
4.1.1电路组成及接线
名称 | 接线 |
AT89C51单片机 | XTAL1/XTAL2—>连接晶振电路 RST—>连接复位电路 P0.0-P0.7—>计数数码管/排阻 P1.0-P1.7—>计数数码管 P3.7—>按键开关 |
复位电路 | |
晶振电路 | |
两个数码管 | |
按键开关 | |
排阻 |
4.2控制程序
4.2.1控制程序步骤
库文件和引脚定义
段码
延时函数
按键处理函数
主程序(数值显示)
INT0中断函数
4.2.3源代码
//功能:首次按键计时开始,再次按键暂停,第三次按键清零。#include<reg51.h>#define uchar unsigned char#define uint unsigned intsbit K1=P3^7;uchar i,Second_Counts,Key_Flag_Idx;bit Key_State;uchar DSY_CODE[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};//延时void DelayMS(uint ms){uchar t;while(ms--) for(t=0;t<120;t++);}//处理按键事件void Key_Event_Handle(){if(Key_State==0){Key_Flag_Idx=(Key_Flag_Idx+1)%3;switch(Key_Flag_Idx){case 1: EA=1;ET0=1;TR0=1;break;case 2: EA=0;ET0=0;TR0=0;break;case 0: P0=0x3f;P2=0x3f;i=0;Second_Counts=0;}}}//主程序void main(){P0=0x3f; //显示00P2=0x3f;i=0;Second_Counts=0; Key_Flag_Idx=0; //按键次数(取值0,1,2,3)Key_State=1; //按键状态TMOD=0x01; //定时器0方式1TH0=(65536-50000)/256; //定时器0:15msTL0=(65536-50000)%256;while(1){if(Key_State!=K1){DelayMS(10);Key_State=K1;Key_Event_Handle();}}}//INT0中断函数void DSY_Refresh() interrupt 1{TH0=(65536-50000)/256; //恢复定时器0初值TL0=(65536-50000)%256;if(++i==2) //50ms*2=0.1s转换状态{i=0;Second_Counts++;P0=DSY_CODE[Second_Counts/10];P2=DSY_CODE[Second_Counts%10];if(Second_Counts==100) Second_Counts=0; //满100(10s)后显示00}}
5例子4:INT0INT1中断控制数码管计数
实现功能:每次按下第1个计数键时,第1组计数值累加并显示在右边3只数码管上, 每次按下第2个计数键时,第2组计数值累加并显示在左边3只数码管上,后两个按键分别清零。
本质:左右各三管,分别由两键独立计数与清零,互不干扰。
5.1电路原理图
5.1.1电路组成及接线
名称 | 接线 |
AT89C51单片机 | XTAL1/XTAL2—>连接晶振电路 RST—>连接复位电路 P2.0-P1.3—>6位数码管 P3.2-P3.5—>按键 |
复位电路 | |
晶振电路 | |
6位数码管 | |
按键 |
5.2控制程序
5.2.1控制程序步骤
库文件和引脚定义
数码管段码和位码定义
数据显示函数
主程序(数值显示)
INT0中断函数
INT1中断函数
5.2.3源代码
//功能:每次按下第1个计数键时,第1组计数值累加并显示在右边3只数码管上,每次按下第2个计数键时,第2组计数值累加并显示在左边3只数码管上,后两个按键分别清零。#include<reg51.h>#define uchar unsigned char#define uint unsigned intsbit K3=P3^4; //2个清零键sbit K4=P3^5;//数码管段码与位码uchar code DSY_CODE[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0xff};uchar code DSY_Scan_Bits[]={0x20,0x10,0x08,0x04,0x02,0x01};//2组计数的显示缓冲,前3位一组,后3位一组uchar data Buffer_Counts[]={0,0,0,0,0,0};uint Count_A,Count_B=0;//延时void DelayMS(uint x){uchar t;while(x--) for(t=0;t<120;t++);}//数据显示void Show_Counts(){uchar i;Buffer_Counts[2]=Count_A/100;Buffer_Counts[1]=Count_A%100/10;Buffer_Counts[0]=Count_A%10;if( Buffer_Counts[2]==0){Buffer_Counts[2]=0x0a;if( Buffer_Counts[1]==0)Buffer_Counts[1]=0x0a;}Buffer_Counts[5]=Count_B/100;Buffer_Counts[4]=Count_B%100/10;Buffer_Counts[3]=Count_B%10;if( Buffer_Counts[5]==0){Buffer_Counts[5]=0x0a;if( Buffer_Counts[4]==0)Buffer_Counts[4]=0x0a;}for(i=0;i<6;i++){P2=DSY_Scan_Bits[i];P1=DSY_CODE[Buffer_Counts[i]];DelayMS(1);}}//主程序void main(){IE=0x85;PX0=1; //中断优先IT0=1;IT1=1;while(1){if(K3==0) Count_A=0;if(K4==0) Count_B=0;Show_Counts();}}//INT0中断函数void EX_INT0() interrupt 0{Count_A++; }//INT1中断函数void EX_INT1() interrupt 2{Count_B++; }
6 硬件工程师笔试面试相关文章链接(部分链接)
更多文章可前往主页观看
1、硬件工程师笔面试真题汇总(2025版本)_硬件工程师面试题-CSDN博客https://blog.csdn.net/XU157303764/article/details/140742900?spm=1011.2415.3001.5331硬件工程师笔试面试高频考点汇总——(2025版)_电容或者电感对锁存器的影响-CSDN博客
https://blog.csdn.net/XU157303764/article/details/1488349782、硬件工程师笔试面试汇总(2025版本)_硬件工程师面试题-CSDN博客
https://blog.csdn.net/XU157303764/article/details/1419048583、硬件工程师笔试面试学习汇总——器件篇目录(2025版本)_【【硬件工程师炼成之路】器件篇(更新中。。。)-CSDN博客
https://blog.csdn.net/XU157303764/article/details/142316204
硬件工程师笔记——电子器件汇总大全-CSDN博客https://blog.csdn.net/XU157303764/article/details/147342935?spm=1011.2415.3001.5331Multisim14使用教程详尽版--(2025最新版)-CSDN博客
https://blog.csdn.net/XU157303764/article/details/147197406?spm=1011.2415.3001.5331