关于串口发送数据

shen001   2008-8-28 17:41 楼主
  在中断中从串口调试器里发送出来的数据,接收下来再发送出来在串口调试器上接收的和先前发送的数据不同,不明白到底是什么原因影响了,我是新手,一直找不到原因之只好请各位高手帮忙看看
   

我从串口调试器发送AB2D02000084 这串数据
     
void com_UART(void) interrupt 4 using 1
{

unsigned char idata chek,c;

TOGGLE_WD();
if(RI)
{
c=SBUF;
RI=0;

oldstate=nowstate;
nowstate=0;

switch(oldstate)
{
case 0:
if(c==0xAB)
{
TIME_OUT=50;
chek=c;
nowstate=1;

break;
}
else
{
nowstate=0;


break;
}
case 1:
if(c<=0x2f&&c>=0x20)
{
TIME_OUT=50;
REBuffer[0]=c;
chek^=c;
nowstate=2;


}
else
{
nowstate=0;}

break;

case 2:
TIME_OUT=50;
REBuffer[1]=c;
chek^=c;
nowstate=3;
index=0;

break;
case 3:
TIME_OUT=50;
if(index {
REBuffer[2+index]=c;
chek^=c;
index++;
nowstate=3;
break;
}

if(c==chek)
{
CmdValid=1;
SBUF=REBuffer[0];   这里在串口调试器上可以看到正确返回了2D   
while(!TI);
TI=0;
}
else
{
SBUF=0xFF;
CmdValid=0;
while(!TI);
TI=0;

}
break;
default: break;
}
}
if(TI&&!RI)
{
TI=0;
chek=0;
index=0;
}

}
}

void main(void)
{
char idata status;

init();

init_serialcomm();

status = M500PcdConfig();

Idle_init(); //Initialize and prepare for Idle

while(1)

{ TOGGLE_WD();

if(CmdValid)
{
SBUF=REBuffer[0];  这里返回的就不是2D,而是B3了,不知道这个B3是哪里来的,为什么会无故跑出个其他数来?
CmdValid = FALSE;
cmdexecution();
Idle=FALSE;

else {
Tdelay_10ms(10);
}

}
请高手帮我看看吧!

回复评论 (7)

只能说你程序写的太混乱了, 自己先好好检查一下吧. 呵呵
点赞  2008-8-28 18:54
串口还是建议使用中断方式,查询标志位太浪费资源了,中断会更加简单
程序最好能缩进,要不然读起来太费力气,还没有注释
点赞  2008-8-28 23:40

不好意思,先前的程序没有缩进和注释看起来的确很费劲。现在加上缩进和注释,请高手帮帮忙看看吧!

串口中断服务函数,从串口调试器发送一串规定格式的数据,格式为开始位0XAB,命令字0X20-0X2F中的一个,数据的长度位,数据……,奇偶校验位,这里我从串口发送AB2D02000084,即命令字为2D,数据长为2,2个数据是分别是00,00,校验位为84,

void com_UART(void) interrupt 4 using 1
  {
   unsigned char idata chek,c;
   
   TOGGLE_WD();   喂狗信号
   if(RI)
     {
      c=SBUF;      如果从串口调试器上有数发出则把接收到的数存在C中
      RI=0;
     oldstate=nowstate;           
     nowstate=0;                设定状态,初始状态为0,即从开始位开始接收
     switch(oldstate)
       {
       case 0:
        if(c==0xAB)           如果接收到的数为AB
           {  
            TIME_OUT=50;           时间溢出,若很长时间还没有接收到数则返回到初始态
             chek=c;            存在校验位里以便运算
             nowstate=1;         进入下个状态,即接收命令字
               break;
             }
        else
            {
             nowstate=0;         不然就返回到初始状态继续等待接收AB
             break;
             }

      case 1:
        if(c <=0x2f&&c>=0x20)            如果命令字在这个范围内
          {  
            TIME_OUT=50;          将命令字存在REBuffer里,定义如下:
             REBuffer[0]=c;        static unsigned char xdata Buffer[24] ;         
             chek^=c;            开始位与命令字进行异或运算,算出其校验位
             nowstate=2;          进入第2状态,即接收数据长度
           }
         else
            {
              nowstate=0;         不在范围内则返回初始态
             }
         break;

       case 2:
         TIME_OUT=50;               
         REBuffer[1]=c;                  接收长度到REBuffer[1]
         chek^=c;                       计算其校验位
         nowstate=3;                     进入第3状态,即接收数据
         index=0;                        
         break;

      case 3:
        TIME_OUT=50;
        if (index < Buffer[1])              一个个接收REBuffer[1]个数据
         {
          REBuffer[2+index]=c;                  接收的数存入REBuffer中
          chek^=c;                  
          index++;                             计算其校验位
          nowstate=3;                            继续返回接收数据状态直到数据接收完
          break;
         }

       if(c==chek)                     接收完后,如果再接收到的数等于计算出来的校验位则置 CmdValid=1;
        {
         CmdValid=1;
         SBUF=REBuffer[0];          这里在串口调试器上可以看到发送的命令字,正确返回了2D  
          while(!TI);
           TI=0;
         }
        else
        {
          SBUF=0xFF;                校验不对则返回FF
          CmdValid=0;  
          while(!TI);
          TI=0;
        }
        break;
       default: break;
     }
  }
    if(TI&&!RI)
     {
      TI=0;
      chek=0;
      index=0;
     }

   }
}
主程序
void main(void)
  {
    char idata status;

    init();                   初始化一些变量

    init_serialcomm();           初始化串口

    status = M500PcdConfig();      

     Idle_init(); //Initialize and prepare for Idle     初始化无卡的状态

    while(1)

    {
     TOGGLE_WD();          喂狗信号

   if(CmdValid)          当串口调试器发送一串正确的数据后程序将进入这里
     {
      SBUF=REBuffer[0];  在这里返回命令字看是多少,这里返回的就不是2D,而是B3了,不知道这个B3是哪里来的,为什么会无故跑出个其他数来?
        CmdValid = FALSE;   
       cmdexecution();         根据返回的命令字来执行函数
        Idle=FALSE;

    else
     {
      Tdelay_10ms(10);
      }
}
点赞  2008-8-29 10:07
先从简单的来!!!

我是做c8051f单片机
我打算做三合一的下载线

c8051f,s5x,(以上两种已做好,效果还真不错!!!)

现在准备做mega8/48/88/168


欢迎大家到我的博客看看

http://c8051fmcu.blog.sohu.com

点赞  2008-9-1 16:02
yang96381 很有打广告的嫌疑哦
点赞  2008-9-2 13:18
问题解决了,结贴
点赞  2008-9-2 15:51
这么快就结帖了?lz都没告诉问题的原因呢
点赞  2009-7-8 14:47
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 京公网安备 11010802033920号
    写回复