二、C51中断处理过程
在程序设计中,设置一个好的时钟中断,将能使一个CPU发挥两个CPU的功效,大大方便和简化程序的编制,提高系统的效率与可操作性。如把需要定时执行的程序放在时钟中断中,还可以利用时钟中断协助主程序完成定时、延时等操作,下面以AT89C51系统为例,说明时钟中断的应用。
1.定时器初值与中断周期
定时器每过一个机器周期,计数值自动加l,当计数满后,产生溢出中断,并由硬件设置相应的标志位供软件查询。以定时器TO的工作方式l、时钟6MHz、定时20ms为例,12个时钟周期为一个机器周期,20ms中有10000个机器周期,则65536-10000=55536=D8F0h。由于响应中断、保护现场及重装初值还需要7~8个机器周期,即TO应装入的初值是D8F7h。
设置一个或几个单元,每次中断加l,可以从中获得20ms的任意整数倍的定时时间。例如:有一段向数码管送显的程序,需要每0.5秒执行一次刷新,设一单元W_DISP初值为O,当W_DISP计数到25后,便执行送显程序。可以设置多个等待单元,以便取出多个不同的时基信号,执行相应的处理。
2.在中断中读键
程序读键盘步骤为:扫描键盘,若有键按下,则延时几十毫秒去抖动,再次确认此键确实按下,然后处理该键对应的工作。但这有两点不足:
1)处理相应工作时无法锁存按键的输入,即可能漏键。
2)延时去抖时,CPU无法做其他事情。若把读键放入时钟中断中,则可避免上述不足。方法为:如果在两次相邻的中断中都读到同一个键按下,则这个键是有效的,并将其锁存到先入先出的键盘缓冲区,等主程序来处理。这样,主程序在处理按键的同时,仍可响应键盘的输入。缓冲区深度通常可设为8级,若锁存的键数多于8个,则忽略新的按键,并报警提示用户新的按键无效。
3.主程序中的延时
由于有时钟中断,当主程序需要时间较短、精度较高的延时时,应暂时把时钟中断关闭,当程序中需要时间较长、精度不高的延时时,可仿照下面的写法,避免多层嵌套的循环延时。
中断服务函数的完整语法如下:
void函数名(void)[模式][再入]
interrupt n[using r]
其中,n(0~31)代表中断号。
C51编译器允许32个中断,具体使用哪个中断由80C51系列的芯片决定。r(0-3)代表第r组寄存器。在调用中断函数时,要求中断过程调用的函数所使用的寄存器组必须与其相同。“再入”
用于说明中断处理函数有无“再入”
能力。下面举一个简单的例子,让大家了解一下编C51中断程序的方法。
例:设单片机时钟12MHz,要求用TD的方式1编程,在P1.O脚输出周期为2ms的方波。
用C语言编写的中断服务程序如下:
#include<reg51.h>
sbit P1_0=P1^0;void timerO (void)interrupt 1 using 1{/*TO中断服务程序入口*/P1_0=!P1_0;THO=-(1000/256);/*计数初值重装*/TLO=(1000%256); }
void main(void) {TMOD=OxO1;/*TO工作在定时器方式l*/Pl_0=0;TH0=-(1000/256);/*预置计数初值*/TL0=-(1000%256);EA=1; /*CPU开中断*/ETO=1; /*TO开中断*/TR0=1; /*启动TO*/d0{}while(1);}
从上例可以看出,要灵活地应用时钟中断,应将任务合理分配给中断程序和主程序,并且二者要分工明确、接口简单。要注意:应尽量缩短中断处理程序的执行时间,不要长于20ms。