HELP:关于MC35I用循环队列接收串口数据出错的问题。
用AT89S52控制MC35I,读出并分析短信。AT89S52串口的数据先用循环队列接收,然后再一段一段取出来放到一个数组中处理,取出的数据有某一位出错,有时正常,有时不正常。测试过串口接收到的正常,问题在程序中有描述,应该就是队列、GetRet()函数;、GetCom()函数这三个中的某个有问题,麻烦各位高手看看,帮忙找找,小弟不胜感激!附程序:
lpQueue idata RecQueue; //用于接收串口数据的循环队列
uchar idata DelBuff; //多用,处理短信,发送串口字符串等
uchar istemp;
uchar iscnt=0;
boolRecFlag;
uchar echo=1;
extern uchar ManaNum[]; //管理员号码
extern ManaFlag; //管理员号码是否已设置标志
void SetNull(lpQueue *lp) //队置空
{
lp->head=0;
lp->reccnt=0;
}
uchar GetLenght(lpQueue *lp) //获取有效结点长度
{
return(lp->reccnt);
}
uchar GetHead(lpQueue *lp) //取头结点
{
return(lp->RecBuff);
}
bool InQueue(lpQueue *lp,uchar x) //数据入队
{
if(lp->reccnt<mrec) //队列未满
{
lp->RecBuff[(lp->head+lp->reccnt)%mrec]=x; //计算尾索引,且入队
lp->reccnt++; //有效结点数加1
return 1; //返回成功
}
else
return 0; //队列已满
} //返回失败
uchar OutQueue(lpQueue *lp) //数据出队
{
uchar temp;
if(lp->reccnt>0) //队列非空
{ //读出头结点值后头索引加1
temp=lp->RecBuff; //头索引求模
lp->head%=mrec; //有效结点数减1
lp->reccnt--; //返回头结点值
return temp;
}
else //队列为空
return 0; //返回失败
}
void uart_init(void)
{
TMOD=0x20;
TH1=0xfd;
TL1=0xfd;
TR1=1;
REN=1;
SM0=0;
SM1=1;
EA=1;
ES=1;
}
//---------------------------------------------------------
//函数名称:void send_string(void)
//函数功能:串口1发送一个字符串
//输入参数:
// str, 要发送的字符串
//返回参数:无
//---------------------------------------------------------
void SendStr(unsigned char *str)
{
while(*str)
{
SBUF=*str;
while(!TI);
TI=0;
str++;
}
}
void uart_ser() interrupt 4
{
if(RI)
{
RI=0;
istemp=SBUF;
RecFlag=InQueue(&RecQueue,istemp);
if(!RecFlag)
{
LED2=0;
}
/*
if(echo==1)
{
iscnt++;
if(iscnt==32)
{
iscnt=0;
lcd_pos(0,2);
}
lcd_wdat(istemp);
}
*/
}
}
uchar GetRet(void) //得到队列中 \r\nxxx\r\n或 xxx\r\n类型的字符串,放入DelBuff中
{
uchar i=0,count;
memset(DelBuff,0,sizeof(DelBuff));
do
{
while(GetLenght(&RecQueue)<2);//确认队列不为空
DelBuff=OutQueue(&RecQueue);
i++;
}
while(GetHead(&RecQueue) != '\r');
OutQueue(&RecQueue); //丢掉字符串后的\r\n
while(GetLenght(&RecQueue)<1);
OutQueue(&RecQueue);
return i;
}
uchar GetCom(void) //得到队列中 xxx, 类型的字符串,放入DelBuff中
{
uchar i=0,count;
memset(DelBuff,0,sizeof(DelBuff));
do
{
while(GetLenght(&RecQueue)<2);
DelBuff=OutQueue(&RecQueue);
i++;
}
while(GetHead(&RecQueue) != ',');
OutQueue(&RecQueue); //丢掉字符串后的逗号
return i;
}
/*
\r\n
+CMGR: "REC UNREAD","1252015288433643",,"11/11/27,13:47:35+32"\r\n
此处为PDU码\r\n
\r\n
OK\r\n
*/
uchar ReadSms(uchar num)
{
uchar result=0x00,i=0;
uchar shi,ge;
uchar *Psms;
memset(DelBuff,0,sizeof(DelBuff));
strcpy(DelBuff,"AT+CMGR=");
strcat(DelBuff,&num);
strcat(DelBuff,"\r\n");
SendStr(DelBuff);
GetCom();
//delay(2);//此处只能延时2,不然会出错。若不延时常接成12020,若用串口模拟,则差不多是随机的
/*
//shi=RecQueue.head/10;
//ge=RecQueue.head%10;
//lcd_wdat('0'+shi);
//lcd_wdat('0'+ge);
shi=RecQueue.reccnt/10;
ge=RecQueue.reccnt%10;
lcd_wdat('0'+shi);
lcd_wdat('0'+ge);
//执行delay(10)串口接收12个
//执行memset(DelBuff,0,sizeof(DelBuff));接收一个
*/
if(strstr(DelBuff,"+CMGR") != NULL)
{
result|=0x01;
if(strstr(DelBuff,"REC UNREAD") != NULL)
{
result|=0x02;
GetCom();//测得RecQueue.reccnt为3时,此函数接收必然出错,接成12020或其它,都是固定第三位出错
//lcd_puts(0,1,DelBuff);
if((Psms=strstr(DelBuff,"+86")) != NULL)
{
result|=0x04;
if(ManaFlag == 0)
{
Psms+=3;
i=0;
for(i=0;i<11;i++)
ManaNum=*Psms++;
}
else
{
if(strstr(DelBuff,ManaNum) != NULL)
{
result|=0x16;
GetRet();
GetRet();
return result=0xff;
}
else
return result;
}
}
else if((Psms=strstr(DelBuff,"12520")) != NULL)
{
LED1=0;
result|=0x08;
if(ManaFlag == 0)
{
Psms+=5;
i=0;
for(i=0;i<11;i++)
ManaNum=*Psms++;
}
else
{
if(strstr(DelBuff,ManaNum) != NULL)
{
LED1=0;
result|=0x16;
GetRet();
GetRet();
lcd_puts(0,2,DelBuff);
return result=0xef;
}
else
return result;
}
}
}
else
return result;
}
else
return result;
}
源文件ourdev_723357X4ZL0L.rar(文件大小:72K) (原文件名:新建文件夹.rar) 回复【楼主位】smalling6
-----------------------------------------------------------------------
万能的神坛!我发完就找到了错误,谢谢大家。
页:
[1]