传统的8位51单片机,程序地址控件是从0x0000到0xFFFF。根据51单片机的特点,上电的时候,内部程序地址计数器从0x0000开始执行程序。因为程序被编译成机器码后,一般是存储在0x0000开始的地方,按照顺序存入EPROM或者其他类型的ROM中。
当你的处理中包含了中断处理的时候,根据所用的中断类型,系统有默认的约定,规定哪个中断从哪个地址开始进入处理。因此中断处理程序的起始地址,不是由我们能自行决定的。
8051单片机中有以下几个中断,按照存储地址的顺序罗列如下:
简称 | 说明 | 触发条件 | 处理地址 |
INT0 | 外部中断0,低电平触发,通过P3.2引脚引入 | P3.2引脚为低电平 | 0x0003 |
T0 | 定时器、计数器0溢出中断 | 数值溢出 | 0x000B |
INT1 | 外部中断1,低电平触发,通过P3.3引脚引入 | P3.3引脚为低电平 | 0x0013 |
T1 | 定时器、计数器1溢出中断 | 数值溢出 | 0x001B |
TX/RX | 串口中断 | 串口收发数据 | 0x0023 |
因此在有中断处理时,我们会在主程序中加入如下语句:
ORG 0000H
LJMP Main ; 转到主程序入口
ORG 0003H
LJMP Proc_Int0 ;转到外部中断0的中断处理程序入口
ORG 000BH
LJMP Proc_T0 ;转到定时器/计数器0的中断处理程序入口
ORG 0013H
LJMP Proc_Int1 ;转到外部中断1的中断处理程序入口
ORG 001BH
LJMP Proc_T1 ;转到定时器/计数器1的中断处理程序入口
ORG 0023H
LJMP Proc_Com ;转到串口的中断处理程序入口
ORG表示其后的处理程序是从什么地址开始。
我们在程序中,使用RET表示子程序处理结束,返回调用它的地方。但中断处理程序不能用RET,而是用RETI。
在中断处理程序中,要做保护现场和恢复现场的处理,避免在中断处理完成后,破坏了之前的处理现场,导致运行错误。这里说的现场,指的是程序运行中用到的寄存器的数据。另外中断处理程序中尽可能执行少量代码,避免中断嵌套太多出现问题。
中断处理中还要注意中断标志位及清除中断状态的处理,避免出现中断死循环。
如果你开发时用的不是汇编语言,而是使用其他语言,在编译器编译的时候,也会按照中断处理的规则,分配正确的中断地址,保证中断被正常执行。
51单片机的主程序中,一开始一定要分配堆栈用的地址。不分配的话,如果产生中断,或者产生子程序调用,会出现意想不到的错误。
51单片机是这样分配地址的,其它种类的单片机,在对中断处理分配地址上,大体也是这样处理的,每个中断都有固定的一个开始地址。