串口转485应用笔记(UM3085EESA)

1. 关键信息

常见问题

数据通信错误,串口发送字节0x55,PC接收 0x55FF

使用了一款新的芯片,在测试通信能时,发现数据异常。原本发送的单字节变成了双字节,很有问题!

我的链路通信MCU串口 -> 串口转485芯片(UM3085EESA) -> 485转USB -> PC

快速检查了软件,没有发现明显问题。但是凭我的感觉应该是MCU到485芯片之间出了问题,因为我知道我的TX在空闲的时候是高电平,初步怀疑可能是串口转485将空闲作为数据发送了。

尝试发送完成后将485芯片转接收,正确接收0x55。因为我一直是将485芯片处于发送状态,这样的RE引脚一直拉高。(实际上只是强制转接收吧数据扔掉了)

危险!!,思考了一下还是不对,理论上不应该如此,串口一帧数据发完哪来的起始位,没有起始位怎么可能把下一帧数据再发送出去?

于是用示波器尝试抓MCU TX口波形,发现数据位和停止位之间多了一位,但是我明应该配置的是无校验。无校验的话也不可能多以数据周期。尝试用切换为奇校验,数据正确!确信的停止位应该是高电平,这个数据位和这里多的一位有问题。(就是485把校验位当作起始位发了下一帧,导致上位机解析出了FF)

于是检查代码发现,校验配置没有无校验模式,只有奇偶校验和多机模式,我配的竟然是一个多机模式,差点被骗过去了(其实是当然写代码的时候想当然了,把多机模式认为是无校验)。

但是如何配置无校验呢,手册看了半天,没找到。于是遭到芯片厂商技术支持,一下就点出了问题所在,要配置无校验应该先配置串口模式位MODE1。这块芯片(HC32L170JATA)串口有四种模式,MODE0 同步半双工,还有MODE123,异步全双工。当时没有仔细看这部分内容,再MODE1下数据组成如下Start (1bit) + Data(8bit) + Stop(1~2bit),好吧,为什么不直接出一个无校验呢😥

差点让这个问题漏过去,如果因为底层没有配置好,在应用层再发现,定位时间又要翻倍了。

Modbus RTU通信中的帧错位问题,485应用层通信超时后,收到上一帧数据导致错误数据被接收写入

问题背景:偶发性数据错误:在0-50号寄存器范围内,偶尔出现数据写入为0的异常

因为我的modbus是间隔发的0~50有正常数据,应为非0值,50~100为空。偶发性的出现0~50寄存器数据错误。本来打算不管,但是有点难受,于是尝试找问题根因。

通过增加日志发现,在没有通信的情况下bug是不复现的,只有在通信情况下问题才会出现,排除系统跑飞,导致数据被情况。

找到数据写入部分,增加日志。通过日志发现出现异常时,数据响应超时。我在超时时,切换了下一帧发送,然后,得到了一个新的响应,难道新的响应被认为时上一帧丢失的数据吗?

我开始不断的快速断开连接通信,问题复现概率变高,问题变成稳定复现。

通过分析日志发现,实际是当设备从机响应超时(280ms)后,从机再发送响应帧到线控主机,导致线控主机接收上一帧错误数据,进而写入寄存器表的异常问题。

根因:Modbus RTU通信中的帧错位问题。PC从机概率性的响应超时,可能是modbus slaver本身的bug?

解决办法;增加了从机响应帧正确性判断,修改参数轮询间隔数据包寄存器数据数量差异。如果接收数据超时,且从机响应跟我主机请求数量不匹配则丢弃此次接收。主要还是请求与响应缺少校验的手段,导致错误数据滥竽充数。

参考资料

results matching ""

    No results matching ""