51串口中断不论是单片机发送数据到电脑(发送),还是电脑发数据至单片机都会进入串口中断(接收)。单片机接收数据,因为不知道什么时候接收数据所以用中断接收。在配置初始化的时候要开中断。发送数据因为是单片机发,所以不需要中断进行处理,如果需要进入中断,就可以把中断打开。打开中断在发送数据的时候就会进入中断。
刚学习串口的时候也没有过多思考中断的事情,在看江科大的视频的时候,他写了如下这样的代码
他在接收一个数据以后又把数据发送回了电脑。当时产生了这样的疑问:既然开了中断,为什么中断里面发送数据没有进入中断呢?不是说发送和接收数据都会进入中断吗?
后来写了这样的代码尝试:
unsigned char count = 0;
void UART_Routine() intrrrupt 4
{
count++;
if(RI == 1)
{
RI = 0;
UART_SendByte(SBUF);
P2 = SBUF;
Delay(1000);
}
P2 = count;
Delay(1000);
}
如果可以多次进入中断那么count应该会变为2,但是P2只亮了count等于1时的灯。说明没有重复进入中断,最开始还猜测了,会不会打断当前中断,所以吧P2 = SBUF放在了发送数据后面。但是事实证明并不会。其实最准确的解释是同级中断不会被同级中断打断。
那到底是为什么呢,百思不得其解,后来又尝试接收数据会不会多次进中断呢,于是写了下面的代码:
void UART_Routine() intrrrupt 4
{
if(RI == 1)
{
RI = 0;
UART_SendByte(0x55);
P2 = SBUF;
Delay(1000);
}
UART_SendByte(0x55);
Delay(1000);
}
因为有Delay(1000)
延时1S,所以可以短时间内多次发送数据。于是在STC上我连续点了多次发送数据
最开始只点了两次发现会发两次,以为可以多次进中断
但是当我发送多次数据后。
发送多次数据仍然只返回两次,这是为什么呢,按照上面的理解,应该进多次中断啊。
后来观察串口收发数据这张图,TI和RI是促发中断的条件,原来这才是关键,忽然想起来,上面的代码改过,最开始就是江科大的代码,RI=0在发送数据后面,我把他放在了最前面,那放在后面呢?
在这里插入代码片void UART_Routine() intrrrupt 4
{
if(RI == 1)
{
UART_SendByte(0x55);
P2 = SBUF;
Delay(1000);
RI = 0;
}
UART_SendByte(0x55);
Delay(1000);
}
如果这样在Delay之前多点几次还会进两次中断吗
事实证明不会。这样就忽然清晰了。
于是就得出结论,原来我理解的是错的,原来以为,发一次或者接收一次数据就会进一次中断,进中断的次数和收发次数相等,其实不然。
事实是:进不进中断只和RI或者TI是否等于1有关其中一位为1就会进入中断,这也就解释了为什么之前没有多次进入中断了,因为同级中断不会打断,在执行完此次中断TI就已经被置为0。所以出去之后就没有再次进入。
发送多次只进了两次中断,是因为中断前面执行的很快,我们只是在RI=0后把RI置为了1,我们按多少次,RI就还是1,在下一次中断RI被置为0,出来第二次中断自然就不会再次进入。