标签:
基于STM32W108的SimpleMac协议栈编写程序,实现多个无线节点之间的通信。节点分为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"); } |
函数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嵌入式无线传感器网络》邱铁,夏锋,周玉编著.清华大学出版社,2014年5月
标签:
原文地址:http://blog.csdn.net/u010273356/article/details/46793383