1. 无线传感器网络系统设计概述想象一下你需要在工厂车间部署几十个温湿度传感器或者在城市不同区域安装空气质量监测点。如果每个传感器都拉一条数据线回来不仅布线成本高后期维护更是噩梦。这时候基于STM32与Zigbee的无线传感器网络就能大显身手了。我去年做过一个农业大棚监测项目需要在200米×80米的区域内部署15个土壤温湿度传感器。最终采用的方案就是STM32F103C8T6作为终端节点控制器配合DL-22 Zigbee模块实现数据回传。实测下来这套方案有三大优势低功耗终端节点用纽扣电池能撑3个月抗干扰在满是金属支架的大棚里数据丢包率0.5%易扩展新增节点只需配置相同信道系统架构通常包含三类设备终端节点STM32传感器Zigbee模块负责数据采集路由节点可选Zigbee模块中继传输协调器节点STM32Zigbee模块作为数据汇聚点提示新手建议先从点对点通信开始等熟悉协议栈后再扩展为Mesh网络2. 硬件选型与电路设计2.1 核心器件选型要点选STM32型号时我踩过最大的坑就是串口数量。比如用F103C6只有2个USART而F103C8有3个。推荐配置发送端至少3个串口传感器、调试、Zigbee各占1个接收端至少2个串口Zigbee和调试这是我的器件清单表器件类型推荐型号关键参数STM32主控STM32F103C8T672MHz主频3×USARTZigbee模块DL-22或CC2530支持透传模式250kbps速率温湿度传感器DHT22或SHT30I2C/单总线接口颗粒物传感器PMS5003UART输出主动上传模式2.2 电路连接注意事项最近帮学员调试一个项目时发现Zigbee模块的电源设计很关键。建议给每个Zigbee模块单独加100μF钽电容串口TX/RX线要加1KΩ电阻做缓冲天线周围5mm内不要走其他信号线以STM32F103与DL-22连接为例// 串口3引脚配置 PB10(TX) - Zigbee_RX // PB11(RX) - Zigbee_TX GPIO_InitTypeDef GPIO_InitStructure; RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE); GPIO_InitStructure.GPIO_Pin GPIO_Pin_10; GPIO_InitStructure.GPIO_Mode GPIO_Mode_AF_PP; GPIO_InitStructure.GPIO_Speed GPIO_Speed_50MHz; GPIO_Init(GPIOB, GPIO_InitStructure); GPIO_InitStructure.GPIO_Pin GPIO_Pin_11; GPIO_InitStructure.GPIO_Mode GPIO_Mode_IN_FLOATING; GPIO_Init(GPIOB, GPIO_InitStructure);3. Zigbee模块配置实战3.1 透传模式参数设置DL-22模块出厂默认是广播模式要改为点对点模式需要发AT指令。这里有个坑必须等模块指示灯慢闪就绪状态才能配置成功。具体步骤用USB转TTL连接模块波特率设115200发送进入配置模式不要带回车收到a后快速发送以下指令ATDEST0x1234 # 目标地址 ATCH15 # 信道号11-26 ATNETID0x1122 # 网络ID ATUART115200,8,1,0 # 波特率配置注意两个通信的模块必须保证DEST地址互为对方且CH和NETID完全一致3.2 信号强度优化技巧在仓库环境测试时发现金属货架会导致信号衰减。通过实测总结出这些经验天线尽量垂直于地面模块离地高度1.2米时通信距离更远信道选择避开WiFi频段建议用15/20/25信道可以用ATRSSI指令查看信号强度值-60dBm信号优秀-60~-80dBm信号一般-80dBm需调整位置4. STM32程序设计精要4.1 多串口资源分配策略发送端的串口分工最容易搞混。以颗粒物传感器PMS5003为例USART1接PC串口助手用于调试输出USART2接传感器波特率9600USART3接Zigbee模块波特率115200关键点在于USART2的中断服务程序设计。我优化过的版本加入了超时机制#define BUF_SIZE 32 uint8_t sensorBuf[BUF_SIZE]; uint32_t lastRxTime 0; void USART2_IRQHandler(void) { static uint8_t idx 0; if(USART_GetITStatus(USART2, USART_IT_RXNE)) { uint8_t ch USART_ReceiveData(USART2); lastRxTime HAL_GetTick(); if(idx 0 ch ! 0x42) return; // 帧头校验 sensorBuf[idx] ch; if(idx BUF_SIZE) { processSensorData(sensorBuf); // 数据处理函数 USART3_Send(sensorBuf, BUF_SIZE); // 转发给Zigbee idx 0; } } } void checkTimeout() { if(HAL_GetTick() - lastRxTime 100 idx 0) { idx 0; // 超时重置接收状态 } }4.2 数据校验与纠错方案工业场景中电磁干扰严重我推荐采用双校验机制帧结构校验检查头尾标志如0x42 0x4DCRC校验计算数据段校验和以PM2.5传感器为例的校验函数bool validatePMSData(uint8_t *data) { // 帧头校验 if(data[0]!0x42 || data[1]!0x4D) return false; // 长度校验 uint16_t len (data[2]8) | data[3]; if(len ! 28) return false; // CRC校验 uint16_t crc (data[30]8) | data[31]; uint16_t sum 0; for(int i0; i30; i) sum data[i]; return crc sum; }5. 系统调试与性能优化5.1 常见故障排查指南上周有个学员遇到数据错乱问题最终发现是串口中断优先级配置不当。分享我的调试清单数据不全检查传感器供电是否稳定测量串口信号线电压TTL应为3.3V数据错位确认双方波特率一致在中断服务函数中加入临界区保护__disable_irq(); // 处理接收数据 __enable_irq();通信距离短用频谱仪查看信道干扰尝试降低波特率如从115200降到576005.2 低功耗设计技巧对于电池供电的场景这几个技巧很管用在HAL_UART_RxCpltCallback()中唤醒MCU设置Zigbee模块为休眠模式ATSLEEP1STM32用STOP模式仅保留串口唤醒功能实测电流对比工作模式平均电流全速运行23mA仅传感器唤醒1.8mA深度休眠50μA最后提醒部署前一定要做72小时压力测试。我在一个项目中发现连续运行后内存泄漏会导致系统崩溃后来通过增加看门狗和定期重启机制解决了问题。