EFR32MG21模组(Zigbee)与STM32单片机通信
EFR32MG21模组(Zigbee)与STM32单片机通信
介绍: 通过本次的通信可以实现单片机通过Zigbee控制开关设备,比如zigbee智能开关,智能插座,以及模拟量的数据上传
- EFR32 是 Silicon Labs 面向物联网的低功耗多协议无线 SoC系列,基于 ARM Cortex‑M3/M33 内核,覆盖 Sub‑GHz 与 2.4 GHz 频段,支持 ZigBee、Thread、BLE、Matter 等协议,广泛应用于智能家居、工业自动化、智能能源等领域。
1、本次主要是单片机与通信文档的一个初步的解析
也就是针对这片文章的开关示例的简单的分析
2、主要分协议内容以及协议的分析

{uint8_t buf[32];uint8_t len = 0;buf[len++] = 0xFE;buf[len++] = 0x0B;buf[len++] = 0x02;buf[len++] = 0x01;buf[len++] = 0x02;buf[len++] = 0x00;buf[len++] = 0x00;buf[len++] = 0x00;buf[len++] = 0x04;buf[len++] = seconds;buf[len] = ZigBee_CalcChecksum(buf, len);USART2_SendBuffer(buf, len + 1);Serial_Printf("打开网络允许入网,时长=%d 秒\r\n", seconds);
}
进行开网的数据发送,然后通过中断获取数据帧
串口调试助手进行实时的打印数据进行监控
遇到问题
进行获取端点数据的发送
//获取端点数据
void Zigbee_QueryEndpoint(uint16_t shortAddr)
{uint8_t buf[32];uint8_t len = 0;buf[len++] = 0xFE;buf[len++] = 0x0A;buf[len++] = 0x02;buf[len++] = 0x03;buf[len++] = 0x02;buf[len++] = (uint8_t)(shortAddr & 0xFF);buf[len++] = (uint8_t)(shortAddr >> 8);buf[len++] = 0x00;buf[len++] = 0x05;buf[len] = ZigBee_CalcChecksum(buf, len);USART2_SendBuffer(buf, len + 1);Serial_Printf("查询端点\r\n");
}
且重复读取中断点
- 解决办法,清零
进行修改
修改之后再次进行调试
打印结果正确
获取到设备第二条响应
此时会获取到错误帧,注意看手册 02 83 的数据帧为正确,03 83 为错误
查询设备成功
if((ZigBeeGetData.RxBuf[2]==0X02) && (ZigBeeGetData.RxBuf[3]==0X43))//获取设备端点的响应{Serial_Printf("查询端点的第1条响应\r\n");memset(ZigBeeGetData.RxBuf,0,ZigBeeGetData.Rx_count);ZigBeeGetData.Rx_count = 0;ZigBeeGetData.Rx_over = 0;while(ZigBeeGetData.Rx_over==0);if(ZigBeeGetData.Rx_over == 1){if((ZigBeeGetData.RxBuf[2]==0X02) && (ZigBeeGetData.RxBuf[3]==0X83))//获取设备端点的响应{Serial_Printf("查询端点的第2条响应\r\n");if((Zigbee_AddState ==Z_AddLemp)&&(ZigBeeGetData.RxBuf[2]==0X02)){Z_DeviceLib.Dev[ZigBeeAddNem].Device_Num = ZigBeeGetData.RxBuf[10];for(int i=0;i<ZigBeeGetData.RxBuf[10];i++){Z_DeviceLib.Dev[ZigBeeAddNem].Device_list[i]= ZigBeeGetData.RxBuf[11+i];}flag_zigbee0=1;Zigbee_AddState = GetType;LED1_OFF();
// Serial_Printf("----跳出循环----"); }} }}
- 进行查询端点的所有服务
获取端点服务成功
- 第二条回应的数据帧
进行开关的控制状态
发送状态转换的0x02
这里需要注意的是传入的参数,是终端设备的短地址,每次连接都不一样,
void Zigbee_Switch(uint16_t shortAddr,uint16_t endpoint,uint16_t status)
{uint8_t buf[32];uint8_t len = 0;buf[len++] = 0xFE;buf[len++] = 0x0B;buf[len++] = 0x05;buf[len++] = 0x01;buf[len++] = 0x02;buf[len++] = (uint8_t)(shortAddr&0xFF);buf[len++] = (uint8_t)(shortAddr>>8);buf[len++] = (uint8_t)(endpoint);buf[len++] = 0x0A; //帧序列号buf[len++] = status; //属性值buf[len] = ZigBee_CalcChecksum(buf, len); USART2_SendBuffer(buf, len + 1);Serial_Printf("已发送改变开关状态\r\n");
}
最后完成对开关状态的获取
整体流程已实现
注意事项;硬件烧录次数超过5次之后,建议需要重新上电启动,不然串口打印会出现错误