按钮控制数码管显示(中断实现)

写一个程序,让按键S1按下后,数码管的数值加一。
#include <reg51.h>
#define uint unsigned int
#define uchar unsigned char
#define ds1 P0
#define ds2 P2
uint i;
seg1[]={0x11,0xd7,0x32,0x92,0xd4,0x98,0x18,0xd1,0x10,0x90};
seg2[]={0x88,0xeb,0x4c,0x49,0x2b,0x19,0x18,0x8b,0x08,0x09}; void main()
{EA=1; EX1=1; EX0=1; IT1=1; IT0=1; ds1=seg1[0]; ds2=seg2[0]; do{}while(1);
}
void KEY1() interrupt 0 using 2
{i++; if(i>99)i=0;ds1=seg1[i/10]; ds2=seg2[i%10];
} 中断方式实现时,要先打开总中断开关(EA=1)。
设置
EX1 = 1表示 允许外部中断1(INT1) 触发中断。设置
EX0 = 1表示 允许外部中断0(INT0) 触发中断。设置
IT1 = 1表示 INT1 为边沿触发(下降沿触发)。如果设为 0,则为 低电平触发。设置
IT0 = 1表示 INT0 为边沿触发(下降沿触发)。同样,设为 0 为低电平触发。
中断的本质就是当中断口被下降沿触发后进入中断函数。
中断函数:
void KEY1() interrupt 0 using 2
{i++; if(i>99)i=0;ds1=seg1[i/10]; ds2=seg2[i%10];
} KEY1()就是函数名
`interrupt` 后面的数字是 中断号,8051 标准核只定义了 0~4,完整列表如下:
| 中段号 | 向量地址 | 中断源(传统/增强) | 备注 |
| 0 | 0003H | 外部中断 0 (INT0) | 标准 |
| 1 | 000BH | 定时器 0 溢出 (TF0) | 标准 |
| 2 | 0013H | 外部中断 1 (INT1) | 标准 |
| 3 | 001BH | 定时器 1 溢出 (TF1) | 标准 |
| 4 | 0023H | 串口 0 (RI/TI) | 标准 |
| 5 | 002BH | 定时器 2 (TF2/EXF2) | 仅 52 系列 |
| 6~7 | 0033H~003BH | 保留 / 厂家扩展 | 部分 MCU 给 SPI、I²C 等 |
| 8~31 | 0043H~00FFH | 厂家继续扩展 | 如 ADC、PWM、USB、CAN… |
using后面只能写 0、1、2、3 这四个数,对应 8051 内部的 4 组工作寄存器区(每组 8 字节 R0~R7)。
using 0 → 第 0 区(地址 00H~07H)
using 1 → 第 1 区(地址 08H~0FH)
using 2 → 第 2 区(地址 10H~17H)
using 3 → 第 3 区(地址 18H~1FH)
超出 0~3 编译器直接报错。
using如何选择:
主程序不动,继续用默认 区 0。
每写一个中断服务函数,就给它分配 一个未被占用的区号(1→2→3 轮着用)。
若中断嵌套层数 ≤3,4 组足够;如果 MCU 支持更多优先级,再考虑 手工 PUSH/POP 或 软件堆栈。
