标准8051为用户提供了两个外部中断请求输入端INT0和INT1,实际的应用系统中,两个外部中断请求源往往不够用,需对外部中断源进行扩充。本文主要介绍如何利用定时器/计数器和串行输入口扩充外部中断源的方法。
标准8051有两个定时器/计数器,当它们选择为计数器工作模式,T0/T1引脚上发生负跳变时,T0/T1计数器加1,利用这个特性(向上计数),可以把T0/T1引脚作为外部中断请求输入引脚,而定时器/计数器的溢出中断TF0/TF1作为外部中断请求标志。在实际应用中,定时器/计数器一般设置为方式2(8位常数自动重新装载)外部计数工作模式,当然也可以工作于其它方式。方式2的实现见下面例子。
void Counter_initial()
{
TMOD = 0x66; //设置T0、T1工作方式为2
TH0 = 0xff; //T0计数器初值
TL0 = 0xff;
TH1 = 0xff; // T1计数器初值
TL1 = 0xff;
TR0 = 1; //启动T0,开始计数
TR1 = 1; //启动T1,开始计数
ET0 = 1; //允许T0中断
ET1 = 1; //允许T1中断
EA = 1; //CPU开中断
}
void CNT0_ISR () interrupt 1 using 0
{
……
}
void CNT1_ISR () interrupt 3 using 1
{
……
}
当连接于T0/T1引脚的外部中断请求输入线上的电平发生负跳变时,TL0/TL1加1,产生溢出,置1TF0/TF1,向CPU发出中断请求,同时TH0/TH1的内容0xff送入TL0/TL1,即TL0/TL1恢复初值0xff。这样,T0/T1引脚相当于负跳沿触发的外部中断请求源输入端。
标准8051有一个功能强大的全双工的异步通信串行口,既可以用于串行数据通信,也可以用于扩展并行I/O口。当其用于串行数据接收时,串行输入口RXD每接收完1Byte的数据,都可发出中断请求,而且RXD引脚从1到0的负跳变,是1帧信息的起始位。利用这个特性,可以将RXD引脚作为外部中断请求输入引脚。
串行口的工作方式有4种,方式0用于扩展并行I/O口,而且数据的接收没有起始位,所以方式0不能用于外部中断源的扩展。方式1、2、3都用于串行数据通信,方式1、3的波特率由定时器T1控制,而方式2的波特率固定为fosc/64或fosc/32,考虑到定时器T1有可能已经用于外部中断源扩展,所以这里主要介绍方式2。
void UART_initial()
{
SCON = 0x90; //设置UART工作方式为2,允许串行口接收数据,SM2=0,RI=0
ES = 1; //允许串行口中断
EA = 1; //CPU开中断
}
void UART_ISR () interrupt 4 using 0
{
RI = 0; //RI必须由软件清0
……
}
当连接于RXD引脚输入线上的电平发生负跳变时,RXD开始接收数据。当接收完第9位数据,并且满足RI=0和SM2=0这两个条件,接收到的数据送入接收缓冲器SBUF,第9位送入RB8,并置1RI,向CPU发出中断请求。这样,RXD引脚相当于负跳沿触发的外部中断请求源输入端。