C# 接受串口数据处理的问题, 包全粘帖一起了 怎么处理?

色郎中 2012-07-12 12:11:35
发送一个命令后
收到ARM那边传来的数据,其实ARM是打了四次,分别如下:

F0037E018E
7001 17 01060000FFFF01444444444444444444444444 42 记录一
7001 17 01060000FFFF01555555555555555555555555 76 记录二
F0037E048B

“F0 03 7E 01 8E ”
头 长度 内容 校验
7001 17 01060000FFFF01555555555555555555555555 76 记录二
头 长度 内容 校验


但是C#里接受时,并不是我想象的那样触发了4次事件,每次刚好接受一个数据包
全部粘帖在一起了,一起过来了



我在 form_load 里做如下
 comm.ReceivedBytesThreshold = 5;// 触发条件,
//添加事件注册
comm.DataReceived += comm_DataReceived;


接受事件的代码目前这么写:
 int n = comm.BytesToRead;
byte[] buf = new byte[n];//声明一个临时数组存储当前来的串口数据
string str = "";
received_count += n;//增加接收计数

comm.Read(buf, 0, n);//读取缓冲数据



//因为要访问ui资源,所以需要使用invoke方式同步ui。
this.Invoke((EventHandler)(delegate
{
for (int i = 0; i < n; i++)
{
str += buf[i].ToString("X2");
}
this.txGet.AppendText(str);
//修改接收计数
labelGetCount.Text = "Get:" + received_count.ToString();
}));


是可以将所有数据都显示到 texBox上的,

现在是我只想取得数据包中有效的数据,如下记录描述:

7001 17 01060000FFFF01444444444444444444444444 42 这个数据包中的 “4444444444444444444444”

但是通过断点观察,接受事件里,都是2次才能将数据包给收齐。

如第一次收到如下这么多
F0 03 7E 01 8E 70 01
第二次才把后面的给收全
17 01 06 00 00 FF FF 01 44 44 44 44 44 44 44 44 44 44 44 44 42 F0 03 7E 04 8B 70 01 17 01060000FFFF01555555555555555555555555 76 F0037E048B

怎么会出现这样的情况呢? 如何处理是好?


...全文
979 11 打赏 收藏 转发到动态 举报
写回复
用AI写文章
11 条回复
切换为时间正序
请发表友善的回复…
发表回复
色郎中 2012-07-12
  • 打赏
  • 举报
回复

int n = comm.BytesToRead;
byte[] buf = new byte[n];//声明一个临时数组存储当前来的串口数据
string str = "";
received_count += n;//增加接收计数

comm.Read(buf, 0, n);//读取缓冲数据



//因为要访问ui资源,所以需要使用invoke方式同步ui。
this.Invoke((EventHandler)(delegate
{
for (int i = 0; i < n; i++)
{
str += buf[i].ToString("X2");
}
this.txGet.AppendText(str);
//修改接收计数
labelGetCount.Text = "Get:" + received_count.ToString();
}));


我这个接受放在 事件里的,应该是类似线程的吧
而且目前直接显示在 texBox 上是正常的

但是要解析 想要数据过程中,就是有问题,和自己想象的不一样
不想底层,缓存有多少,我取多少,没有问题

我就想不通,这个PC 上接收数据,不行呢,一次打过来超过8个字节,就要分两次了呢
邪门
缭绕飘渺 2012-07-12
  • 打赏
  • 举报
回复
楼主搞硬件比较牛
这个串口接收不关c#语言的事
串口本来就是根据波特率来收发数据的
你应该在接受事件中启动一个线程
在这个线程中根据你的协议去处理数据
色郎中 2012-07-12
  • 打赏
  • 举报
回复
定义了呀,,下面是ARM返回的 4个包

F0037E018E
7001 17 01060000FFFF01444444444444444444444444 42 记录一
7001 17 01060000FFFF01555555555555555555555555 76 记录二
F0037E048B

“F0 03 7E 01 8E ”
头 长度 内容 校验
7001 17 01060000FFFF01555555555555555555555555 76 记录二
头 长度 内容 校验

关键问题时就是,或接收岔了,而C#里接受时

并不是触发了四次事件

分两次接受了,第一接受的字节数,大于第一条记录的长度

第二次,将剩余的都接受了,

于是就把数据包打乱了。。。

bdmh 2012-07-12
  • 打赏
  • 举报
回复
告诉你了,制定协议,包头包尾,校验
色郎中 2012-07-12
  • 打赏
  • 举报
回复

看了,你的那个太复杂了
看不懂 呵呵


int n = comm.BytesToRead;//
byte[] buf = new byte[n];//声明一个临时数组存储当前来的串口数据

bool data_1_catched = false;
string str = "";
received_count += n;//增加接收计数
temp_Counter += n;
comm.Read(buf, 0, n);//读取缓冲数据

if (n > 0)
{
Array.ConstrainedCopy(buf, 0, binary_data_1, temp_Counter - n, n);

if (temp_Counter - n > 0)
data_1_catched = true;
//正确分析一条数据,从缓存中移除数据。
Array.Clear(buf, 0, buf.Length);
}

if (data_1_catched)
{
this.Invoke((EventHandler)(delegate
{
for (int i = 0; i < temp_Counter; i++)
{
str += binary_data_1[i].ToString("X2");
}
this.txGet.AppendText(str);
temp_Counter = 0;
Array.Clear(binary_data_1, 0, binary_data_1.Length);
//修改接收计数
labelGetCount.Text = "Get:" + received_count.ToString();
}));


我现在用一个中间数组,做缓存,,收全了,再处理 这个中间数组的内容

还是有问题呢,,劳驾看看是是上问题呢

谢谢



[Quote=引用 8 楼 的回复:]

呵呵,你的串口问题还没解决啊。

上次忘了给你一个解决方法,请看:SerialPort.DataReceived之“管收不管埋”
[/Quote]
celeron729 2012-07-12
  • 打赏
  • 举报
回复
串口哪里有什么包,只有字节流,要lz字节的程序去分包
showlie 2012-07-12
  • 打赏
  • 举报
回复
另外,你说的一个数据包总是两次接收才能完全收完,这可能是因为ReceivedBytesThreshold设置过小问题。
不过,SerialPort.DataReceived之“管收不管埋”也能解决这个问题。
showlie 2012-07-12
  • 打赏
  • 举报
回复
呵呵,你的串口问题还没解决啊。

上次忘了给你一个解决方法,请看:SerialPort.DataReceived之“管收不管埋”
缭绕飘渺 2012-07-12
  • 打赏
  • 举报
回复
我的意思是在接收里有一个列表这样的东西,读取的数据添加到列表
存放你收到的数据
然后有一个线程去处理你这个列表
判断是不是你需要的数据,是就处理,不是就丢弃
lanweiqiang 2012-07-12
  • 打赏
  • 举报
回复
串口不懂你的通讯协议,当然无法处理粘包
楼主需要根据收到的数据,自己处理粘包的问题
EnForGrass 2012-07-12
  • 打赏
  • 举报
回复
严格按照协议接收数据,读取有效数据,(判断是否是完整数据)

110,538

社区成员

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

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

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