串口通信,接收问题,新手求指教!!!!!

程序小小说 2014-11-10 01:35:49
在层序中我使用了comm.DataReceived += comm_DataReceived;来添加事件,事件中我这样写

也就是想既能接收16进制数,还能显示汉字和字符串(都是通过同一编解码来的)
现在问题是,接收的时候老是丢内容,但是加了第一行挂起延时后,基本上不丢了(不过发的多了,就会丢一个字节)。
但是把这个挂起注掉,单步调试的时候,这个函数就会进入两遍,第一遍显示串口内8个字节,第二遍字节就很多。而且接收到的信息就丢了。
还有一点,我单步调试的时候,接收的信息是好的,不会丢数据,但是运行起来,数据就丢了。
想请教一下,这些是怎么回事???
...全文
303 23 打赏 收藏 转发到动态 举报
写回复
用AI写文章
23 条回复
切换为时间正序
请发表友善的回复…
发表回复
敌敌畏耶 2014-11-12
  • 打赏
  • 举报
回复
先接受,再开一个线程处理·· 先接受到放入一个队列里,然后在根据你所需要的长度从队列里面取出来··进行操作··
程序小小说 2014-11-11
  • 打赏
  • 举报
回复
引用 17 楼 jeabo 的回复:
在你发送端前面加上你这次要发的字符的长度,比如你规定前8位数字是要发送的字符串长度,你接受端接受前8个字符就是要第二步真正要接受的字符的长度,继续接受,如果接受了你得到的字符数量后就结束,否则不结束。不知道你是不是遇到这问题
我的问题是,我发一串字符串,它接收8个字节后程序自己就断了,然后重新触发。这会不会是跟触发方式有关??还是执行触发后的函数在时间上有什么冲突??
yalunwang123 2014-11-11
  • 打赏
  • 举报
回复
引用 20 楼 Z65443344 的回复:
[quote=引用 19 楼 yalunwang123 的回复:] 我有帧结束符,我想做的是接收完数据要处理解析数据。但是一次完整的数据,接收数据的函数执行了两次。才完整的接收。我怎么把他两次的存起来啊。
放到数组里呗 比如List<byte>,或byte[]都行[/quote] 用ArragList LIST=new ArragList();为什么不行啊,因为我判断的是if(LIST[2]==0x69)调试提示object 和int不能。
  • 打赏
  • 举报
回复
拼接 用起始符 终止符分割
於黾 2014-11-11
  • 打赏
  • 举报
回复
引用 19 楼 yalunwang123 的回复:
我有帧结束符,我想做的是接收完数据要处理解析数据。但是一次完整的数据,接收数据的函数执行了两次。才完整的接收。我怎么把他两次的存起来啊。
放到数组里呗 比如List<byte>,或byte[]都行
yalunwang123 2014-11-11
  • 打赏
  • 举报
回复
引用 2 楼 Z65443344 的回复:
串口跟以太网通信不一样 它不存在数据包的概念 数据是一个字节一个字节发送的, 也是一个字节一个字节接收的 串口卡不知道什么时候会接收到完整的数据,因为根本不存在"完整"的概念 你只能接到数据之后自己拼接
我有帧结束符,我想做的是接收完数据要处理解析数据。但是一次完整的数据,接收数据的函数执行了两次。才完整的接收。我怎么把他两次的存起来啊。
猴子写代码 2014-11-10
  • 打赏
  • 举报
回复
在你发送端前面加上你这次要发的字符的长度,比如你规定前8位数字是要发送的字符串长度,你接受端接受前8个字符就是要第二步真正要接受的字符的长度,继续接受,如果接受了你得到的字符数量后就结束,否则不结束。不知道你是不是遇到这问题
liusm001 2014-11-10
  • 打赏
  • 举报
回复
引用 15 楼 u011113596 的回复:
[quote=引用 14 楼 liusm001 的回复:] [quote=引用 11 楼 Z65443344 的回复:] 回9楼,你这是同步的方式,跟异步的理念完全不一样 而且你的代码是建立在对方能够完整的处理你的发送并正常返回数据的前提下的 而无法解决发送之后对方接收的数据被分成多次接收的情况
我这个代码是对法只在接收准确的信息后才会返回信息,我看楼主的情况可能和我的差不多[/quote] 我不确定事件的触发是接收到一个字节的同时就触发呢,还是其他的方法,ReceivedBytesThreshold这个属性我都没改过,按理来说是接收到一个字节的同时就触发事件。那它触发事件后,在执行事件的时候会不会有新的触发,如果有,而且当前事件还没执行完,那还触发吗?[/quote] 没有过,可能需要清空接收区,在接到设置的字节数才会触发
程序小小说 2014-11-10
  • 打赏
  • 举报
回复
引用 14 楼 liusm001 的回复:
[quote=引用 11 楼 Z65443344 的回复:] 回9楼,你这是同步的方式,跟异步的理念完全不一样 而且你的代码是建立在对方能够完整的处理你的发送并正常返回数据的前提下的 而无法解决发送之后对方接收的数据被分成多次接收的情况
我这个代码是对法只在接收准确的信息后才会返回信息,我看楼主的情况可能和我的差不多[/quote] 我不确定事件的触发是接收到一个字节的同时就触发呢,还是其他的方法,ReceivedBytesThreshold这个属性我都没改过,按理来说是接收到一个字节的同时就触发事件。那它触发事件后,在执行事件的时候会不会有新的触发,如果有,而且当前事件还没执行完,那还触发吗?
liusm001 2014-11-10
  • 打赏
  • 举报
回复
引用 11 楼 Z65443344 的回复:
回9楼,你这是同步的方式,跟异步的理念完全不一样 而且你的代码是建立在对方能够完整的处理你的发送并正常返回数据的前提下的 而无法解决发送之后对方接收的数据被分成多次接收的情况
我这个代码是对法只在接收准确的信息后才会返回信息,我看楼主的情况可能和我的差不多
liusm001 2014-11-10
  • 打赏
  • 举报
回复
串口通信是要有时间的,比如,我的接收信息是36个字节,我测试过,9600的波特率可能需要35ms左右,基本上延时个100ms就可以保证接收数据完整,计算机的反应速度是很快的,执行一个语句的速度可能非常快,来不及接收完整就会跳到下一句了
程序小小说 2014-11-10
  • 打赏
  • 举报
回复
引用 8 楼 Z65443344 的回复:
话说,串口发送文字消息,自己玩玩还可以,真正工业上,没有这么用的 都是有固定的协议, 比如固定长度,或者先发送后面总共的字节数,再发送数据 或者即使是固定长度,也有起止符 可能还要加上CRC校验或SUM校验来抗干扰,避免接收到错误的数据
其实就是个任务,等待验收的。刚接触C#,好多东西不太懂,都是网上找的参考
於黾 2014-11-10
  • 打赏
  • 举报
回复
回9楼,你这是同步的方式,跟异步的理念完全不一样 而且你的代码是建立在对方能够完整的处理你的发送并正常返回数据的前提下的 而无法解决发送之后对方接收的数据被分成多次接收的情况
程序小小说 2014-11-10
  • 打赏
  • 举报
回复
引用 9 楼 liusm001 的回复:
发送以后加延时,延时药足够大 PDUscan.Sp.DiscardInBuffer(); PDUscan.Sp.DiscardOutBuffer(); byte[] bytes = setaddr(addnow, addnew); PDUscan.Sp.Write(bytes, 0, bytes.Length); System.Threading.Thread.Sleep(100); int len = PDUscan.Sp.BytesToRead; if (len != 8) { return false; } else { byte[] recievebyte = new byte[len]; PDUscan.Sp.Read(recievebyte, 0, len); if (recievebyte[4] == 0x01) { PDUscan.Sp.Close(); return true; } else { PDUscan.Sp.Close(); return false; } }
我的程序加延时后也没什么问题,去掉延时就不行了,请问这里为什么要加延??而且请问你的代码中recievebyte[4] == 0x01 是什么意思??
liusm001 2014-11-10
  • 打赏
  • 举报
回复
发送以后加延时,延时药足够大 PDUscan.Sp.DiscardInBuffer(); PDUscan.Sp.DiscardOutBuffer(); byte[] bytes = setaddr(addnow, addnew); PDUscan.Sp.Write(bytes, 0, bytes.Length); System.Threading.Thread.Sleep(100); int len = PDUscan.Sp.BytesToRead; if (len != 8) { return false; } else { byte[] recievebyte = new byte[len]; PDUscan.Sp.Read(recievebyte, 0, len); if (recievebyte[4] == 0x01) { PDUscan.Sp.Close(); return true; } else { PDUscan.Sp.Close(); return false; } }
於黾 2014-11-10
  • 打赏
  • 举报
回复
话说,串口发送文字消息,自己玩玩还可以,真正工业上,没有这么用的 都是有固定的协议, 比如固定长度,或者先发送后面总共的字节数,再发送数据 或者即使是固定长度,也有起止符 可能还要加上CRC校验或SUM校验来抗干扰,避免接收到错误的数据
於黾 2014-11-10
  • 打赏
  • 举报
回复
如果你要发送的内容中包含汉字,那么编码02和0d有可能被正常的数据使用 你就需要自己定义起止符了 比如ffff作为起始,0000作为结束
於黾 2014-11-10
  • 打赏
  • 举报
回复
就是起止符,一般如果你发送的是ASCII码,那么数据中就绝对不会出现类似0x02,0x0D这种东西 一般都是将0x02作为起始符,0x0D作为结束符 怎么拼接,你的字符串总要变成byte数组才能通过串口发送吧 不要直接发送,而是循环赋值到一个新的byte数组中去,然后再发送 或者发送之前,先发个02,发送结束,再发送个0D,都行
程序小小说 2014-11-10
  • 打赏
  • 举报
回复
引用 1 楼 BuilderC 的回复:
因为你操作的缓冲区,缓冲区里数据无法保证完整, 一般的串口通信协议都有头标示、 或者结束标示。 你需要不断的拼出完整的数据再进行处理。
头尾标示是不是就是平常说的起止符啊??这个是不是发送是、字符前自己加在所发字符串的前后的??还有请问数据具体是怎么拼出的??谢谢了
於黾 2014-11-10
  • 打赏
  • 举报
回复
用List<byte>或byte[]+int自己算索引偏移 不保证2次就能收到所有的数据,也有可能需要很多次,这跟你发送的数据量有关系 如果很短,也有可能一次就收到 你可以自定义起始符和结束符,这样就能知道到哪里就算收全了 或者如果每次发送的是固定长度的,判断长度也可以 如果是同步接收,也可以通过时间来判断,比如100ms都没有任何新的字节到达
加载更多回复(3)

110,534

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Web++
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧