2025年STM32G031无线温湿度仪开源项目 -4,Zigbee模块(DRF1609H)的初始化

STM32G031无线温湿度仪开源项目 -4,Zigbee模块(DRF1609H)的初始化关键词 CubeMX CubeIDE STM32G031C8T AHT10 DRF1609H 本项目的全部源码资料下载 本项目中使用了 Zigbee 模块 DRF1609H 作为无线数据传输使用 初始化 DRF1609H 主要涉及以下几个方面的内容

大家好,我是讯享网,很高兴认识大家。

关键词:CubeMX,CubeIDE,STM32G031C8T6,AHT10,DRF1609H

本项目的全部源码资料下载

本项目中使用了Zigbee模块(DRF1609H),作为无线数据传输使用,初始化DRF1609H主要涉及以下几个方面的内容:
1,设置节点的类型,可以设置为:Router、End Device。Zigbee网络有3种类型的节点:Coordinator、Router、End Device,Cordinator接在电脑上面收集数据,我们这里是采集节点,所以只设置为Router或End Device。
2,检测节点是否加入了网络
3,如果节点没有加入网络,则启动自动扫描加入网络

1,节点类型的设置:

首先读取DRF1609H的参数:G031向DRF1609H发送读取参数指令,发完参数后,有一个500MS的超时等待参数的回复,参数回复总共是53个字节,放在receiveConfigData里面。

 //--Read DRF1609H Configures -- drf1609h_readModule(); HAL_UART_Receive( &huart1, receivedConfigData, 53, 500 ); 

讯享网
讯享网//------------------------------ void drf1609h_readModule(void) { drf1609h_sendedIns = sendIns_read; HAL_UART_Transmit_DMA( &huart1, readIns, 9 ); } 

读取参数完成后,把读取到的参数整理后放入drf1609这个结构体中:以后取用的时候就非常方便了,建议用户不要改这部分代码,直接拷贝使用就好了。

 //---If DRF1609H Error or Read Error ------ while( readParameterProcess(receivedConfigData, 53) == 0 ) { drf1609h_readModule(); HAL_UART_Receive( &huart1, receivedConfigData, 53, 500 ); } 
讯享网//------------------------------ uint8_t readParameterProcess(uint8_t *inputData, uint16_t inputLen) { uint8_t result=0; uint8_t tempXY=0; uint8_t tempRight=0; uint8_t i=0; tempXY = getXY(inputData, inputLen); if(inputData[0]==0xFA) { tempRight++; } if(inputData[1]==0x31) { tempRight++; } if(inputData[2]==0x0A) { tempRight++; } if(inputData[inputLen-1]==tempXY) { tempRight++; } if(tempRight==4) { //------ drf1609.pointType = inputData[readHeaderLen +0]; drf1609.PAN_ID = inputData[readHeaderLen +1]*256 + inputData[readHeaderLen +2]; drf1609.Channel = inputData[readHeaderLen +3]; drf1609.transferModel = inputData[readHeaderLen +4]; drf1609.userAddress = inputData[readHeaderLen +5]*256 + inputData[readHeaderLen +6]; drf1609.X7X8 = inputData[readHeaderLen +7]*256 + inputData[readHeaderLen +8]; drf1609.uartBraudRate = inputData[readHeaderLen +9]; drf1609.uartDataBits = inputData[readHeaderLen +10]; drf1609.uartStopBits = inputData[readHeaderLen +11]; drf1609.uartParity = inputData[readHeaderLen +12]; drf1609.X13X14 = inputData[readHeaderLen +13]*256 + inputData[readHeaderLen +14]; drf1609.antennaSelect = inputData[readHeaderLen +15]; //------- for(i=0; i<8; i++) { drf1609.macAddress[i] = inputData[readHeaderLen +16 +i]; } //-------- drf1609.prePointType = inputData[readHeaderLen +24]; drf1609.prePAN_ID = inputData[readHeaderLen +25]*256 + inputData[readHeaderLen +26]; drf1609.preChannel = inputData[readHeaderLen +27]; drf1609.preTransferModel = inputData[readHeaderLen +28]; drf1609.preUserAddress = inputData[readHeaderLen +29]*256 + inputData[readHeaderLen +30]; drf1609.X31X32 = inputData[readHeaderLen +31]*256 + inputData[readHeaderLen +32]; drf1609.preUartBraudRate = inputData[readHeaderLen +33]; drf1609.preUartDataBits = inputData[readHeaderLen +34]; drf1609.preUartStopBits = inputData[readHeaderLen +35]; drf1609.preUartParity = inputData[readHeaderLen +36]; drf1609.X37X38 = inputData[readHeaderLen +37]*256 + inputData[readHeaderLen +38]; drf1609.preAntennaSelect = inputData[readHeaderLen +39]; //----------- drf1609.shortAddress = inputData[readHeaderLen +40]*256 + inputData[readHeaderLen +41]; drf1609.X42 = inputData[readHeaderLen +42]; drf1609.isSecurity = inputData[readHeaderLen +43]; for(i=0; i<4; i++) { drf1609.securityCode[i] = inputData[readHeaderLen +44 +i]; } result =1; } return result; } 

接着比较读出来的节点类型与要设置的节点类型是否一致,如果不一致的话,就重新写入要设置的节点类型:

 if( drf1609H_setPontType != drf1609H_readPointType ) 

写的过程:
1,产生写入参数
2,写入
3,接收回复的参数,看看写入是否正确

讯享网 getWriteIns(drf1609); drf1609h_writeModule(); HAL_UART_Receive( &huart1, receivedConfigData, 5, 500 ); 

写入正确以后,则重启模块(注意:DRF1609H的写入参数生效,都需要重启),这里是用一个IO口,控制DRF1609H的RESET脚拉低重启。


讯享网

if( is_InsBack(receivedConfigData, 5) ) { if(receivedConfigData[2] == 0x0A) { drf1609h_reset(); HAL_Delay(2000); drf1609h_status = drf1609h_powerOn; } else { errorStart=1; } } else { errorStart=1; } 

需要注意的是,getWriteIns(drf1609),这个函数是把drf1609结构体,直接变换成写入指令,建议用户不要修改这部分,直接拷贝使用

讯享网//--------------------------------------------------- void getWriteIns(_zigbeeParameters inputParameter) { uint8_t i=0; uint8_t tempXY=0; writeIns[0]= 0xFC; writeIns[1]= 0x27; writeIns[2]= 0x07; writeIns[writeHeaderLen +0]= inputParameter.pointType; writeIns[writeHeaderLen +1]= (inputParameter.PAN_ID & 0xFF00)>>8; writeIns[writeHeaderLen +2]= inputParameter.PAN_ID & 0x00FF; writeIns[writeHeaderLen +3]= inputParameter.Channel; writeIns[writeHeaderLen +4]= inputParameter.transferModel; writeIns[writeHeaderLen +5]= (inputParameter.userAddress & 0xFF00)>>8; writeIns[writeHeaderLen +6]= inputParameter.userAddress & 0x00FF; writeIns[writeHeaderLen +7]= (inputParameter.X7X8 & 0xFF00)>>8; writeIns[writeHeaderLen +8]= inputParameter.X7X8 & 0x00FF; writeIns[writeHeaderLen +9]= inputParameter.uartBraudRate; writeIns[writeHeaderLen +10]= inputParameter.uartDataBits; writeIns[writeHeaderLen +11]= inputParameter.uartStopBits; writeIns[writeHeaderLen +12]= inputParameter.uartParity; writeIns[writeHeaderLen +13]= (inputParameter.X13X14 & 0xFF00)>>8; writeIns[writeHeaderLen +14]= inputParameter.X13X14 & 0x00FF; writeIns[writeHeaderLen +15]= inputParameter.antennaSelect; writeIns[writeHeaderLen +16]= inputParameter.prePointType; writeIns[writeHeaderLen +17]= (inputParameter.prePAN_ID & 0xFF00)>>8; writeIns[writeHeaderLen +18]= inputParameter.prePAN_ID & 0x00FF; writeIns[writeHeaderLen +19]= inputParameter.preChannel; writeIns[writeHeaderLen +20]= inputParameter.preTransferModel; writeIns[writeHeaderLen +21]= (inputParameter.preUserAddress & 0xFF00)>>8; writeIns[writeHeaderLen +22]= inputParameter.preUserAddress & 0x00FF; writeIns[writeHeaderLen +23]= (inputParameter.X31X32 & 0xFF00)>>8; //--AS ReadParameter's X31 X32 writeIns[writeHeaderLen +24]= inputParameter.X31X32 & 0x00FF; //--AS ReadParameter's X31 X32 writeIns[writeHeaderLen +25]= inputParameter.preUartBraudRate; writeIns[writeHeaderLen +26]= inputParameter.preUartDataBits; writeIns[writeHeaderLen +27]= inputParameter.preUartStopBits; writeIns[writeHeaderLen +28]= inputParameter.preUartParity; writeIns[writeHeaderLen +29]= (inputParameter.X37X38 & 0xFF00)>>8; //--AS ReadParameter's X37 X38 writeIns[writeHeaderLen +30]= inputParameter.X37X38 & 0x00FF; //--AS ReadParameter's X37 X38 writeIns[writeHeaderLen +31]= inputParameter.preAntennaSelect; writeIns[writeHeaderLen +32]= 0x1; writeIns[writeHeaderLen +33]= inputParameter.isSecurity; for(i=0; i<4; i++) { writeIns[writeHeaderLen +34 +i]= inputParameter.securityCode[i]; } tempXY = getXY(writeIns, writeInsLen); writeIns[writeInsLen-1]= tempXY; } 

2,检测节点是否加入网络

检测节点是否加入网络,我们这里使用了读取DRF1609H节点信号强度指令,如果读取信号强度成功(回复的数据是正确的),则表明DRF1609H已经加入了网络并且与Coordinator通讯正常。
这个函数用来检测DRF1609H是否加入了网络,加入则回复1,没有则回复0:
注意:这里是检测10次,没有加入也回复1,主要考虑在低功耗情况下,如果Coordinator没有开机,如果节点一直检测,则对耗电不利,用户应根据实际情况修改使用。

uint8_t drf1609h_isJoinedNet() 
讯享网//---------------------- uint8_t drf1609h_isJoinedNet() { uint8_t result=0; uint8_t i=0; //MX_USART1_UART_Init(); //HAL_Delay(10); for(i=0; i<8; i++) { receivedSignalData[i]=0; } drf1609h_requestSignalIndex(); HAL_UART_Receive( &huart1, receivedSignalData, 8, 500 ); HAL_Delay(1000); if( checkSignalData(receivedSignalData, 8) ) { result=1; receivedSignalData[8] = drf1609.pointType; HAL_UART_Transmit_DMA( &huart1, receivedSignalData, 9 ); } else { haveTryToJoinTimers++; if(haveTryToJoinTimers >= maxJoinTimers) { result=1; } else { result=0; } } return result; } 

检测的过程:
1,发送读取信号强度指令
2,等待接收回复数据
3,如果接收回复数据成功(已经加入网络),这里将收到的数据加上自己的节点类型发送给Coordinator,通知节点已经加入成功

 drf1609h_requestSignalIndex(); HAL_UART_Receive( &huart1, receivedSignalData, 8, 500 ); HAL_Delay(1000); if( checkSignalData(receivedSignalData, 8) ) { result=1; receivedSignalData[8] = drf1609.pointType; HAL_UART_Transmit_DMA( &huart1, receivedSignalData, 9 ); } 

3,启动节点自动加入网络

如果连按三次DRF1609H的Function按键,则开始自动扫描,如果扫描到Coordinator,则可以自动加入网络,并从Coordinator处获得“给Router预设的参数”,所以节点是不要设置的,我们节点的板子上也没有把DRF1609H的串口留出来,而是通过连按三次按键,自动加入网络,自动取得参数。
1,检测DRF1609H是否加入网络,用的是读取信号强度的指令
2,如果没有加入网络,则启动自动加入网络
3,启动后,等待12秒,再读取信号强度,判断是否加入了网络
注意,板子上有按键,如果是低功耗模式,建议不要启动这个功能,用按键手工加入网络,如果Coordinator没开机,一直扫描网络,会很快耗光电池。

讯享网 //-- Do 5 timers get Signal Index ----// for(i=0; i<5; i++) { drf1609h_requestSignalIndex(); HAL_UART_Receive( &huart1, receivedSignalData, 8, 500 ); HAL_Delay(500); if( checkSignalData(receivedSignalData, 8) ) { tempVal++; i=5; } else { notGetSignalVal++; } } 
 drf1609h_autoJoinNet_Start(); HAL_Delay(12000); 
讯享网//--------------------------------------- /* This Simulate Function Key to start * point auto join net * ____ ______ ______ ______ * |__| |__| |__| * * 120 200 120 200 120 200 * * ----------------------------------*/ void drf1609h_autoJoinNet_Start() { uint8_t i=0; set_autoJoinNetPin_output(); set_autoJoinNetPin_out_1(); HAL_Delay(100); for(i=0; i<3; i++) { set_autoJoinNetPin_out_0(); HAL_Delay(120); set_autoJoinNetPin_out_1(); HAL_Delay(200); } set_autoJoinNetPin_input(); } 

4,DRF1609H的相关指令

uint8_t linkIns[9] = {0xFC, 0x06, 0x04, 0x44, 0x54, 0x4B, 0x52, 0x46, 0x81}; //---INS01 uint8_t restartIns[9] = {0xFC, 0x06, 0x06, 0x44, 0x54, 0x4B, 0xAA, 0xBB, 0x50}; //---INS02 uint8_t readIns[9] = {0xFC, 0x06, 0x0E, 0x44, 0x54, 0x4B, 0x52, 0x46, 0x8B}; //---INS05 uint8_t writeIns[42]; //--INS06 uint8_t requestSignalIns[9] = {0xFC, 0x06, 0x0C, 0x44, 0x54, 0x4B, 0x52, 0x46, 0x89}; //--INS08 

在这里插入图片描述

小讯
上一篇 2025-03-11 12:52
下一篇 2025-01-13 12:17

相关推荐

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容,请联系我们,一经查实,本站将立刻删除。
如需转载请保留出处:https://51itzy.com/kjqy/14525.html