
1. 问题描述 客户反馈产品在使用 STM32G0C1NEY6TR 的 USART6 和另外一颗 STM32L433CCY6TR 进行单线串口半双工通信时发现数据帧错误,而且很容易复现。从逻辑分析仪抓到的数据看是停止位报错。如下图一。 ![]() 图一 2. 问题确认 针对客户的反馈,建议客户用示波器抓串口波形看数据帧报错时波形有没异常。后来从抓到的波形看 STM32L433 发送过来的起始位数据电压为 1.51v,明显低于 0.7VDD=2.31v (这里 STM32G0 VDD=3.3v,STM32L433 VDD=2.5v), 如下图二 ![]() 图二 3. 问题分析 从示波器的波形看,客户产品两颗 MCU 串口通信的电平并不一致,STM32G0 是 3.3v 供电,而 STM32L433 是 2.5v 供电。但正常 STM32L433 串口发送数据给 STM32G0 高电平为 2.4v 高于 0.7VDD,理论上这也不会影响正常的串口通信。我们怀疑 1.5V 电平是由于 UART 通信线两边状态切换时一边拉高而另一边拉低导致。建议客户提供两边串口 GPIO 的配置,并检查半双工两边收发状态切换时的时序逻辑。 ![]() 图三 首先客户提供了上面图三的 STM32G0 的串口 GPIO 配置,发现 GPIO 默认是下拉的。这跟我们正常配置串口 GPIO 为上拉以及参考手册上关于单线串口半双工配置要求不符,如图四,在单线串口模式时,要求 TX 配置为开漏模式而且需要外部上拉。开始以为是这个GPIO 的配置导致的问题。但后面客户反馈他们并没有采用参考手册这种单线串口半双工通信模式。而是客户自己使用 TX/RX SWAP 客制化实现的一种半双工串口通信。如下图五框图,客户单线串口通信也是使用一根线连接,但 TX、RX 功能的切换是通过软件配置USART_CR2 寄存器的 SWAP 位实现的。 ![]() 图四 ![]() 图五 并且这里 GPIO 配置为默认下拉是由于使能了 TX,RX 管脚电**向功能。 ![]() 图六 对于客户奇怪的单线串口设计,我们首先的疑问是为什么不直接使用参考手册提供的现成的单线串口半双工通信方法,而是要自己去实现一套软件切 TX,RX 的单线半双工通信。客户的答复是这是保留上一代产品的设计,新一代的产品设计只是因为成本,将两颗 MCU中的一颗 MCU 更换为了 STM32G0,而原来 STM32L433 上的软件是不能更改的。而且之前用这种设计的单线串口通信产品已经量产,并且没有这个问题。所以在这个单线串口的设计中,STM32G0 要保持和 STM32L433 的配置一致,也就是上面提到的 GPIO 下拉,TX,RX 通过软件切换并且 TX,RX 电**向。 既然客户这么说,我们也没有证据直接证明这种方式有问题。只能回到问题本身继续分析,也就是分析究竟是谁把 STM32L433 发送端的起始位的电平拉低到 1.5v。为了进一步分析,建议客户在单线串口中间加一颗 100 欧姆的电阻,分别测量在出现问题时STM32G0 PA4 管脚和 STM32L433 PB10 管脚两端的电压变化。测量示意图如下图七 ![]() 图七 经过测量,发现 STM32G0端在 STM32L433端发送数据时,仍然保持低电平状态导致STM32L433 发送端起始位电平被异常拉低。如下图八黄色波形是 STM32G0 端测量的波形,绿色是 STM32L433 发送端测量出的波形。很明显可以观察到在 STM32L433 发送起始位和第一个数据位时,STM32G0 端 PA4 电平仍然为低,导致整根线电平被异常拉低。 ![]() 图八 从上面的现象分析看,显然跟 STM32G0 串口发送接收的时序有很大关系,推断是 STM32G0发送完数据切换为 RX 接收 STM32L433 数据时出现了问题。为了进一步验证,我们配置一个 GPIO 来指示 STM32G0 在发生数据帧错误时,TX 和 RX 切换的状态。如下图九,蓝色是 STM32L433 端测量的波形,绿色是 STM32G0 发送端测量出的波形。而中间的黄色则是 STM32G0 软件切换 TX,RX状态的波形。 从图九中可以很明显观察到 STM32L433 开始发送数据时,也就是 STM32G0 本应该要开始切换回接收状态的时候,STM32G0 软件还没来得及把 TX 切换到 RX 状态接收数据。到这里,我们可以分析出是 STM32G0 端在发送完数据切换为接收数据状态的动作太慢导致发送端起始位电压被拉低到 1.5v,从而导致数据帧错误。 ![]() 图九 4. 问题解决 既然找到了产生问题的原因,也就为我们解决问题提供了思路。问题的解决方法比较简单,我们查看客户 STM32G0 切换 TX,RX 部分代码,如下图十,发现在 TX 发送完中断处理函数中,要切换到 RX 接收状态还需要经过复杂的函数调用。后面建议客户在 TX 发送完成中断函数中直接修改 USART_CR2 寄存器的 SWAP 位完成切换到 RX。并且改用 DMA 收发数据。修改代码后,客户反馈波形得到改善,问题被解决。 ![]() 图十一 5. 小结 本篇笔记分享了怎么帮客户一步步分析解决一个客制化单线串口半双工通信帧错误问题的过程。后面也建议客户在后续的开发中如果使用到单线串口,建议参考 ST 官方 RM0444提供的方式。毕竟这种客制化使用单线串口的方式,并不是 ST 推荐的方式,需要客户自己验证其可靠性。 ———————————————— |