用STM32F103ZET6的5个串口做个简易多路数据采集器:搭配按键和LED的状态反馈

张开发
2026/4/17 18:13:27 15 分钟阅读

分享文章

用STM32F103ZET6的5个串口做个简易多路数据采集器:搭配按键和LED的状态反馈
STM32F103ZET6五串口数据采集器实战从硬件配置到多传感器融合项目背景与核心思路在工业控制、环境监测和智能家居等领域多路数据采集是常见需求。STM32F103ZET6凭借其丰富的外设资源特别是五个独立的串口接口成为构建经济型多路采集系统的理想选择。不同于简单的串口配置教程本文将带您实现一个具备状态反馈的完整数据采集系统通过按键触发采集、LED指示状态并支持多路传感器数据融合处理。这个项目的独特价值在于资源最大化利用充分发挥STM32F103ZET6五个串口的并行处理能力交互可视化通过LED和按键实现本地状态监控与控制模块化设计代码结构清晰便于扩展更多功能模块实战导向包含异常处理、数据校验等工程实践细节1. 硬件架构设计1.1 核心硬件选型与连接STM32F103ZET6的五个串口引脚分配如下表所示串口TX引脚RX引脚时钟总线最大速率USART1PA9PA10APB24.5MbpsUSART2PA2PA3APB12.25MbpsUSART3PB10PB11APB12.25MbpsUART4PC10PC11APB12.25MbpsUART5PC12PD2APB12.25Mbps推荐外围电路设计每个串口添加120Ω终端电阻抑制信号反射TX线路串联100Ω电阻保护IO口在RX引脚对地接4.7kΩ上拉电阻提高抗干扰能力使用TVS二极管防护ESD事件1.2 传感器接口规划为每个串口分配特定类型的传感器模块typedef enum { UART1_GPS 0, UART2_TEMP_HUMIDITY, UART3_BLUETOOTH, UART4_PM2_5, UART5_CUSTOM } UART_DeviceType;典型接线示例USART1连接NEO-6M GPS模块获取位置信息USART2连接SHT30温湿度传感器采集环境数据USART3连接HC-05蓝牙模块实现无线数据传输UART4连接激光PM2.5传感器监测空气质量UART5作为预留接口可扩展其他传感器2. 软件框架搭建2.1 基础驱动层实现采用分层设计架构首先完成底层驱动封装// 串口初始化结构体 typedef struct { USART_TypeDef* USARTx; uint32_t baudrate; GPIO_TypeDef* GPIO_TX_Port; uint16_t GPIO_TX_Pin; GPIO_TypeDef* GPIO_RX_Port; uint16_t GPIO_RX_Pin; uint8_t IRQ_Priority; } UART_Config_t; // 初始化函数原型 void UART_Init(const UART_Config_t* config); void UART_SendData(USART_TypeDef* USARTx, uint8_t* data, uint16_t len); uint16_t UART_ReceiveData(USART_TypeDef* USARTx, uint8_t* buffer);关键配置要点使用DMA传输减轻CPU负担为每个串口设置独立的接收缓冲区实现环形缓冲区管理数据流添加硬件流控制支持CTS/RTS2.2 多任务调度策略针对五种传感器数据设计两种采集模式轮询模式适合低速传感器void Sensor_PollingTask(void) { static uint8_t current_uart 0; switch(current_uart) { case 0: Read_GPS_Data(); break; case 1: Read_TempHumidity(); break; // ...其他传感器 } current_uart (current_uart 1) % 5; }中断模式适合实时性要求高的场景void USART1_IRQHandler(void) { if(USART_GetITStatus(USART1, USART_IT_RXNE)) { uint8_t data USART_ReceiveData(USART1); GPS_ParseByte(data); // 实时解析GPS数据 } }3. 人机交互实现3.1 按键控制逻辑利用开发板上的三个按键实现多功能控制按键功能描述触发动作KEY0单次采集所有传感器短按(1s)KEY1切换采集模式轮询/中断长按(2s)KEY2进入低功耗模式双击按键消抖实现代码#define KEY_DEBOUNCE_TIME 20 // 消抖时间(ms) uint8_t Key_Scan(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin) { static uint8_t key_state 0; if(GPIO_ReadInputDataBit(GPIOx, GPIO_Pin) 0) { // 按键按下 delay_ms(KEY_DEBOUNCE_TIME); if(GPIO_ReadInputDataBit(GPIOx, GPIO_Pin) 0) { if(key_state 0) { key_state 1; return 1; // 有效按键 } } } else { key_state 0; } return 0; // 无按键 }3.2 LED状态指示设计利用两个LED实现丰富的状态反馈LED0状态表常亮系统正常运行慢闪(1Hz)数据采集中快闪(5Hz)通信异常熄灭系统休眠LED1模式指示点亮中断采集模式熄灭轮询采集模式void LED_UpdateSystemStatus(SystemStatus_t status) { switch(status) { case SYS_NORMAL: LED0_ON(); break; case SYS_BUSY: LED0_Blink(500); // 500ms间隔 break; case SYS_ERROR: LED0_Blink(200); // 200ms快闪 break; case SYS_SLEEP: LED0_OFF(); break; } }4. 数据协议与错误处理4.1 自定义通信协议设计统一的数据帧格式确保各传感器数据兼容帧头(2B) | 设备ID(1B) | 数据长度(1B) | 数据(NB) | CRC16(2B) | 帧尾(2B) 0x5AA5 | 0x01-0x05 | 0x00-0xFF | ... | | 0x0D0ACRC校验实现uint16_t Calculate_CRC16(uint8_t *data, uint16_t length) { uint16_t crc 0xFFFF; while(length--) { crc ^ *data; for(uint8_t i0; i8; i) { if(crc 0x0001) { crc 1; crc ^ 0xA001; } else { crc 1; } } } return crc; }4.2 异常处理机制建立多级错误防护体系物理层硬件看门狗定时器IWDG_WriteAccessCmd(IWDG_WriteAccess_Enable); IWDG_SetPrescaler(IWDG_Prescaler_256); // 约1s超时 IWDG_SetReload(0xFFF); IWDG_Enable();数据链路层帧超时检测每帧不超过500ms数据长度校验CRC校验失败重传机制应用层传感器数据合理性检查异常数据标记与过滤错误计数器自动复位5. 系统优化与扩展5.1 性能提升技巧内存优化策略使用__packed关键字减少结构体填充按需分配缓冲区大小启用编译器优化选项-O2实时性保障措施// 在RTOS中合理设置任务优先级 #define TASK_PRIORITY_SENSOR (osPriorityHigh) #define TASK_PRIORITY_COMM (osPriorityNormal) #define TASK_PRIORITY_UI (osPriorityLow)5.2 功能扩展方向无线传输扩展通过蓝牙模块上传数据到手机APP添加Wi-Fi模块连接云平台本地存储方案// SPI Flash存储示例 void SaveToFlash(uint8_t* data, uint16_t len) { SPI_FLASH_WriteBuffer(data, FLASH_ADDR, len); }高级功能数据压缩算法减少传输量动态调整采样率传感器自动识别实战调试经验在实际开发中有几个容易忽视的细节值得注意串口电平匹配部分3.3V传感器需电平转换才能与5V设备通信中断冲突当多个串口同时使用中断时合理分配优先级电源噪声模拟传感器建议使用LDO单独供电接地环路所有传感器共地避免电位差导致数据异常一个典型的调试案例当GPS模块与蓝牙模块同时工作时发现蓝牙数据传输不稳定。最终发现是GPS模块的1PPS脉冲信号引起电源波动通过在蓝牙模块VCC端添加100μF电容解决问题。

更多文章