与设备联调Csharp使用SerialPort这个类实现的串口通讯时出现的数据不完整问题解决。

现象:

环境:上位机软件,Csharp编写,SerialPort类实现串口异步通讯;
下位机,STM32F1系列单片机。
串口设置: 波特率9600, 8bit数据位,1bit停止位, 无校验。
当上位机与下位机串口通讯时,通过观察收发,发现有时候接收的数据并不是一个完整的数据帧。
例如: 发 10 11 12 13 14
收到可能为 10 11 12
然后再收到 13 14.
但是通过串口助手分别与上位机和下位机通讯,同样的串口设备却不存在这个问题。基本可排除下位机问题了,可能是SerialPort类实现的串口接收问题。
上网查询,结果很多都存在这个问题。

解决

网上给出的办法基本有两个:
1, 在SerialPort的异步串口接收函数内,申请一个大的缓存,当存满指定长度的缓存时再触发。或者自己实现组包。
2, 在异步串口接收函数开始,对本异步线程延迟一段时间,等待所有数据接收完。 这个方法,也有效,不过延迟的时间需根据接收数据最大长度来定,这对短的数据接收就有些不可取了。

我采用的算是第一种方法吧。
首先申请了一个私有字段 List comRecvBuffer = new List();

然后在接收函数内

        private void sp1_DataReceived(object sender, SerialDataReceivedEventArgs e)
        {
            while (ComDevice.BytesToRead > 0)
            {
                comRecvBuffer.Add((byte)ComDevice.ReadByte());
                if (comRecvBuffer.Count >= 1024)//缓存溢出
                {
                comRecvBuffer.Clear();
                //清缓存
                ComDevice.DiscardInBuffer();//清输入缓冲区
                    return;
                }
            }
            RecvDataAnalyze(null, comRecvBuffer.ToArray());
        }

在RecvDataAnalyze 这个函数内判断接收到的是否为完整数据帧,因为是MODBUS协议,我先判断了地址,然后计算CRC跟后两位是否相同来判断是否接收了完整帧。是的话就显示然后处理。 若不是的话需要清缓存,如下:

                    comRecvBuffer.Clear();
                    //清缓存
                    ComDevice.DiscardInBuffer();//清输入缓冲区
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值