手把手教你用STM32F103和DL-22 Zigbee模块搞定颗粒物传感器无线传输(附完整代码)

📅 2026/7/16 3:28:06 👁️ 阅读次数 📝 编程学习
手把手教你用STM32F103和DL-22 Zigbee模块搞定颗粒物传感器无线传输(附完整代码)

从零构建STM32与Zigbee的颗粒物监测无线系统

最近在帮学校实验室搭建环境监测网络时,发现传统有线传感器布线不仅麻烦,而且灵活性极差。于是尝试用STM32F103搭配DL-22 Zigbee模块实现无线传输,过程中踩了不少坑,也积累了些实战经验。本文将分享从硬件连接到代码调试的完整流程,特别适合刚接触嵌入式开发的新手。

1. 硬件准备与模块配置

1.1 设备清单与选型建议

手头需要准备以下核心组件(以我的实际配置为例):

  • 主控芯片:STM32F103VET6(发送端)/RCT6(接收端)
  • 无线模块:DL-22 Zigbee透传模块×2
  • 传感器:攀藤PMS5003颗粒物传感器
  • 调试工具:USB-TTL转换器、杜邦线若干

注意:不同型号STM32的串口引脚可能不同,建议提前查阅对应芯片的datasheet。我用的VET6有5个USART接口,而RCT6只有3个。

1.2 Zigbee模块工作模式配置

DL-22支持两种通信模式,通过AT指令切换:

模式类型特点适用场景
点对点需指定发送/接收端定向数据传输
广播所有模块同信道通信组网广播

建议按以下步骤配置点对点模式:

  1. 用USB-TTL连接电脑,打开串口调试助手
  2. 发送AT+MODE=P2P设置模式
  3. 发送端补充指令:AT+ROLE=TX
  4. 接收端补充指令:AT+ROLE=RX
  5. 双方设置相同信道:AT+CH=15
# 示例配置流程(发送端) AT+MODE=P2P AT+ROLE=TX AT+CH=15 AT+SAVE

2. 硬件连接与引脚分配

2.1 发送端接线方案

发送端需要同时连接传感器和Zigbee模块,具体引脚分配如下:

  • 传感器接口

    • USART2(PA2/PA3) - 传感器TX/RX
    • 5V - 传感器VCC
    • GND - 共地
  • Zigbee模块

    • USART3(PB10/PB11) - 模块TX/RX
    • 3.3V - 模块VCC
  • 调试接口

    • USART1(PA9/PA10) - USB-TTL(可选)

2.2 接收端简化设计

接收端只需处理Zigbee通信:

  • USART2(PA2/PA3) - Zigbee模块
  • USART1(PA9/PA10) - 上位机通信

实际接线时遇到过的问题:曾将传感器TX误接单片机TX导致通信失败,切记RX-TX需要交叉连接。

3. 核心代码实现解析

3.1 发送端中断处理逻辑

传感器数据接收的关键在于USART2的中断服务函数。以PMS5003传感器为例,其数据帧格式为:

0xFF 0x01 0x03 PM2.5_H PM2.5_L ...

对应中断处理代码:

#define DATA_LENGTH 10 uint8_t sensorBuffer[DATA_LENGTH]; volatile uint8_t dataFlag = 0; void USART2_IRQHandler(void) { static uint8_t count = 0; uint8_t byte = USART_ReceiveData(USART2); if(byte == 0xFF && count == 0) { sensorBuffer[count++] = byte; return; } if(count > 0 && count < DATA_LENGTH) { sensorBuffer[count++] = byte; // 完整帧校验 if(count == DATA_LENGTH && sensorBuffer[1] == 0x01) { uint16_t pm25 = (sensorBuffer[3]<<8) | sensorBuffer[4]; USART_SendData(USART3, pm25>>8); // 先发高字节 while(USART_GetFlagStatus(USART3, USART_FLAG_TXE) == RESET); USART_SendData(USART3, pm25); // 再发低字节 dataFlag = 1; count = 0; } } else { count = 0; // 异常重置 } }

3.2 接收端数据转发实现

接收端需要将Zigbee数据转发给上位机:

void USART2_IRQHandler(void) { static uint8_t buffer[2], index = 0; uint8_t byte = USART_ReceiveData(USART2); buffer[index++] = byte; if(index == 2) { uint16_t pm25 = (buffer[0]<<8) | buffer[1]; printf("PM2.5: %dug/m3\r\n", pm25); index = 0; } }

4. 调试技巧与性能优化

4.1 常见问题排查指南

根据实际调试经验,整理出以下问题排查表:

现象可能原因解决方案
无数据接收接线错误检查TX/RX交叉连接
数据乱码波特率不匹配确认所有设备波特率一致
通信不稳定电源干扰增加100uF电容滤波
丢包严重中断处理耗时优化ISR代码,避免复杂运算

4.2 中断服务优化建议

  1. 精简ISR代码:移除所有非必要操作,如:

    • 避免在中断内调用printf
    • 禁用浮点运算
    • 使用静态变量减少栈操作
  2. 双缓冲技术:创建ping-pong缓冲区提高吞吐量

typedef struct { uint8_t buf[2][DATA_LENGTH]; volatile uint8_t activeBuf; } DoubleBuffer; DoubleBuffer dbuff; void USART2_IRQHandler(void) { static uint8_t pos = 0; uint8_t byte = USART_ReceiveData(USART2); dbuff.buf[dbuff.activeBuf][pos++] = byte; if(pos >= DATA_LENGTH) { dbuff.activeBuf ^= 1; // 切换缓冲区 pos = 0; // 触发主循环处理非活跃缓冲区数据 } }

5. 系统扩展与进阶应用

5.1 多节点组网方案

通过修改Zigbee配置可实现星型网络:

  1. 设置一个协调器(Coordinator)
  2. 多个终端设备(End Device)连接传感器
  3. 使用广播模式传输数据
# 协调器配置 AT+MODE=BROADCAST AT+ROLE=COORD AT+CH=15

5.2 低功耗优化策略

对于电池供电场景:

  • 启用STM32的STOP模式
  • 配置传感器间歇工作
  • 优化Zigbee发射功率
void Enter_LowPowerMode(void) { RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR, ENABLE); PWR_EnterSTOPMode(PWR_Regulator_LowPower, PWR_STOPEntry_WFI); SystemInit(); // 唤醒后需重新初始化时钟 }

实际部署时发现,通过合理设置采样间隔(如5分钟一次),可使系统续航从1天提升至2周以上。