#include "reg52.h"
#include "intrins.h"
#include "string.h"
#define SIZE 12
sfr AUXR = 0x8E;
sbit D5 = P3^7;
sbit D6 = P3^6;
char buffer[SIZE];
char LYMS[] = "AT+CWMODE=2\r\n";
char DLJ[] = "AT+CIPMUX=1\r\n";
char JLFW[] = "AT+CIPSERVER=1\r\n";
char FSSJ[] = "AT+CIPSEND=0,5\r\n";
char AT_OK_Flag = 0;
char Client_Connect_Flag = 0;
void Delay1000ms() //@11.0592MHz
{
unsigned char i, j, k;
_nop_();
i = 8;
j = 1;
k = 243;
do
{
do
{
while (--k);
} while (--j);
} while (--i);
}
void UartInit()
{
//相关寄存器的配置
AUXR = 0x01;
SCON = 0x50;
TMOD &= 0x0F;
TMOD |= 0x20;
TH1 = 0xFD;
TL1 = 0xFD;
TR1 = 1;
EA = 1;
ES = 1;
}
void sendByte(char data_msg)
{
SBUF = data_msg;
while(!TI);
TI = 0;
}
void sendString(char *data_msg)
{
while(*data_msg != '\0'){
sendByte(*data_msg);
data_msg++;
}
}
void main()
{
//每隔一秒发送一串字符
UartInit();
Delay1000ms();
sendString(LYMS);
Delay1000ms();
Delay1000ms();
Delay1000ms();
while(!AT_OK_Flag);
AT_OK_Flag = 0;
sendString(DLJ);
Delay1000ms();
Delay1000ms();
Delay1000ms();
while(!AT_OK_Flag);
AT_OK_Flag = 0;
sendString(JLFW);
Delay1000ms();
Delay1000ms();
Delay1000ms();
while(!Client_Connect_Flag);
AT_OK_Flag = 0;
if(Client_Connect_Flag){
D5 = 0;//点亮D5,代表有客户端接入
D6 = 0;
}
while(1){
//4 发送数据
sendString(FSSJ);
Delay1000ms();
Delay1000ms();
sendString("Hello");
Delay1000ms();
Delay1000ms();
}
}
void UART_Handler() interrupt 4
{
static int i;
char tmp;
if(RI){
RI = 0;
tmp = SBUF;
if(tmp == 'O' || tmp == '0' || tmp == ':'){
i = 0;
}
buffer[i++] = tmp;
if(buffer[0] == 'O' && buffer[1] == 'K'){
AT_OK_Flag = 1;
i = 0;
memset(buffer,'\0',SIZE);
}
if(buffer[0] == '0' && buffer[2] == 'C'){
Client_Connect_Flag = 1;
i = 0;
memset(buffer,'\0',SIZE);
}
if(buffer[0] == ':' && buffer[1] == 'o' && buffer[2] == 'p'){
D5 = 0;//点亮D5
i = 0;
memset(buffer, '\0', SIZE);
}
if(buffer[0] == ':' && buffer[1] == 'c' && buffer[2] == 'l'){
D5 = 1;//熄灭D5
i = 0;
memset(buffer, '\0', SIZE);
}
if(i == 12){
i = 0;
}
}
if(TI);
}
在做白盒测试时,功能完全正常。但是直接连接到单片机时就没用了,是为什么呢?
原因:在中断服务函数中的最后面部分,没有在当i = 12时,对i清零,让i回到初始的位置。
为什么做白盒测试的时候有用呢,是因为做白盒测试时,单片机接收到的只有OK和0,Connect这两种字串,而直接连接单片机时,接受到的字串不止这两种,在没有判断到OK和0,Connect这两种关键字时,索引i就不会清0,反而会一直递增,导致后面关键字符来了,单片机也找不到。
在这种特定的情况下,少了这段代码可能导致问题的原因如下:
-
缓冲区溢出问题:如果没有在中断服务函数中检查缓冲区索引
i
是否达到最大值,当接收到连续的字符时,i
会继续递增,直到超出缓冲区的大小。这可能导致数组越界,破坏其他重要的数据,或者导致程序的其他部分无法正常工作。 -
正确清除缓冲区:当缓冲区索引
i
达到最大值时,需要将其重置为0,以便缓冲区可以重新使用。如果不进行这样的重置,缓冲区可能会在达到其容量上限后无法继续接收数据,从而导致接收到的数据丢失或覆盖。
问:你的意思时i超出了缓冲区12的大小,就会导致缓冲区无法继续使用吗?
答:
是的,您理解得很正确。
在这种特定情况下,缓冲区大小被定义为 12,表示它最多可以容纳 12 个字符。如果 i
的值超过了缓冲区的大小,即 i
变为了 12,这意味着缓冲区已经填满了。此时如果没有将 i
重置为 0,那么当再次接收到新的字符时,将无法将其放入缓冲区中,因为 i
已经达到了其最大值,超出了缓冲区的范围。这样的话,新接收到的字符将会丢失或覆盖掉之前缓冲区中的数据,导致接收到的数据不完整或混乱。
因此,确保在缓冲区填满时重置 i
为 0 是十分必要的,这样可以确保缓冲区能够循环使用,而不会因为达到最大容量而导致数据丢失或错误。