pingmac 发表于 2010-11-22 20:50:43

请教关于串口多字节通讯问题-怎么实现数据不混乱

我做的个温度采集

上位机发送6个字节给C52,单片机判断第1个字节和第6个字节,如果不对,就不发送温度数据;

但是我现在这个方法,是利用receive数组来保存多个字节,这样会有个问题就是:

每次必须发送6个字节,如果发送6个以下或以上, 这个判断会永远失效,因为数组每组赋值是叠加在一起的; 如果第一次发送4个字节,那么receive - receive 就先保存了这4个字节,就说后面发送6个正确的字节,但这6个字节只能前面两个字节存放到 receive receive; 依次类推,就永远通不过if了;

请问大家用的什么方法? 拜谢!

void read_serial() interrupt 4
{

        if(RI)
        {
                  receive=SBUF;
                  RI = 0;
              k++;
                  if(k==6)
                  {
                      if(receive=='T'&&receive=='>')
                      {
                     k=0;//置0,便于下一次接收
                     flag=1;//接收完成标志
                      }
                        else
                        {
                                   k=0;
                        }
                  }
               
          }
}

pingmac 发表于 2010-11-22 22:43:08

难道没有人吗?

我意思是每次发送的数据长度不一样!

benladn911 发表于 2010-11-22 22:53:31

要做超时判断机制。

如果第一次数据帧只有4个字节,从接收第1个字节开始启动定时器,如果时间超过4个字节的接收时间后,还是只有4个字节,则这次的数据无效。直接清除接收指针和接收缓冲。

pingmac 发表于 2010-11-23 04:28:40

谢谢了 楼上!

dengxiaofeng 发表于 2010-11-23 08:20:36

我有几次都是这么做的 每次发送几个字节然后接受 判断关键是要懂得舍弃
和2楼说的差不多
哈哈哈
刚刚看了下我原来的程序

是这样操作的首先一个接受计数
如果发送5个为一串,那么当计数到5的时候 判断 第一个字符 是不是我设定的特殊字符
如果是 说明字符串可用如果不是直接舍弃

snoopyzz 发表于 2010-11-23 08:29:24

先对头码,再校验,以下是部分代码

const u8 Comm_HeadBuffer[] =
{
    'W',    // LOGO0
    'T',    // LOGO1
    '0',    // DEV_H
    '0',    // DEV_L
};

void Comm_RecvData(void)
{
    u8 ch;
    while( Uart_ReadByte(&ch)==true )
    {
      if( Comm_HeadBuffer!=ch )
      {
            Comm.HeadPos = 0;
      }
      else
      if( ++Comm.HeadPos>=sizeof(Comm_HeadBuffer) )
      {
            Comm.HeadPos = 0;
            Comm.RecvPos = 0;
            Comm.RecvXor = 0;
            continue;
      }
      //头码正确
      if( Comm.RecvPos<sizeof(Comm.RecvBuffer) )
      {
            Comm.RecvXor ^= Comm.RecvBuffer = ch;
            //校验正确
            if( Comm.RecvXor==0 )
            {
                switch( Comm.RecvBuffer )
                {
                  case COMM_MODE_DATA: Comm_ReadData(); break;
                  case COMM_MODE_TIME: Comm_ReadTime(); break;
                }
            }
      }
    }
}

gongxd 发表于 2010-11-23 08:38:41

串口处理的库,希望可以帮你 详细的数据格式都有,用着很可靠

点击此处下载 ourdev_599778X3AVOT.rar(文件大小:6K) (原文件名:Archive.rar)

benladn911 发表于 2010-11-23 08:38:45

【转】串口接收超时判断的一种思路


有朋友问起串口接收超时的处理,简单说明如下,以51为例,仅提供一个思路,供参考


问题: 串口接收数据,一帧32字节,收满32字节处理一次,但是有可能丢失数据,也就是收不满32字节,如何做超时处理?

假设 : 串口通信格式 9600,n,8,1 ,则传输32字节需要33.333毫秒,则可以判断40毫秒没有接到完整的一帧数据,则超时,做超时处理。

具体处理方式:

接收一帧数据标志:

RcvFlag = 0;

定义一个接收缓冲区数组:

RcvData;

接收数据计数器:

RcvCnt = 0;

超时计数器:

TimeOutCnt = 0

定时器中断,设置为5毫秒中断一次,则中断8次,达到40毫秒。


串口接收中断


void RcvInt(void) interrupt 4 using 2
{

if(RI==1)
{
if(TimeOutCnt==0)
      TimeOutCnt = 10;
RcvData = SBUF;
if(RcvCnt>=32)
{
   RcvFlag = 1;//收到一帧完整的数据
   TimeOutCnt = 0;
   
}
}

}


定时器中断处理:

void timer(void) intterupt 2 using 1
{

重装定时器 ;

if(TimeOutCnt>2)
   TimeOutCnt --;
else
{
   RcvCnt = 0;//接收计数器清0
          TimeOutCnt = 0;//超时计数器清0
}
}


}
//其他处理
}



主程序处理

main()
{
//初始化

      //其他处理

//接收数据处理
if(RcvFlag)
{

//判断处理数据

RcvFlag= 0;
RcvCnt = 0;
}



}

gongxd 发表于 2010-11-23 08:48:41

http://cache.amobbs.com/bbs_upload782111/files_34/ourdev_599786YW283A.JPG
(原文件名:DSCF9567.JPG)

http://cache.amobbs.com/bbs_upload782111/files_34/ourdev_599787QEKIGP.JPG
(原文件名:DSCF9576.JPG)

http://cache.amobbs.com/bbs_upload782111/files_34/ourdev_599788BQM5LI.JPG
(原文件名:DSCF9579.JPG)

http://cache.amobbs.com/bbs_upload782111/files_34/ourdev_599789XG8MQE.JPG
(原文件名:DSCF9580.JPG)

http://cache.amobbs.com/bbs_upload782111/files_34/ourdev_599790WVE10S.JPG
(原文件名:DSCF9603.JPG)

wanyou132 发表于 2010-11-23 11:03:35

MARK 标记

stepby 发表于 2010-11-23 11:07:25

MARK

susuyu 发表于 2010-11-29 09:18:54

mark

wang_2008 发表于 2012-2-9 11:30:47

mark

bihan163 发表于 2012-8-29 11:27:18

过来学习下

步凡王子 发表于 2012-8-29 11:42:37

啊 之前我的出错了 总是要浪费一个有用的数据才能再次开始接受有用数据 加上这个 就可以不浪费那个有用的数据了 多谢楼主了。

wzd 发表于 2012-9-28 15:28:39

过来学习下
页: [1]
查看完整版本: 请教关于串口多字节通讯问题-怎么实现数据不混乱