【嵌入式软件】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计数器)。

相关推荐
萧技电创EIIA5 小时前
基于wifi摄像头与单片机的串口透传及二次开发
单片机·51单片机·硬件工程·个人开发
三佛科技-134163842125 小时前
迷你加湿器方案开发,加湿器/香薰机MCU控制方案开发设计
单片机·嵌入式硬件·智能家居·pcb工艺
hazy1k5 小时前
51单片机基础-矩阵按键
嵌入式硬件·矩阵·51单片机
一支闲人6 小时前
带你了解STM32:SPI通信(硬件部分)
stm32·单片机·嵌入式硬件·基础知识
我先去打把游戏先8 小时前
VSCode通过SSH连接到Ubuntu虚拟机失败“找不到ssh安装”问题解决
笔记·vscode·单片机·嵌入式硬件·学习·ubuntu·ssh
XiangrongZ8 小时前
江协科技STM32课程笔记(三)—定时器TIM(输出比较)
笔记·科技·stm32
学工科的皮皮志^_^11 小时前
电压源和电流源学习理解
单片机·嵌入式硬件·学习
linweidong12 小时前
跨平台驱动开发:打造兼容多款MCU的硬核方案
驱动开发·单片机·嵌入式硬件·bsp·rtos·spi驱动·hal设计
易享电子13 小时前
基于单片机大棚浇水灌溉控制系统Proteus仿真(含全部资料)
单片机·嵌入式硬件·fpga开发·51单片机·proteus