请教关于串口多字节通讯问题-怎么实现数据不混乱
我做的个温度采集上位机发送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;
}
}
}
} 难道没有人吗?
我意思是每次发送的数据长度不一样! 要做超时判断机制。
如果第一次数据帧只有4个字节,从接收第1个字节开始启动定时器,如果时间超过4个字节的接收时间后,还是只有4个字节,则这次的数据无效。直接清除接收指针和接收缓冲。 谢谢了 楼上! 我有几次都是这么做的 每次发送几个字节然后接受 判断关键是要懂得舍弃
和2楼说的差不多
哈哈哈
刚刚看了下我原来的程序
是这样操作的首先一个接受计数
如果发送5个为一串,那么当计数到5的时候 判断 第一个字符 是不是我设定的特殊字符
如果是 说明字符串可用如果不是直接舍弃 先对头码,再校验,以下是部分代码
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;
}
}
}
}
} 串口处理的库,希望可以帮你 详细的数据格式都有,用着很可靠
点击此处下载 ourdev_599778X3AVOT.rar(文件大小:6K) (原文件名:Archive.rar) 【转】串口接收超时判断的一种思路
有朋友问起串口接收超时的处理,简单说明如下,以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;
}
} 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) MARK 标记 MARK mark mark 过来学习下 啊 之前我的出错了 总是要浪费一个有用的数据才能再次开始接受有用数据 加上这个 就可以不浪费那个有用的数据了 多谢楼主了。 过来学习下
页:
[1]