smalling6 发表于 2012-3-1 17:07:07

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 发表于 2012-3-1 19:38:03

回复【楼主位】smalling6
-----------------------------------------------------------------------

万能的神坛!我发完就找到了错误,谢谢大家。
页: [1]
查看完整版本: HELP:关于MC35I用循环队列接收串口数据出错的问题。