串口转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。
参考资料
-
XHSC. (2024). RM_HC32F460_F45x_A460系列参考手册_Rev1.5. ↩