STM32W108无线传感器网络节点自组织与移动智能体导航技术
- 作者: 五速梦信息网
- 时间: 2026年04月04日 13:25
/**************************************************************************
功能描写叙述:对接收的数据包进行解析。并运行对应的操作
输入參数:无
输出參数:无
*************************************************************************/
void processRxPacket(void)
{
u8 i;
boolean pktHasSrcPanId = FALSE;
u8 srcAddrOffset = 0;
u16 srcPanId=0xFFFF;
u16 shortSrcAddr=0;
u8 longSrcAddr[8]={0,};//64位数据源地址
u8 pt = PT_JOIN_DENIED; //负载类型
u8 assignedShortId[2] = {0xFE, 0xFF};
#ifdef ROOT_ROLE
u8 fatherLongAddr[8]={0,},childLongAddr[8]={0,}; //记录64位长地址
#endif
u8 payloadStart; //负载的起始位置
u8 packetType; //数据包类型
u8 packet[128]; //用于记录将发送的数据包内容
int x,y;//用于记录节点的坐标
if(!rxData.packetBeingProcessed) {
return;
}
//数据包的长度不能小于10
if(rxData.packet[0]<10) {
RX_DETAILS(printf("Length byte too short\r\n");)
goto stopProcessing;
}
//推断帧类型
switch(rxData.packet[1]&0x7) {
case FT_DATA:
RX_DETAILS(printf("FT_DATA\r\n");)
packetType = (FT_DATA<<4);
RX_DETAILS(printf("the packet type is:%X\r\n",packetType);)
break;
case FT_MAC_COMMAND:
RX_DETAILS(printf("FT_MAC_COMMAND\r\n");)
packetType = (FT_MAC_COMMAND<<4);
break;
default:
RX_DETAILS(printf("Unknown frame type\r\n");)
goto stopProcessing;
};
//推断是否有PAN ID
if((rxData.packet[1]&0x40)!=0x40) {
pktHasSrcPanId=TRUE;
srcAddrOffset = 2;
}
//推断地址类型
switch(rxData.packet[2]) {
case FCF_SHORTDST + FCF_SHORTSRC:
RX_DETAILS(printf("short dst, short src\r\n");)
shortSrcAddr = (rxData.packet[8+srcAddrOffset+1]<<8)|
(rxData.packet[8+srcAddrOffset+0]<<0);
payloadStart = 10+srcAddrOffset;
if(pktHasSrcPanId) {
srcPanId = (rxData.packet[9]<<8)|(rxData.packet[8]<<0);
}
break;
case FCF_SHORTDST + FCF_LONGSRC:
RX_DETAILS(printf("short dst, long src\r\n");)
memcpy(longSrcAddr, (rxData.packet+8+srcAddrOffset), 8);
payloadStart = 16+srcAddrOffset;
if(pktHasSrcPanId) {
srcPanId = (rxData.packet[9]<<8)|(rxData.packet[8]<<0);
}
break;
case FCF_LONGDST + FCF_SHORTSRC:
RX_DETAILS(printf("long dst, short src\r\n");)
shortSrcAddr = (rxData.packet[14+srcAddrOffset+1]<<8)|
(rxData.packet[14+srcAddrOffset+0]<<0);
payloadStart = 16+srcAddrOffset;
if(pktHasSrcPanId) {
srcPanId = (rxData.packet[15]<<8)|(rxData.packet[14]<<0);
}
break;
case FCF_LONGDST + FCF_LONGSRC:
RX_DETAILS(printf("long dst, long src\r\n");)
memcpy(longSrcAddr, (rxData.packet+14+srcAddrOffset), 8);
payloadStart = 22+srcAddrOffset;
if(pktHasSrcPanId) {
srcPanId = (rxData.packet[15]<<8)|(rxData.packet[14]<<0);
}
break;
default:
RX_DETAILS(printf("Unknown addressing mode\r\n");)
goto stopProcessing;
}
RX_DETAILS(
if(pktHasSrcPanId) {
RX_DETAILS(printf("src pan = 0x%04X\r\n", srcPanId);)
}
)
//确保数据包的长度足够包括负载类型数据
if(rxData.packet[0]<payloadStart) {
RX_DETAILS(printf("Length byte too short\r\n");)
goto stopProcessing;
}
//获取数据包的负载类型
packetType |= (rxData.packet[payloadStart]<<0);
RX_DETAILS(printf("packet type = 0x%02X\r\n", packetType);
printf("the longAddr is:");printLongAddr(longSrcAddr);)
//依据负载类型,处理数据包
switch(packetType) {
case (GENERIC_DATA_PACKET): //普通类型数据包,用于更新最新通信时间
RX_DETAILS(printf("GENERIC_DATA_PACKET\r\n");)
rxData.lqi = calculateLqi(rxData.errors, (rxData.packet[0]+3)); //计算通信联络质量
//节点坐标
x=((rxData.packet[payloadStart+3]&0xFF)
|((rxData.packet[payloadStart+4]&0xFF)<<8)
|((rxData.packet[payloadStart+5]&0xFF)<<16)
|((rxData.packet[payloadStart+6]&0xFF)<<24));
y=((rxData.packet[payloadStart+7]&0xFF)
|((rxData.packet[payloadStart+8]&0xFF)<<8)
|((rxData.packet[payloadStart+9]&0xFF)<<16)
|((rxData.packet[payloadStart+10]&0xFF)<<24));
printLongAddr(longSrcAddr);
RX_DETAIL(printf("RSSI=%d,X=%d,Y=%d\n",rxData.rssi,x,y);)
//更新父节点与子节点之间的通信时间
for(i=0;i<CHILD_TABLE_SIZE;i++)
{
if(childTable[i].active&&whetherEqual(longSrcAddr,childTable[i].longAddr))//子节点
{
//更新子节点记录信息
childTable[i].lastDataTransmitTick=halCommonGetInt16uQuarterSecondTick();
childTable[i].nodeSite.x=x;
childTable[i].nodeSite.y=y;
break;
}
}
break;
/*当节点收到增加请求数据包时。首先推断自己是否是根节点,假设是则回复数据包,
假设不是则推断自己是否已增加网络,假设已增加网络则可作为路由节点使用,假设
没有增加网络则忽略此数据包*/
case (FATHER_SEARCH_PACKET):
if(rxData.rssi<RELIABLE_RSSI) //依据数据包RSSI进行数据包的过滤
{
goto stopProcessing;
}
if(father.active&&childAvailable) //推断是否具有作为父节点的条件
{
//数据包封装
packet[1] = FCF_DATA; //帧类型
packet[2] = FCF_LONGDST + FCF_LONGSRC; //地址类型
currSeqNum++; //数据包序列号
packet[3]=currSeqNum;
packet[4] = (0xFFFF>>0)&0xFF; //目标PAN ID
packet[5] = (0xFFFF>>8)&0xFF;
memcpy((packet+6), longSrcAddr, 8); //64位长目标地址
packet[14] = (ST_RadioGetPanId()>>0)&0xFF; //源PAN ID
packet[15] = (ST_RadioGetPanId()>>8)&0xFF;
memcpy((packet+16), ST_RadioGetEui64(), 8); //64位长目标地址
packet[24] = PT_FATHER_AVAILABLE; //负载类型,父节点可用数据包
packet[25]=currentHopCount; //传递当前节点的跳数
enqueueTxPacket(TRUE, 0xFFFF, packet, 0); //广播通信
}
break;
/*当节点搜索父节点增加网络时,收到回复的数据。此前是广播所以可能会有多个节
点进行回复,此时须要延时,等待收到全部的回复。然后从回复的数据中选择跳数
最少,假设跳数最少的有多个节点,则选择RSSI最大的节点作为父节点进行增加
网络*/
case (FATHER_AVAILABLE_PACKET): //父节点可用数据包
if(rxData.rssi<RELIABLE_RSSI) //依据数据包RSSI进行数据包的过滤
{
goto stopProcessing;
}
if(!father.active) //假设当前没有增加网络。进入例如以下操作
{
for(i=0;i<current_optional_father_num;i++) //扫描当前可用父节点数组
{
//推断数组中是否包括此父节点的信息
if(whetherEqual(longSrcAddr,optionalFather[i].longAddr))
{
optionalFather[i].rssi += rxData.rssi; //RSSI值累加
optionalFather[i].packetNum++; //记录接收数据包次数
//推断数据包次数是否满足成为有效父节点的最小次数
if(optionalFather[i].packetNum==MIN_PACKET_NUM)
optionalFather[i].active=TRUE;
break;
}
}
if(i==current_optional_father_num) //数组中不包括此数据包信息
{
//记录跳数信息
optionalFather[current_optional_father_num].hop=rxData.packet[payloadStart+1];
//数据包源地址
memcpy(optionalFather[current_optional_father_num].longAddr,longSrcAddr,8);
optionalFather[current_optional_father_num].panId=srcPanId; //PAN ID值
optionalFather[current_optional_father_num].rssi=rxData.rssi; //RSSI
optionalFather[current_optional_father_num].packetNum=1; //数据包个数
optionalFather[current_optional_father_num].active=FALSE; //不能够
current_optional_father_num++; //可用父节点数添加
}
}
break;
case (JOIN_REQUEST_PACKET): //增加网络请求数据包
if(rxData.rssi<RELIABLE_RSSI) //依据数据包RSSI进行数据包的过滤
{
goto stopProcessing;
}
RX_DETAIL(printf("JOIN_REQUEST_PACKET\r\n");)
//数据包封装
packet[0] = (24+2); //数据包长度
packet[1] = FCF_DATA + FCF_ACKREQ + FCF_INTRAPAN; //帧类型
packet[2] = FCF_LONGDST + FCF_LONGSRC; //地址类型
currSeqNum++; //数据包序列号
packet[3]=currSeqNum;
packet[4] = (ST_RadioGetPanId()>>0)&0xFF; //目标PAN ID
packet[5] = (ST_RadioGetPanId()>>8)&0xFF;
memcpy((packet+6), longSrcAddr, 8); //64位长目标地址
memcpy((packet+14), ST_RadioGetEui64(), 8);//64位长源地址
//扫描子节点数组,推断是否有可用空间加入新的子节点
for(i=0;i<CHILD_TABLE_SIZE;i++)
{
//推断数组中是否已包括此子节点
if(whetherEqual(childTable[i].longAddr,longSrcAddr))
{
//记录子节点坐标信息
childTable[i].nodeSite.x=(rxData.packet[payloadStart+1]&0xFF
|(rxData.packet[payloadStart+2]&0xFF)<<8
|(rxData.packet[payloadStart+3]&0xFF)<<16
|(rxData.packet[payloadStart+4]&0xFF)<<24);
childTable[i].nodeSite.y=(rxData.packet[payloadStart+5]&0xFF
|(rxData.packet[payloadStart+6]&0xFF)<<8
|(rxData.packet[payloadStart+7]&0xFF)<<16
|(rxData.packet[payloadStart+8]&0xFF)<<24);
//记录最新通信时间
childTable[i].lastDataTransmitTick=halCommonGetInt16uQuarterSecondTick();
if(!childTable[i].active) //更新该数组位置信息
{
childNum++; //子节点数添加
childTable[i].active=TRUE; //此子节点位置占用
if(childNum==CHILD_TABLE_SIZE) //推断子节点数是否等于最大子节点数
childAvailable=FALSE; //假设是。则此节点不能再作为其它节点的父节点
}
pt = PT_JOIN_ACCEPTED; //发送增加网络同意数据包
assignedShortId[0] = (shortAddrCounter>>0)&0xFF;
assignedShortId[1] = (shortAddrCounter>>8)&0xFF;
RX_DETAIL(printf("Join: the child in the childtable Planet 0x%04X (index %d)
has joined the network\r\n", shortAddrCounter, i);)
break;
}
else if(!childTable[i].active) //假设数组空间没有被占用,占用该位置空间
{
childTable[i].active = TRUE; //占用该位置空间
childNum++; //子节点数添加
if(childNum==CHILD_TABLE_SIZE) //推断子节点数是否等于最大子节点数
childAvailable=FALSE; //假设是,则此节点不能再作为其它节点的父节点
shortAddrCounter++; //短地址添加
childTable[i].shortAddr = shortAddrCounter; //短地址
memcpy(childTable[i].longAddr,longSrcAddr, 8); //64位长地址
//子节点坐标
childTable[i].nodeSite.x=(rxData.packet[payloadStart+1]&0xFF
|(rxData.packet[payloadStart+2]&0xFF)<<8
|(rxData.packet[payloadStart+3]&0xFF)<<16
|(rxData.packet[payloadStart+4]&0xFF)<<24);
childTable[i].nodeSite.y=(rxData.packet[payloadStart+5]&0xFF
|(rxData.packet[payloadStart+6]&0xFF)<<8
|(rxData.packet[payloadStart+7]&0xFF)<<16
|(rxData.packet[payloadStart+8]&0xFF)<<24);
//最新通信时间
childTable[i].lastDataTransmitTick=halCommonGetInt16uQuarterSecondTick();
pt = PT_JOIN_ACCEPTED; //负载类型
assignedShortId[0] = (shortAddrCounter>>0)&0xFF;
assignedShortId[1] = (shortAddrCounter>>8)&0xFF;
RX_DETAIL(printf("Join: the child is a new child Planet 0x%04X (index %d)
has joined the network\r\n", shortAddrCounter, i);)
#ifndef ROOT_ROLE
#ifndef MOBILE_NODE
//将子节点信息发送到汇聚节点
sendNewNodeSiteToRoot(longSrcAddr,childTable[i].nodeSite);
#endif
#endif
break;
}
}
packet[22] = pt; //负载类型
packet[23] = assignedShortId[0]; //节点Node ID
packet[24] = assignedShortId[1];
enqueueTxPacket(TRUE, 0xFFFF, packet, 0); //广播回复
break;
case (JOIN_ACCEPTED_PACKET): //同意增加网络数据包
if(rxData.rssi<RELIABLE_RSSI) //依据数据包RSSI进行数据包的过滤
{
goto stopProcessing;
}
RX_DETAIL(printf("JOIN_ACCEPTED_PACKET\r\n");)
//设置Node ID
ST_RadioSetNodeId((rxData.packet[payloadStart+1]<<0)
|(rxData.packet[payloadStart+2]<<8));
networkJoinedStopSearching = TRUE; //增加网络成功。停止搜索
break;
case (JOIN_DENIED_PACKET): //增加网络拒绝数据包
RX_DETAIL(printf("JOIN_DENIED_PACKET\r\n");)
ST_RadioSetPanId(0xFFFF); //重置PAN ID
break;
case (LEAVING_PACKET): //离开网络数据包
RX_DETAIL(printf("LEAVING_PACKET\r\n");)
//将节点信息从子节点表中删除
for(i=0;i<CHILD_TABLE_SIZE;i++) //扫描子节点表。查找子节点
{
if(childTable[i].active && whetherEqual(childTable[i].longAddr,longSrcAddr))
{
RX_DETAIL(printLongAddr(longSrcAddr);printf("the node leave the network\n");)
childTable[i].active = FALSE; //将该子节点设置为无效
childNum--; //子节点数降低
childAvailable=TRUE; //而且设置该节点可继续作为父节点,执行子节点的增加
break;
}
}
break;
//信标节点发送的位置信息数据包,用于移动节点的定位
case (FIXED_NODE_SEND_SITE_PACKET):
if(rxData.rssi<RELIABLE_RSSI) //依据数据包RSSI进行数据包的过滤
{
goto stopProcessing;
}
if(!siteIsFixed) //假设位置为固定,则处理此数据包
{
for(i=0;i<current_node_num;i++) //扫描信标节点数组
{
//推断是否有此节点的信息
if(whetherEqual(longSrcAddr,receivePacketRecord[i].longAddr))
{
receivePacketRecord[i].totalRssi+=rxData.rssi; //RSSI值累加
receivePacketRecord[i].current_num++; //数据包数添加
break;
}
}
if(i==current_node_num) //假设数组中无此节点的记录信息
{
//获取信标节点的坐标
x=(rxData.packet[payloadStart+1]&0xFF
|(rxData.packet[payloadStart+2]&0xFF)<<8
|(rxData.packet[payloadStart+3]&0xFF)<<16
|(rxData.packet[payloadStart+4]&0xFF)<<24);
y=(rxData.packet[payloadStart+5]&0xFF
|(rxData.packet[payloadStart+6]&0xFF)<<8
|(rxData.packet[payloadStart+7]&0xFF)<<16
|(rxData.packet[payloadStart+8]&0xFF)<<24);
RX_DETAIL(printf("the node site x is:%d, y is:%d\n",x,y);)
receivePacketRecord[current_node_num].nodeSite.x=x; //记录坐标
receivePacketRecord[current_node_num].nodeSite.y=y;
receivePacketRecord[current_node_num].current_num=1;//第一个数据包
receivePacketRecord[current_node_num].totalRssi=rxData.rssi;//RSSI值
memcpy(receivePacketRecord[i].longAddr,longSrcAddr,8); //64位长地址
current_node_num++; //当前可用定位节点个数
}
}
break;
case (CHANNEL_SEARCH_PACKET): //信道搜索数据包
if(channelSearched)
{
RX_DETAIL(printf("CHANNEL_SEARCH_PACKET\r\n");)
//数据包封装
packet[0] = (24+2); //数据包长度
packet[1] = FCF_DATA; //帧类型
packet[2] = FCF_LONGDST + FCF_LONGSRC; //地址类型
currSeqNum++; //数据包序列号
packet[3]=currSeqNum;
packet[4] = (0xFFFF>>0)&0xFF; //目标PAN ID
packet[5] = (0xFFFF>>8)&0xFF;
memcpy((packet+6), longSrcAddr, 8); //长目标地址
packet[14] = (ST_RadioGetPanId()>>0)&0xFF; //源PAN ID
packet[15] = (ST_RadioGetPanId()>>8)&0xFF;
memcpy((packet+16), ST_RadioGetEui64(), 8); //长源地址
packet[24] = PT_CHANNEL_AVAILABLE; //负载类型。信道可用数据包
enqueueTxPacket(TRUE, 0xFFFF, packet, 0); //广播回复
}
break;
case (CHANNEL_AVAILABLE_PACKET): //信道可用数据包
RX_DETAIL(printf("CHANNEL_AVAILABLE_PACKET\r\n");)
channelStopSearching=TRUE;
break;
//移动节点请求定位数据包,当信标节点接收到此数据包时广播其位置信息
case (POSITIONING_REQUEST_PACKET):
if(rxData.rssi<RELIABLE_RSSI) //依据数据包RSSI进行数据包的过滤
{
goto stopProcessing;
}
#ifndef ROOT_ROLE
#ifndef MOBILE_NODE
if(siteIsFixed) //假设为信标节点
{
fixedNodeBroadcast(longSrcAddr,FALSE); //广播其位置信息
}
#endif
#endif
break;
//移动智能体请求定位数据包,当信标节点接收到此数据包时广播其位置信息
case (MOBILE_NODE_POSITIONING_REQUEST_PACKET):
if(rxData.rssi<RELIABLE_RSSI) //依据数据包RSSI进行数据包的过滤
{
goto stopProcessing;
}
#ifndef ROOT_ROLE
#ifndef MOBILE_NODE
if(siteIsFixed)
{
fixedNodeBroadcast(longSrcAddr,TRUE); //信标节点广播,用于移动智能体定位
}
#endif
#endif
break;
case (DATA_FROM_MOBILE_NODE_PACKET): //移动智能体发送的数据包
if(rxData.rssi<RELIABLE_RSSI) //依据数据包RSSI进行数据包的过滤
{
goto stopProcessing;
}
#ifdef ROOT_ROLE //假设为汇聚节点
//获取移动智能体的坐标信息
x=((rxData.packet[payloadStart+1]&0xFF)
|((rxData.packet[payloadStart+2]&0xFF)<<8)
|((rxData.packet[payloadStart+3]&0xFF)<<16)
|((rxData.packet[payloadStart+4]&0xFF)<<24));
y=((rxData.packet[payloadStart+5]&0xFF)
|((rxData.packet[payloadStart+6]&0xFF)<<8)
|((rxData.packet[payloadStart+7]&0xFF)<<16)
|((rxData.packet[payloadStart+8]&0xFF)<<24));
memcpy(childLongAddr,(rxData.packet+payloadStart+9),8); //64位长地址
RX_DETAIL(printf("%d %d\n",x,y);)
for(i=0;i<CHILD_TABLE_SIZE;i++) //扫描其子节点表
{
if(whetherEqual(longSrcAddr,childTable[i].longAddr)) //查找数据包来自哪个子节点
{
//TRUE表示可以在移动智能体和汇聚节点之间建立通信路由
inDirectDataOfMobileNode=TRUE;
//表示此子节点可以和移动智能体之间建立通信路由
childTable[i].transDataFromMobileNode=TRUE;
childTable[i].pathStartTime=((rxData.packet[payloadStart+9])
|((rxData.packet[payloadStart+10]&0xFF)<<8)); //记录通信路由的建立时间
break;
}
}
#else
#ifndef MOBILE_NODE //非汇聚节点和非移动智能体
/*间节点收到来自移动智能体的数据包进行转发。发送给其父节点,
父节点继续向其父节点转发,直到到达汇聚节点*/
transmitDataFromMobileNode(payloadStart+1,rxData.packet[0]-payloadStart); //转发数据
for(i=0;i<CHILD_TABLE_SIZE;i++) //扫描其子节点表
{
if(whetherEqual(longSrcAddr,childTable[i].longAddr)) //查找数据包来自哪个子节点
{
inDirectDataOfMobileNode=TRUE; //表示此节点与移动智能体之间建立通信路径
childTable[i].transDataFromMobileNode=TRUE; //通信路径的下一跳为此子节点
if(rxData.packet[0]-payloadStart==8) //推断数据包中是否包括时间信息
childTable[i].pathStartTime=halCommonGetInt16uQuarterSecondTick(); //当前时间
else
childTable[i].pathStartTime=((rxData.packet[payloadStart+9])
|((rxData.packet[payloadStart+10]&0xFF)<<8)); //数据包中的时间
break;
}
}
#endif
#endif
break;
case (DATA_TO_MOBILE_NODE_PACKET): //发往移动智能体的数据包
#ifndef MOBILE_NODE
#ifndef ROOT_ROLE
//非移动智能体节点收到来自汇聚节点发送给移动智能体的数据,进行转发
dataTransmitToMobileNode(payloadStart+1,rxData.packet[0]-payloadStart);
#endif
#endif
break;
//广播发送给移动智能体的数据包
case (DATA_BROADCAST_TO_MOBILE_NODE_PACKET):
#ifdef MOBILE_NODE
/*移动智能体依据收到来自汇聚节点的信息。调整自己的移动
汇聚节点发送给移动智能体的数据可能是控制命令,可能是新的目标坐标*/
if(rxData.packet[0]-payloadStart > 1)//发送的是目标坐标
{
x=((rxData.packet[payloadStart+1]&0xFF)
|((rxData.packet[payloadStart+2]&0xFF)<<8)
|((rxData.packet[payloadStart+3]&0xFF)<<16)
|((rxData.packet[payloadStart+4]&0xFF)<<24));
y=((rxData.packet[payloadStart+5]&0xFF)
|((rxData.packet[payloadStart+6]&0xFF)<<8)
|((rxData.packet[payloadStart+7]&0xFF)<<16)
|((rxData.packet[payloadStart+8]&0xFF)<<24));
RX_DETAIL(printf("mobile node receive new site:x=%d,y=%d\n",x,y);)
if(x!=targetSite.x||y!=targetSite.y)
{
targetSite.x=x; //设置新的移动坐标
targetSite.y=y;
isArriveTargetSite=FALSE; //表示没有达到指定位置
arriveTargetSiteTimes=0; //清空达到指定位置次数
}
}
else //发送的是控制命令
{
u8 data;
data=rxData.packet[payloadStart+1];
switch (data)
{
case 's': //停止移动命令
isArriveTargetSite=TRUE;
STOP(); //运行STOP()函数,停止移动智能体的移动
break;
case 'm': //移动命令
isArriveTargetSite=FALSE;
adjustAngle(nodeSite,targetSite); //依据当前位置和目标位置调整移动方向及角度
break;
default://不可识别的信息,不进行不论什么操作
break;
}
}
#endif
break;
case (DATA_TO_ROOT_PACKET): //收到发送到根节点的数据
//假设汇聚节点接收到此信息,通过串口显示信息
#ifdef ROOT_ROLE
//获取坐标信息
x=((rxData.packet[payloadStart+17]&0xFF)
|((rxData.packet[payloadStart+18]&0xFF)<<8)
|((rxData.packet[payloadStart+19]&0xFF)<<16)
|((rxData.packet[payloadStart+20]&0xFF)<<24));
y=((rxData.packet[payloadStart+21]&0xFF)
|((rxData.packet[payloadStart+22]&0xFF)<<8)
|((rxData.packet[payloadStart+23]&0xFF)<<16)
|((rxData.packet[payloadStart+24]&0xFF)<<24));
memcpy(fatherLongAddr,(rxData.packet+payloadStart+1),8); //父节点64位长地址
memcpy(childLongAddr,(rxData.packet+payloadStart+9),8); //子节点64为长地址
//输出64位长地址信息
printFatherLongAddr(fatherLongAddr);
printChildLongAddr(childLongAddr);
RX_DETAIL(printf("RSSI=%d,",rxData.rssi);)
RX_DETAIL(printf("X=%d,Y=%d\n",x,y);)
#else //不是汇聚节点而是中间路由节点
#ifndef MOBILE_NODE
dataTransmitToRoot(payloadStart+1,rxData.packet[0]-payloadStart); //转发数据
#endif
#endif
break;
default:
RX_DETAIL(printf("Unknown payload type\r\n");)
goto stopProcessing;
}
stopProcessing:
rxData.packetBeingProcessed = FALSE;
}
- 上一篇: STM32标准外设库、 HAL库、LL库
- 下一篇: stm32f104芯片能用链表吗
相关文章
-
STM32标准外设库、 HAL库、LL库
STM32标准外设库、 HAL库、LL库
- 互联网
- 2026年04月04日
-
STM32复位及通过函数判断是何种条件出发的复位
STM32复位及通过函数判断是何种条件出发的复位
- 互联网
- 2026年04月04日
-
stm32输入的功能引脚功能介绍
stm32输入的功能引脚功能介绍
- 互联网
- 2026年04月04日
-
stm32f104芯片能用链表吗
stm32f104芯片能用链表吗
- 互联网
- 2026年04月04日
-
STM32CubeMX使用方法及功能介绍
STM32CubeMX使用方法及功能介绍
- 互联网
- 2026年04月04日
-
stm32cubemx多通道adc采集
stm32cubemx多通道adc采集
- 互联网
- 2026年04月04日






