记录一次给下位机串口发包不回的bug

前言

采购了第三方的传感器。开始只知道是2400bps/8位数据位/1位停止位。
用PC端的串口助手发包,传感器不回包。

实验

先问第三方的研发部,说是偶校验,用串口助手发包有回包。但是用我们自己的上位机(C#)和下位机(STM32)均没有回包。

因为我们上位机采用的是无校验的方式,这个选项没法设置,只能采用无校验。
先请第三方将他们的协议改成无校验。

再用串口助手试一下。手头有2个版本的串口助手。

  • ComMonitor(串口助手4.5), 用这个工具按照2400/N/8/1发包,是有正确回包的。
  • 用星翼的XCOM V2.0发包,收到的包不对,前面有很多3F,然后才是约定的包,而且包的CRC16-modbus校验过不了。
  • 用我们自己的上位机发包,收到的包头尾是对的,中间有2~4个字节不对,导致CRC16-modbus校验无法通过。

调试

先自查上位机

  • 我们C#上位机程序是以前写好的,手头没有可参考的代码。
    无源码动态调试主程序,在system.io中的最底层串口打开处下断点,程序跑起来,断住后,看到串口通讯参数,确实是2400/N/8/1. 发包也没错。但是收包的内容确实不对。

  • 去下载了串口监视工具,看用ComMonitor发包和用我们自己软件发包,在打开串口的参数上有啥不同。
    发现确实有不同。
    又去比较XCOM V2.0的发包和ComMonitor,我们自己上位机的区别(这里只有ComMonitor的回包是对的),这次发现了有效的区别。 ComMonitor打开串口时,会指定 DTR_ENABLE 选项。原来第三方的设备采用了流控制,怪不得。

  • 修补上位机程序。
    无源码动态调试住程序,在发包的代码上断住,回溯,回一层,就浏览这一层的编码实现。找到了上位机设置串口参数的地方。

编辑此函数,加了一句DTR使能代码,重新编译,保存全部。

this.ComPort.DtrEnable = true;

这回,再用上位机发包,正常了。NB.

修改下位机

我们软件有3种用法:

  • 一种是直接用上位机去和传感器通讯(通过PC端的串口)。
  • 一种是通过网络,通过下位机透传串口收发。
  • 一种是和下位机通讯,下位机将结果报上来。
    那下位机该咋改呢,一查,下位机初始化串口时,并没有设置DTR的选项。但是流控选项有,就将默认的USART_HardwareFlowControl_None改为
USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_RTS

编译完,下载跑起来,O了~

总结

  • 上位机软件编码成本低,要考虑的情况要周到些。像参数设置这种场景,要将参数列出来,让用户选,而不能有默认参数,用户改不了的情况。
  • 如果和第三方的接口交互不畅,还是要第三方指导快一些。至少能尽快确认问题的原因,最好能一起联调下(如果对方愿意帮我我们)。
  • 下位机的参数要在配置文件中列全些,使用配置文件中的参数,而不是使用默认参数。这样,如果有方法去改配置文件(e.g. 修改http server的配置页面HTML + JS代码), 那下位机程序就不用修改。
  • 如果像我们的上位机那样,我没有权限得到工程,可以在无源码的情况下,去帮他修复bug, 整完之后,还是蛮开心的。NB.
发布了436 篇原创文章 · 获赞 126 · 访问量 175万+

猜你喜欢

转载自blog.csdn.net/LostSpeed/article/details/103974084