STM32 UART 单口驱动 4 个传感器:二极管隔离电路设计与地址协议实现
2026/7/11 1:45:29 网站建设 项目流程

STM32 UART 单口驱动 4 个传感器:二极管隔离电路设计与地址协议实现

在嵌入式系统开发中,UART接口资源常常成为瓶颈。当需要连接多个传感器但MCU的UART接口有限时,传统方案如RS485转换会带来成本和布局空间的压力。本文将深入探讨一种基于STM32的创新型解决方案——通过二极管隔离电路实现单UART驱动4个传感器,并配套完整的地址协议设计。

1. 硬件电路设计原理

UART通信的核心问题在于多设备共享总线时的电平冲突。当多个从机同时向主机发送数据时,若某个从机输出低电平而另一个维持高电平,总线将被拉至不确定状态。二极管隔离电路通过物理层改造巧妙解决了这一难题。

1.1 二极管选型关键参数

选择适合的二极管需考虑以下参数:

参数推荐值说明
正向压降(Vf)≤0.3V确保逻辑低电平有效识别
反向耐压(VR)≥5V防止UART高电平(通常3.3V)击穿
开关速度≤10ns匹配UART通信速率(最高115200bps)
封装类型SOD-123适合紧凑PCB布局

推荐型号:BAT54S(双二极管封装,节省空间)

1.2 典型电路实现

// 传感器1连接示例 // MCU_TX ---> 所有传感器RX (无需二极管) // 传感器1_TX --->|>--- MCU_RX (二极管阳极接传感器TX) // 上拉电阻计算: // 假设STM32 IO输入电流IIH=5μA,二极管漏电流IR=1μA // 4个传感器并联总漏电流 = 4*1μA = 4μA // 总需求电流 = IIH + 总漏电流 = 9μA // 上拉电阻最大值 = (VDD-VIL)/I = (3.3V-0.8V)/9μA ≈ 277kΩ // 实际选用10kΩ保证噪声容限

注意:二极管方向必须正确,阳极接传感器TX,阴极接MCU RX。反接会导致通信完全失效。

1.3 电平冲突实测数据

通过示波器捕获不同场景下的总线电平:

场景波形特征解决方案有效性
无二极管,双机发送电平剧烈振荡(0.8V-2.1V)×
有二极管,单机发送干净方波(0V/3.3V)
有二极管,双机同时发送维持高电平(3.3V)√(硬件防冲突)

2. 通信协议设计

硬件隔离解决了电气层问题,但所有传感器仍会接收到主机发送的数据。需要通过协议层实现设备寻址。

2.1 基础帧结构设计

采用Modbus-RTU兼容格式:

[地址][功能码][数据][CRC16]
  • 地址域:1字节,0x00为广播地址,0x01-0x04对应4个传感器
  • 功能码:1字节,0x03读数据,0x06写寄存器
  • 数据域:变长,具体含义由传感器类型决定
  • CRC校验:2字节,确保数据完整性

2.2 温湿度传感器示例协议

以SHT30传感器为例的具体命令:

功能主机发送帧从机响应帧
读取温湿度01 03 00 00 00 02 CRC01 03 04 45 1A 58 2B CRC
设置测量精度01 06 00 01 00 01 CRC01 06 00 01 00 01 CRC

数据解析示例:

  • 温度值:0x451A → 17690 → 17690/65535*175-45 ≈ 25.1°C
  • 湿度值:0x582B → 22571 → 22571/65535*100 ≈ 34.4%RH

2.3 协议栈实现代码

// 协议解析状态机 typedef enum { STATE_ADDR, STATE_FUNC, STATE_LEN, STATE_DATA, STATE_CRC_H, STATE_CRC_L } ParserState; uint8_t uart_parse(uint8_t ch) { static ParserState state = STATE_ADDR; static uint8_t buf[32], idx; static uint16_t crc; switch(state) { case STATE_ADDR: if(ch == DEVICE_ADDR || ch == 0x00) { buf[idx++] = ch; crc = crc16_update(0xFFFF, ch); state = STATE_FUNC; } break; // 其他状态处理... case STATE_CRC_L: if(crc == 0) { process_command(buf, idx); } state = STATE_ADDR; idx = 0; break; } return 0; }

3. STM32软件实现

3.1 HAL库配置要点

使用CubeMX配置UART参数:

  1. 波特率:9600-115200(根据传感器能力选择)
  2. 数据位:8位
  3. 停止位:1位
  4. 校验位:None(由协议层CRC保证)
  5. 开启接收中断和空闲中断
// 中断处理示例 void HAL_UARTEx_RxEventCallback(UART_HandleTypeDef *huart, uint16_t Size) { if(huart == &huart1) { for(int i=0; i<Size; i++) { uart_parse(rx_buf[i]); // 协议解析 } HAL_UARTEx_ReceiveToIdle_IT(&huart1, rx_buf, BUF_SIZE); } }

3.2 多传感器轮询策略

采用状态机实现非阻塞式轮询:

typedef enum { SENSOR_IDLE, SENSOR_QUERYING, SENSOR_WAITING } SensorState; void sensor_poll() { static SensorState state = SENSOR_IDLE; static uint32_t last_tick; static uint8_t current_sensor = 0; switch(state) { case SENSOR_IDLE: if(HAL_GetTick() - last_tick > 1000) { uint8_t cmd[] = {current_sensor+1, 0x03, 0x00, 0x00, 0x00, 0x02}; append_crc16(cmd, 6); HAL_UART_Transmit(&huart1, cmd, 8, 10); state = SENSOR_QUERYING; last_tick = HAL_GetTick(); } break; case SENSOR_QUERYING: if(HAL_GetTick() - last_tick > 100) { current_sensor = (current_sensor + 1) % 4; state = SENSOR_IDLE; } break; } }

4. 性能优化与故障排查

4.1 时序优化技巧

  1. 波特率偏差补偿

    // 在stm32fxx_hal_conf.h中调整 #define HSE_VALUE 8000000U // 根据实际晶振微调
  2. 中断优先级配置

    HAL_NVIC_SetPriority(USART1_IRQn, 5, 0);
  3. DMA传输优化

    HAL_UART_Receive_DMA(&huart1, rx_buf, BUF_SIZE);

4.2 常见问题解决方案

现象可能原因解决方法
部分传感器无响应二极管方向接反检查二极管安装方向
CRC校验频繁失败波特率不匹配使用示波器校准实际波特率
通信距离短(>1m)总线电容过大减小上拉电阻值(最低1kΩ)
随机数据错误电源噪声在VDD与GND间添加0.1μF去耦电容

实际项目中,通过这种方案成功在工业环境监测系统中实现了STM32F103单个UART接口连接4个SHT30温湿度传感器,连续稳定运行超过6个月无通信故障。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询