【嵌入式软件】STM32 UART转485通信问题

1.背景

在原来的文章中,已经测试了RS485的电路

【嵌入式】RS485通信+硬件

经过多次测试,没有问题。

但是在通信的过程中,偶尔会发生错误。

2.问题集合

2.1通信错位问题

2.1.1 问题描述

最近某台设备采用的MODBUS协议,返回的数据格式应该是

复制代码
1 3 4 ef 8e 0 f ee ac

但是实际收到的数据是:

复制代码
ee 1 3 4 ef 8e 0 f ee

上面的数据出现了数据错位

2.1.2 解决方法

1)首先要保证uart的rx引脚配置为上拉,不要外接下拉电阻;因为uart的通信起始位 是低电平开始,可能会导致数据判断错误;

2)rs485为半双工通信,在数据发送结束后,需要等待一段时间后再去接收数据;

这是因为,虽然uart已经发送完成了,但是485驱动器还需要切换电平,硬件缓冲区可能已清空,但驱动器可能还需要一点时间将最后一个位完全驱动到总线上。立即切换可能导致最后一个位被截断。这个延迟通常需要至少 1 个字符的传输时间(例如,对于 115200bps,1 个字符 10 位:10 / 115200 ≈ 87us)。更保守的做法是等待 2-3 个字符时间。可以使用简单的 for循环延时或定时器实现。

3)程序处理框架

复制代码
HAL_StatusTypeDef RS485_SendData(uint8_t *pData, uint16_t Size, uint32_t Timeout) {
    HAL_StatusTypeDef status;

    RS485_DIR_TX(); // 切换到发送模式

    status = HAL_UART_Transmit(&huart1, pData, Size, Timeout); // 阻塞发送

    if (status == HAL_OK) {
        // 等待发送寄存器真正空 (TC 标志)
        while (__HAL_UART_GET_FLAG(&huart1, UART_FLAG_TC) == RESET) {}

        // 关键延迟:等待最后一个位完全发出 (至少 1 个字符时间)
        // 这里使用简单的循环延时,实际应用中建议使用定时器或计算精确时间
        volatile uint32_t delay = SystemCoreClock / 1000000 * 100; // 大约 100us 延时 (根据你的波特率调整!)
        while (delay--);
    }

    RS485_DIR_RX(); // 切换回接收模式 (无论发送成功与否)

    return status;
}

// 接收数据函数 (与普通 UART 接收一样)
HAL_StatusTypeDef RS485_ReceiveData(uint8_t *pData, uint16_t Size, uint32_t Timeout) {
    return HAL_UART_Receive(&huart1, pData, Size, Timeout);
}

2.1.3 要点

1)切换时机是核心:​​ 过早切换回接收模式会截断自己发送的数据;过晚切换会错过总线上的响应或增加总线冲突风险。​发送完成后的延迟至关重要。

2)延迟计算:​​ 延迟时间需要根据你的波特率计算。例如

(1)波特率 9600bps:1 位时间 ≈ 104us,1 个字符 (10 位:1 起始 + 8 数据 + 1 停止) ≈ 1.04ms。延迟建议 > 1.04ms。

(2)波特率 115200bps:1 位时间 ≈ 8.68us,1 个字符 ≈ 86.8us。延迟建议 > 87us。

(3)使用 HAL_Delay()进行毫秒级延迟通常足够,但对于高波特率,需要更精确的微秒级延迟(如定时器或 DWT计数器)。

相关推荐
国科安芯4 小时前
立方星与微纳卫星综合电子微型化趋势下的抗辐射MCU选型综述
人工智能·单片机·嵌入式硬件·mcu·risc-v·抗辐射
xunyan62344 小时前
3-1 独立按键控制LED亮灭(SDCC + Notepad++ + STC-ISP/普中ISP)
单片机·嵌入式硬件·接口隔离原则
WD137298015575 小时前
WD5030L,为充电桩、工业设备、5G 基站、车载系统、消费电子提供电源,7-30V 的宽压输入
stm32·单片机·嵌入式硬件·5g·车载系统·51单片机
创界工坊工作室7 小时前
30-基于STM32的小麦烘干塔温度控制系统设计
stm32·单片机·嵌入式硬件·proteus
Zwawa8 小时前
先把轮子转稳,才不会烧心:编码器速度环 PID 怎么接回 PWM
c语言·单片机·嵌入式
单片机仿真设计8 小时前
【proteus仿真设计】基于 STM32 的开荒机器人遥控控制系统设计(仿真图+程序)
stm32·嵌入式硬件·机器人·proteus
smartpi_ai8 小时前
51 单片机写好了,大模型语音怎么接?17T 全驱动的现成方案、双板串口分工的边界与画板前的三项硬件确认
单片机·嵌入式硬件·学习
我先去打把游戏先9 小时前
NimBLE是什么-ESP32蓝牙协议栈详解
单片机·嵌入式硬件·ubuntu
木子n110 小时前
车载以太网与SOME/IP服务化通信实战-02.状态机与订阅:SOME/IP-SD的三态迁移、重传账与上电风暴
嵌入式硬件·网络协议·车载系统·车载以太网·some/ip
Gongsion10 小时前
30V输入耐压|1.5μA超低静态电流|200mA输出,CSM52系列:线性稳压器LDO,12V母线转3.3V/5V传感器、MCU弱电支路可靠稳压方案
单片机·嵌入式硬件·车载系统·无人机·智能家居