搜索
bottom↓
回复: 15

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

[复制链接]

出0入0汤圆

发表于 2010-11-22 20:50:43 | 显示全部楼层 |阅读模式
我做的个温度采集

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

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

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

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

void read_serial() interrupt 4
{

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

阿莫论坛20周年了!感谢大家的支持与爱护!!

知道什么是神吗?其实神本来也是人,只不过神做了人做不到的事情 所以才成了神。 (头文字D, 杜汶泽)

出0入0汤圆

 楼主| 发表于 2010-11-22 22:43:08 | 显示全部楼层
难道没有人吗?

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

出0入0汤圆

发表于 2010-11-22 22:53:31 | 显示全部楼层
要做超时判断机制。

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

出0入0汤圆

 楼主| 发表于 2010-11-23 04:28:40 | 显示全部楼层
谢谢了 楼上!

出0入18汤圆

发表于 2010-11-23 08:20:36 | 显示全部楼层
我有几次都是这么做的 每次发送几个字节  然后接受 判断  关键是要懂得舍弃
和2楼说的差不多
哈哈哈
刚刚看了下我原来的程序

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

出0入0汤圆

发表于 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[Comm.HeadPos]!=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[Comm.RecvPos++] = ch;
            //  校验正确
            if( Comm.RecvXor==0 )
            {
                switch( Comm.RecvBuffer[COMM_MODE] )
                {
                    case COMM_MODE_DATA: Comm_ReadData(); break;
                    case COMM_MODE_TIME: Comm_ReadTime(); break;
                }
            }
        }
    }
}

出0入0汤圆

发表于 2010-11-23 08:38:41 | 显示全部楼层
串口处理的库,希望可以帮你 详细的数据格式都有,用着很可靠

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

出0入0汤圆

发表于 2010-11-23 08:38:45 | 显示全部楼层
【转】串口接收超时判断的一种思路


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


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

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

具体处理方式:

接收一帧数据标志:

RcvFlag = 0;

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

RcvData[48];

接收数据计数器:

RcvCnt = 0;

超时计数器:

TimeOutCnt = 0

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


串口接收中断


void RcvInt(void) interrupt 4 using 2
{

if(RI==1)
{
  if(TimeOutCnt==0)
      TimeOutCnt = 10;
  RcvData[RcvCnt++] = 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;
}



}

出0入0汤圆

发表于 2010-11-23 08:48:41 | 显示全部楼层

(原文件名:DSCF9567.JPG)


(原文件名:DSCF9576.JPG)


(原文件名:DSCF9579.JPG)


(原文件名:DSCF9580.JPG)


(原文件名:DSCF9603.JPG)

出0入0汤圆

发表于 2010-11-23 11:03:35 | 显示全部楼层
MARK 标记

出0入0汤圆

发表于 2010-11-23 11:07:25 | 显示全部楼层
MARK

出0入0汤圆

发表于 2010-11-29 09:18:54 | 显示全部楼层
mark

出0入0汤圆

发表于 2012-2-9 11:30:47 | 显示全部楼层
mark

出0入0汤圆

发表于 2012-8-29 11:27:18 | 显示全部楼层
过来学习下

出0入0汤圆

发表于 2012-8-29 11:42:37 | 显示全部楼层
啊 之前我的出错了 总是要浪费一个有用的数据才能再次开始接受有用数据 加上这个 就可以不浪费那个有用的数据了 多谢楼主了。

出0入0汤圆

发表于 2012-9-28 15:28:39 | 显示全部楼层
过来学习下
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片。注意:要连续压缩2次才能满足要求!!】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-7-23 22:16

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

快速回复 返回顶部 返回列表