我用c#编写了一个串口数据接收软件,接收的数据为16进制的6个字符,每秒一次,我软件接受到的数据中大部分是对的,但会有一部分错误,不知道什么原因,发送的数据肯定没有问题,用其他串口调试助手试过,不知道程序是哪的问题,求大神帮我看看,谢谢!
private void comm_DataReceived_1(object sender, SerialDataReceivedEventArgs e)
{
yanshi++;
if (yanshi < 10) return; //仪器的初始化
Data_Receive.Clear();
Thread.Sleep(100); //读取速度太慢,加Sleep延长读取时间, 不可缺少
byte[] buf = new byte[6]; //声明一个临时数组存储当前来的串口数据
received_count += 1; //增加接收计数
comm.Read(buf, 0, 6); //读取缓冲数据
comm.DiscardInBuffer(); //清空缓存,避免下次的数据相互干扰
}
上面是代码,请大神帮我看看,buf中的数据会不定时出现几个与发送不同的数据
------解决思路----------------------
我们更不知道了,你和上游通信,先制定好协议,然后调整串口参数,把你接收到的内容跟上游作对比,看看是接收问题还是发送问题
------解决思路----------------------
串口本来也并不保证数据一定能够正常接收到
它本身是利用电路的高低电平切换来实现通信的
TCP协议底层封装好了校验的方法,如果数据出错,数据包会被丢弃
而串口通信是一个字节一个字节发送,一个字节一个字节接收,并没有"包"的概念
需要你自己制定协议来校验什么样算一组数据,同一组数据通过什么来检测它是否完整,是否有错误
参考SUM校验,CRC校验,MODBUS RTU协议
------解决思路----------------------
你用串口调试助手跟踪了多长时间发现没有问题?
你的程序中不定时发生问题又是多长时间?
不要以为串口调试助手1分钟没有问题,再过5小时就都不会有问题
------解决思路----------------------
我好奇怪哦,读取的时候,很多人都是尽快的读取数据,还没有看到需要延时读取的。
------解决思路----------------------
延时读取逻辑简单,不用考虑分包接包的问题
正规的做法应该是接收到数据后判断是否完整,不完整继续读取,然后自己拼接
------解决思路----------------------
comm.DiscardInBuffer(); //清空缓存,避免下次的数据相互干扰
为什么要Discard,把这行去掉试试
------解决思路----------------------
如果楼主说收到的数据丢失了几个字节,可能是由于这个原因,否则跟它没什么关系,清不清里面也没有数据的
如果是数据错误,这个跟串口通信本身的硬件机制有关系,本来就很可能造成数据错误
------解决思路----------------------
比如串口线附近有个大电机启动了,一个强电磁干扰很可能使你的数据全部变成0xff
------解决思路----------------------
好久没来了,看到这个楼主写的那个接收方法明显有问题,comm.DiscardInBuffer(); 特别是用上了这个。。。
串口发送过来的数据,有时还在缓存区,如果没达到一定的长度是不会触发DataRevive事件 此时你把他清空了,就造成你上面说的200个数据出错。那是因为它也像TCPIP通信一样,在接收的缓存区 粘包。串口数据接收到的数据,下位机有时发送6个字符过来。你的上位机在DataRecive时不一定就是6个字符,有可能是分成两次接收,先接收到4个字符,第二次是2个字符。 这是时有发生的,也就是发生了你上面的问题了,你做这个,应写一个接收字节缓冲区,专门接收字节,也不用Sleep()
看一下这个吧,http://blog.csdn.net/wyd1520/article/details/23822313
这个也是为论坛另一网友跟你提的一样的问题写的。
这是当时他提的原贴子
http://bbs.csdn.net/topics/390316188