51单片机外部中断实战:数码管数字切换

📅 2026/6/30 22:00:34
51单片机外部中断实战:数码管数字切换
点灯学习—51单片机外部中断写文章巩固一下顺便学习Markdown使用STC59C52外部中断修改数码管数字外部中断的原理图为AT89C52中断系统结构*51单片机中断整体结构原理图*1INT0 外部中断interrupt 00中断请求由P3.2引脚输入当检测到中断信号中断标志位IE0TCON.0置1。2INT1 外部中断1interrupt 1中断请求由P3.3引脚输入当检测到中断信号中断标志位IE0TCON.3置1。3IT 外部中断方式控制位TCON.0,TCON.2当ITx 1时外部中断下降沿触发图中学习乱标记当ITx 0时为低电平触发*特殊功能寄存器TCON*4EXx 外部中断允许寄存器() 只有当中断被允许时EXx 1 才会触发中断*中断允许寄存器IE*(5)中断优先级51单片机中断的优先级*中断优先级查询次序*外部中断的编程实现理解了外部中断的原理后我们就可以开始编写代码了。下面以 STC89C52 单片机为例演示如何使用外部中断 0 (INT0) 来响应按键并控制一个 LED 灯的亮灭。1. 硬件连接使用51单片机开发板原理图如下*单片机开发板原理图*数码管通过连接74HC573与单片机连接独立按键3连接P3.22. 代码示例 (C语言)#includeREGX52.H#includeintrins.hsbit WELAP2^7;sbit DULAP2^6;unsignedcharstate0;voiddelay(unsignedi){intk0;intj0;for(k;ki;k){for(j;j110;j){_nop_();}}}/*-----------------数码管驱动-------------*/// 0~9数字段码unsignedcharseg_num[10]{0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F};// 常用字母 A,b,C,d,E,F,H,L,P,Uunsignedcharseg_char[10]{0x77,0x7C,0x39,0x5E,0x79,0x71,0x76,0x38,0x73,0x3E};voidsegment_num(unsignedintlocation,unsignedcharnum){unsignedchari0XFE;WELA0;DULA0;P0_crol_(i,location);WELA1;delay(1);WELA0;P0seg_num[num];DULA1;delay(2);DULA0;P00X00;DULA1;delay(1);DULA0;}voidsegment_char(unsignedintloc,unsignedcharch){unsignedchari0XFE;WELA0;DULA0;P0_crol_(i,loc);WELA1;delay(1);WELA0;P0seg_char[ch];DULA1;delay(2);DULA0;P00X00;DULA1;delay(1);DULA0;}voidchange_state()interrupt0{delay(20);if(P3_20){state!state;}}voidmain(){IT01;//下降沿触发EX01;//开启外部中断0EA1;//允许总中断while(1){if(state1){segment_num(0,1);segment_num(1,2);}elseif(state0){segment_char(0,0);segment_char(1,1);}}}3. 代码解析这段代码实现了一个简单的外部中断应用通过按键触发外部中断 0INT0对应 P3.2 引脚切换数码管显示内容——在数字 “1、2” 和字母 “A、b” 之间切换。1. 头文件与宏定义#includeREGX52.H#includeintrins.hREGX52.HSTC89C52 系列单片机的特殊功能寄存器定义头文件。intrins.h包含内部函数如_nop_()空操作和_crol_()循环左移。2. 引脚与变量定义sbit WELAP2^7;sbit DULAP2^6;WELA位选锁存器控制引脚连接 P2.7控制哪个数码管亮。DULA段选锁存器控制引脚连接 P2.6控制数码管显示什么内容。unsignedcharstate0;state显示状态标志位。0时显示字母 “A、b”1时显示数字 “1、2”。外部中断触发时会翻转该值。3. 延时函数delayvoiddelay(unsignedi){intk0;intj0;for(k;ki;k){for(j;j110;j){_nop_();}}}通过双重循环和_nop_()空操作实现粗略的毫秒级延时主要用于数码管动态扫描和按键消抖。4. 段码表定义unsignedcharseg_num[10]{0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F};unsignedcharseg_char[10]{0x77,0x7C,0x39,0x5E,0x79,0x71,0x76,0x38,0x73,0x3E};seg_num0~9 数字对应的共阴极数码管段码。seg_char常用字母A~U 中选出的 10 个段码程序中用索引 0 对应 ‘A’索引 1 对应 ‘b’。5. 数码管显示函数segment_num(unsigned int location, unsigned char num)在location位显示数字num。segment_char(unsigned int loc, unsigned char ch)在loc位显示字母段码seg_char[ch]。两个函数的操作流程一致关闭位选和段选WELA0; DULA0;。通过P0口送出位选信号_crol_()循环左移选择位置拉高WELA锁存。通过P0口送出段码数据拉高DULA锁存。短暂延时后清除段码并再次锁存消除残影。6. 外部中断 0 服务函数change_statevoidchange_state()interrupt0{delay(20);if(P3_20){state!state;}}interrupt 0外部中断 0 的中断号。消抖处理先延时约 20ms再检测P3.2是否仍为低电平过滤按键抖动。状态翻转确认按键按下后执行state !state实现显示内容的切换。7. 主函数mainvoidmain(){IT01;// 下降沿触发EX01;// 开启外部中断 0EA1;// 允许总中断while(1){if(state1){segment_num(0,1);segment_num(1,2);}elseif(state0){segment_char(0,0);segment_char(1,1);}}}中断初始化直接在main中设置——IT01下降沿触发、EX01开外部中断 0、EA1开总中断。主循环不断扫描显示。state 1第 0 位显示数字 “1”第 1 位显示数字 “2”。state 0第 0 位显示字母 “A”seg_char[0]第 1 位显示字母 “b”seg_char[1]。每次按下按键外部中断翻转state数码管显示就会在两组内容之间切换。总结这个程序用最精简的方式演示了 51 单片机外部中断的使用——按键触发中断、消抖确认、状态切换、数码管动态扫描显示非常适合初学者入门理解中断的触发与响应机制。4. 进阶思考消抖处理: 实际按键会产生机械抖动可能导致一次按下触发多次中断。可以在中断服务函数开头添加延时消抖或在主循环中采用软件定时器进行消抖判断。中断优先级: 如果系统中还有定时器中断等其他中断可以通过设置IP寄存器来调整它们的优先级。通过这个简单的例子你应该能够将原理图中的寄存器配置与实际代码对应起来并动手实现一个基本的外部中断应用。2026年6月29日第三次学习