串口转485芯片开发笔记(UM3085EESA)

1. 关键信息

  • 芯片:UM3085EESA
  • 工作电压:5V
  • 波特率:最高500kbps
  • DE/RE引脚(并联场景下):高电平发送,低电平接收
  • 功能:TTL电平与RS-485差分电平互转(半双工)

注意:方向切换存在延时,参考手册:$ t_{DZL} $/$ t_{DZH} $ = 2500ns

2. 管脚定义

引脚名称 引脚功能 输出方向
RO 接收器输出,接串口RX Output
RE 接收使能(低有效) Input
DE 驱动使能(高有效),通常将DE和RE#引脚并联在一起,通过MCU的一个GPIO口控制芯片收发切换 Input
DI 驱动器输入,接串口TX Input
GND Power
A 总线差分正端 Bidirectional
B 总线差分负端 Bidirectional
VCC 电源(+5V) Power

常见问题

数据通信错误,串口发送字节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?

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

发送数据被截断,PC收到3F乱码

问题背景:2400bps端口偶发发送异常,单步调试正常,连续运行异常。PC收到断裂帧:01 03 01 00 3F 3F 00 02 C5 FF

尝试增加LOG确认软件发送了正确的8字节(01 03 01 00 00 02 C5 F7),但PC收到10字节,多了3F 3F,且最后一字节F7变FF。

3F是RS485 DE引脚拉低后差分线浮空的典型采样值,怀疑是是485收发方向中途被异常转换。

发现设计的35ms静默超时在发送期间清零了u16CommLen,同时bWaitLastTxComplateFlag在TXE中断中过早置起!!

根因:TXE中断置起bWaitLastTxComplateFlag后,主循环检测到后执行EnableRx拉低DE,此时移位寄存器可能还在发送。35ms超时在发送期间清零u16CommLen,导致提前结束发送。之前用别的端口正常是因为,别的端口用的都是9600bps,2400bps下8字节需36.7ms > 35ms超时阈值,9600bps下9.2ms < 35ms正常。

解决办法:发送真正完成后再置起bWaitLastTxComplateFlag。超时处理需区分,本意是数据接收超时,不应该在发送时生效,所以超时处理加bTxInProgress保护,发送中不重置缓冲区,保持发送。发送启动前清除残留标志。

DE/RE引脚控制时序不当导致最后一字节丢失

问题背景:发送完成后立即转接收,最后一个字节被截断,从机无响应。

软件在TXEIE中断中置起发送完成标志,主循环检测到后立即执行EnableRx拉低DE。但TXE只是数据寄存器空,移位寄存器可能还在发送最后一个字节。

根因:TXEIE ≠ TC。TXEIE中断触发时最后一个字节刚移到移位寄存器,还在发送中。此时拉低DE,转接收,会截断最后一个字节的发送。

解决办法:等待TC(发送完成)标志后再切换DE。或最后一个字节写入后关TXEIE中断、开TCIE中断,等发送完成中断触发后再切换DE。

通过确认USARTn_SR.TC位确认发送是否完成。连续发送数据并使用发送中断的情况,可通过TI(发送数据寄存器空中断)中断写入最后一个发送数据,并将USARTn_CR1.TXEIE写0,USARTn_CR1.TCIE写1,最后一帧数据发送结束后,产生发送完成中断1

参考资料

  1. XHSC. (2024). RM_HC32F460_F45x_A460系列参考手册_Rev1.5

results matching ""

    No results matching ""