详解中断程序的编写方法
在应用中断技术时,先要根据中断需实现的功能设计好电路,然后编写中断程序。下面首先分析一个中断程序,再总结出编写中断程序的一般规律。
从实例了解中断程序的编写图5-2所示是一个已设计好的单片机电路,在这个电路中需要实现这样的中断控制:当按下按键S1时,单片机的外部中断INT0端(与P3.2引脚共用)输入中断请求信号,该信号进入内部中断系统,让CPU产生中断来执行中断子程序,程序运行的结果是让单片机的P1.2引脚输出低电平,发光二极管VD1发光。
图5-2 一个单片机应用电路
实现上述控制功能的程序如下:
程序执行过程说明如下。
① 程序从第2行指令开始执行(因为第1行是伪指令,不执行),执行第2行指令的结果是跳到第6行。
② 第6行~第11行指令用于进行中断前的设置。具体包括:在单片机内部存储器中设置一个区域当作堆栈(堆栈的栈底地址设为5FH);将I/O接口设置到初始状态;设置中断输入有效方式(下降沿有效),并开启总中断和外部中断0。
③ 第12行指令“LJMP $”是一条死循环指令。这条指令执行的结果就是再执行它,程序一直执行这条指令,无法执行下一条指令,就像是原地踏步。
④ 一旦按下按键S1,单片机的INT0端(P3.2)马上由高电平变为低电平,相当于该端输入一个下降沿信号,该信号使单片机内部的中断系统发生中断,由于外部中断0的中断入口地址为0003H,程序马上由“LJMP $”指令处跳到第4行指令“LJMP INT_0”处,第4行指令执行的结果是跳到标号“INT_0”处。
⑤ 从标号“INT_0”到指令“RETI”的这一段程序为中断子程序。为了避免执行中断子程序时破坏累加器ACC和寄存器PSW中的数据,先用“PUSH”指令将ACC、PSW中的数据送到先前设置好的堆栈中保存下来(保护现场),然后执行子程序中的关键部分“CPL P1.2”,执行完后,再用“POP”指令依次将堆栈中的数据送回到PSW、ACC中(恢复现场)。要注意的是,先保存到堆栈中的数据要后取出(先存后取),由于ACC中的数据先存入堆栈,所以要后取出,如果不按“先存后取”的顺序,就会造成数据恢复错误(如会将堆栈中ACC的数据送到PSW中)。
⑥ “ RETI”指令是一条中断子程序返回指令,该条指令执行的结果是返回到中断前的指令,这里是返回到指令“LJMP $”处,让程序又“原地踏步”,直到INT0端再输入中断请求信号。
中断程序的编写方法中断程序的编写包括主程序的编写和中断子程序的编写。
1.编写主程序
主程序的一般编写过程如下。
① 设置中断源和中断触发方式。根据需要确定中断的性质,通过设置定时器/计数器控制寄存器TCON或串行通信口控制寄存器SCON相应位的值来选择是外部中断,还是定时器/计数器中断等;设置中断触发方式是低电平触发,还是下降沿触发。
② 设置中断优先顺序。根据中断紧急程度(当有多个中断源时)确定中断源的优先顺序,以此来设置中断优先级控制寄存器IP中相应位的值。
③ 打开中断。通过在中断允许寄存器IE中设置相应的值,打开各个中断。
2.编写中断子程序
中断子程序的编写过程如下。
① 关中断。进入中断后,一般先要将中断关闭,再进行现场保护,如在前面的实例中,可在“PUSH ACC”指令前加一条“CLR EA”指令,就能将总中断关闭。
② 保护现场。为了防止执行中断子程序的过程中改变ACC和PSW中的数据,要用“PUSH ”指令将ACC和PSW中的数据送入堆栈中保护起来。
③ 开启中断。现场保护好后,再开启中断,如在前面实例的“PUSH PSW”指令后加一条“SETB EA”指令,就能将总中断打开。
④ 执行中断服务。中断服务程序是中断子程序中的核心,前面实例中的“CPL P1.2”指令就是中断服务程序。
⑤ 关闭中断。中断服务程序执行后又要关闭中断,以恢复现场,如在前面的实例中,可在“CPL P1.2”指令后加一条“CLR EA”指令,就能将总中断关闭。
⑥ 恢复现场。恢复现场的方法是用“POP”指令将堆栈中的数据送还给ACC和PSW。
⑦ 退出中断子程序,返回主程序。在中断子程序的最后用“RETI”指令可以退出中断子程序,返回主程序。