STM32W108无线射频模块多节点之间通信实例

STM32W108无线射频模块多节点之间通信实例 

 

基于STM32W108SimpleMac协议栈编写程序,实现多个无线节点之间的通信。节点分为SUN节点和PLANET节点,SUN节点使用STM32W108无线开发板,PLANET节点使用STM32W108无线数据采集节点,SUN节点可与PC机进行通信。

 

编程与实现

程序的设计基于SimpleMac协议栈进行,以下给出部分主要相关代码。该实例中的部分代码与11章中的两节点通信实例代码相同,本章不再重复说明。

文件solar-system.c部分内容:

部分变量全局变量定义:

//负载类型定义

#define PT_SLEEPING      (0x08)

#define PT_LED           (0x09)

#define PT_TRSEND        (0x0A)

 

//数据包类型定义

#define SYN_SLEEPING_WAITTIME    ((FT_DATA <<4) | (PT_SLEEPING   <<0))

#define SYN_LED_WAITTIME          ((FT_DATA <<4) | (PT_LED   <<0))  

#define TRSEND_PACKET             ((FT_DATA <<4) | (PT_TRSEND   <<0)) 

 

函数processRxPacket()

/**************************************************************************

功能描述:对接收的数据包进行解析,并执行相应的操作

输入参数:无

输出参数:无

*************************************************************************/

void processRxPacket(void)

{

   ......

......

   …… 

   //不同类型数据包进行不同处理

   switch(packetType) {

     case (GENERIC_DATA_PACKET): //普通类型数据包

       RX_DETAILS(printf("GENERIC_DATA_PACKET\r\n");)

#ifdef SUN_ROLE

       halToggleLed(LED_D1); //LED1闪烁

       halCommonDelayMilliseconds(500);//延迟500ms

       halClearLed(LED_D1); //关闭LED1

#endif

#ifdef PLANET_ROLE

       halToggleLed(LED_D3); //LED3闪烁

       halCommonDelayMilliseconds(500); //延迟500ms

       halClearLed(LED_D3); //关闭LED3

#endif

     rxData.lqi = calculateLqi(rxData.errors, (rxData.packet[0]+3)); //计算通信链路质量

printf("RX:  Addr=0x%04X, VDD=%dmV, RxSFD=0x%05X, ", shortSrcAddr,

((rxData.packet[payloadStart+1]<<0)|(rxData.packet[payloadStart+2]<<8)),  rxData.time);

if(rxData.packet[payloadStart+5]&0x80)   //判断数据包是否包含SFD

{

         //获取TX SFD数据,并输出

         rxData.packet[payloadStart+5] &= ~0x80;

         printf("TxSFD=0x%05X, ", ((rxData.packet[payloadStart+3]<<  0)|

(rxData.packet[payloadStart+4]<< 8)| (rxData.packet[payloadStart+5]<<16)));

}

else

{

printf("TxSFD=-------, ");

}

printf("RSSI=%ddBm, LQI=0x%02X\r\n", rxData.rssi, rxData.lqi);

break;

 

#ifdef PLANET_ROLE

     case (SYN_SLEEPING_WAITTIME):   //PT_SLEEPING类型数据包

         printf("SYN_SLEEPING_WAITTIME\r\n");

            halToggleLed(LED_D3); //闪烁LED3

            halCommonDelayMilliseconds(1000); //延迟1000ms

         halClearLed(LED_D3); //关闭LED3

         break;

     case (SYN_LED_WAITTIME): //PT_LED类型数据包

         printf("SYN_LED_WAITTIME\r\n");

            halToggleLed(LED_D3);    //闪烁LED3

            halCommonDelayMilliseconds(500); //延迟500ms

         halClearLed(LED_D3); //关闭LED3

         halCommonDelayMilliseconds(500);

         halToggleLed(LED_D3);   

            halCommonDelayMilliseconds(500);

         halClearLed(LED_D3);

         halCommonDelayMilliseconds(500);

         halToggleLed(LED_D3);   

            halCommonDelayMilliseconds(500);

         halClearLed(LED_D3);

         break;

#endif

     case (TRSEND_PACKET): //PT_TRSEND类型数据包

         sendVddDataPacket(0x0000,0x0001,TRUE); //向节点1发送数据包

         printf("trsend success\r\n");

         break;

……

……

……  

     default:

       RX_DETAILS(printf("Unknown payload type\r\n");)

       goto stopProcessing;

  }

 

stopProcessing:

   rxData.packetBeingProcessed = FALSE;

}

函数sendVddDataPacket()

/**************************************************************************

功能描述:向参数中传入的地址发送类型负载类型为PT_GENERIC_DATA的数据包

输入参数:vddMillivolts为发送的16位数据,dstShortAddr为目的地址,sendDirectly为调用不同发送函数的表示符。

输出参数:无

*************************************************************************/

void sendVddDataPacket(u16  vddMillivolts,u16 dstShortAddr, boolean sendDirectly)

{

  u8  packet[128];

 

   //数据包封装

   packet[0] = (15+2); //数据包长度

   packet[1] = FCF_DATA + FCF_ACKREQ + FCF_INTRAPAN; //帧类型

   packet[2] = FCF_SHORTDST + FCF_SHORTSRC; //地址类型

   currSeqNum++; //数据包序列号

   packet[3] = currSeqNum;

   packet[4] = (ST_RadioGetPanId()>>0)&0xFF; //目标PAN  ID

   packet[5] = (ST_RadioGetPanId()>>8)&0xFF;

   packet[6] = (dstShortAddr>>0)&0xFF; //目标短地址

   packet[7] = (dstShortAddr>>8)&0xFF;

   packet[8] = (ST_RadioGetNodeId()>>0)&0xFF; //源短地址

   packet[9] = (ST_RadioGetNodeId()>>8)&0xFF;

   packet[10] = PT_GENERIC_DATA; //负载类型

   packet[11] = (vddMillivolts>>0)&0xFF; //发送的16位数据

   packet[12] = (vddMillivolts>>8)&0xFF;

 

//归零Tx  SFD有效负载,MSB用于指示SFD有效

   packet[13] = 0;

   packet[14] = 0;

   packet[15] = 0;

   enqueueTxPacket(sendDirectly, dstShortAddr, packet, 15); //发送数据包

   printf("send already!\r\n");

}

 STM32W108无线射频模块多节点之间通信实例_第1张图片

函数sendVddDataPacket1()

/**************************************************************************

功能描述:向参数中传入的地址发送类型负载类型为PT_SLEEPING的数据包

输入参数:vddMillivolts为发送的16位数据,dstShortAddr为目的地址,sendDirectly为调用不同发送函数的表示符。

输出参数:无

*************************************************************************/

void sendVddDataPacket1(u16  vddMillivolts,u16 dstShortAddr,boolean sendDirectly)

{

   u8 packet[128];

 

  //数据包封装

   packet[0] = (15+2); //数据包长度

   packet[1] = FCF_DATA + FCF_ACKREQ + FCF_INTRAPAN; //帧类型

   packet[2] = FCF_SHORTDST + FCF_SHORTSRC; //地址类型

   currSeqNum++;  //数据包序列号

   packet[3] = currSeqNum;

   packet[4] = (ST_RadioGetPanId()>>0)&0xFF; //目标PAN  ID

   packet[5] = (ST_RadioGetPanId()>>8)&0xFF;

   packet[6] = (dstShortAddr>>0)&0xFF; //目标短地址

   packet[7] = (dstShortAddr>>8)&0xFF;

   packet[8] = (ST_RadioGetNodeId()>>0)&0xFF; //源短地址

   packet[9] = (ST_RadioGetNodeId()>>8)&0xFF;

   packet[10] = PT_SLEEPING; //负载类型

   packet[11] = (vddMillivolts>>0)&0xFF; //发送的16位数据

   packet[12] = (vddMillivolts>>8)&0xFF;

 

//归零Tx  SFD有效负载,MSB用于指示SFD有效

   packet[13] = 0;

   packet[14] = 0;

   packet[15] = 0; 

   enqueueTxPacket(sendDirectly, dstShortAddr, packet, 15); //发送数据包

#ifdef SUN_ROLE 

   halToggleLed(LED_D2); //LED2闪烁

   halCommonDelayMilliseconds(500); //延时500ms

   halClearLed(LED_D2);

#endif

   printf("send sleeping packet to every planet!\r\n");

}

 

 

本文出自《STM32W108嵌入式无线传感器网络》邱铁,夏锋,周玉编著.清华大学出版社,20145

你可能感兴趣的:(嵌入式技术,物联网技术,STM32)