首页 > 代码库 > 「ZigBee模块」组网实验-信号传输质量检测
「ZigBee模块」组网实验-信号传输质量检测
信号传输质量检测
重点在代码分析部分...就是废话比较多...
一、实验平台
两个ZigBee模块
一个方口USB线
一个编译器
二、实验现象
两块ZigBee模块通信,一个模块作发射,另外一个模块作接收,接收模块通过串口在PC机上显示当前的误包率、RSSI值和接收到数据包的个数
三、准备工作
由于硬件平台不同,所以我们需要在per_test中加入串口发送函数
1. 打开工程—>application—>per_test.c
在per_test.c文件中添加串口发送函数
2. INCLUDES中添
#include "string.h"
3. 在函数声明中添加
void uartInit(void);//**************************void uartSend(int8 *Data,int len);//**********************
4. 添加串口初始化函数
1 /**************************************************************** 2 串口初始化函数 3 ****************************************************************/ 4 void initUART(void) 5 { 6 PERCFG = 0x00; //位置1 P0口 7 P0SEL = 0x0c; //P0_2,P0_3用作串口(外部设备功能) 8 P2DIR &= ~0XC0; //P0优先作为UART0 9 10 U0CSR |= 0x80; //设置为UART方式11 U0GCR |= 11; 12 U0BAUD |= 216; //波特率设为11520013 UTX0IF = 0; //UART0 TX中断标志初始置位014 }
5. 添加串口发送函数
1 /**************************************************************** 2 串口发送字符串函数 3 ****************************************************************/ 4 void uartSend(int8 *Data,int len) 5 { 6 int j; 7 for(j=0;j<len;j++) 8 { 9 U0DBUF = *Data++;10 while(UTX0IF == 0);11 UTX0IF = 0;12 }13 }
6. 因为只有接收模块使用到串口,把串口初始化放入appReceiver()即可
四、分析per_test.c的代码
看代码前还是想先解释一下,这里一个数据包就是一个结构体数据类型,里面包括6个字节的内容和1个字节的序号 我们是利用序号来判断有没有发生误包的。
第一步,先找到main函数
1 void main (void) 2 { 3 //变量声明 4 uint8 appMode; //用来选择模式(发送或接收) 5 6 appState = IDLE; 7 8 //配置basic RF 9 basicRfConfig.panId = PAN_ID;10 basicRfConfig.ackRequest = FALSE;11 12 //初始化外围设备13 halBoardInit();14 15 //初始化hal_rf16 if(halRfInit()==FAILED) {17 HAL_ASSERT(FALSE);18 }19 20 //点亮led1(P1.0)用以表示程序开始运行21 halLedSet(1);22 23 //信道设置 11—25都可以24 basicRfConfig.channel = 0x0B;25 26 //这里就是模式选择啦,选择完进入那个函数,然后main函数就不需要啦27 //这个怎么选??28 //看MODE_SEND,go to definition,找到定义的地方29 //把那行代码注释掉就是接收部分,不注释就是发送30 #ifdef MODE_SEND31 appMode = MODE_TX;32 #else33 appMode = MODE_RX;34 #endif 35 // Transmitter application36 if(appMode == MODE_TX) {37 // No return from here38 appTransmitter();39 }40 // Receiver application41 else if(appMode == MODE_RX) {42 // No return from here43 appReceiver();44 }45 // Role is undefined. This code should not be reached46 HAL_ASSERT(FALSE);47 }
看完main函数,再来看一下发送的函数吧~
总结一下就是一大堆初始化然后依次发送数据包
1 static void appTransmitter() 2 { 3 //声明变量 4 uint32 burstSize=0; //设定进行一次测试所发送的数据包数量 5 uint32 pktsSent=0; //指示当前已经发了多少个数据包 6 uint8 n; 7 8 //初始化Basic RF 9 basicRfConfig.myAddr = TX_ADDR;10 if(basicRfInit(&basicRfConfig)==FAILED) 11 {12 HAL_ASSERT(FALSE);13 }14 15 //置输出功率16 halRfSetTxPower(2);17 18 //设置进行一次测试所发送的数据包数量 19 burstSize = 1000;20 21 //关闭接收模块,省电22 basicRfReceiveOff();23 24 //配置定时器和IO25 //暂时不知道有什么用...以后补上26 appConfigTimer(0xC8);27 28 //初始化数据包载荷29 //txPacket是什么? 就是一个数据包~在per_test.h中!30 //里面有两个变量,seqNumber和padding[6]31 //就是说一个数据包里面有6个字节的内容和一个表示序号的seqNumber32 //讲一下seqNumber 就是拿来当序号用,发送时按012345这样的顺序发送,所以理应012345这样接受33 //如果这次收到3,下次收到5,那就表示丢包了34 txPacket.seqNumber = 0;35 for(n = 0; n < sizeof(txPacket.padding); n++) //初始化下,数据包里面就是01234536 {37 txPacket.padding[n] = n;38 }39 40 //主循环41 while (TRUE) 42 {43 if (pktsSent < burstSize) //如果数据包还没有发送完,继续执行44 {45 // 改变发送序号的字节顺序46 //我也不知道为什么要改变顺序再改回来,可能和数据发送的一些协议有关吧,以后知道再补上47 UINT32_HTON(txPacket.seqNumber);48 49 //发送数据函数(发给谁, 发的内容, 数据长度) 重点就是这行代码!50 //注意下,发送的就是txPacket这一整个数据,包括实际内容和序号,这是一个完整的数据包51 basicRfSendPacket(RX_ADDR, (uint8*)&txPacket, PACKET_SIZE);52 53 //在增加序号前将字节顺序改回为主机顺序54 UINT32_NTOH(txPacket.seqNumber);55 txPacket.seqNumber++; //发的序号+1 56 57 pktsSent++; //发送了一个数据包了 +158 59 halLedToggle(1); //改变LED1的亮灭状态60 halMcuWaitMs(500); //延时61 }62 //数据包清零63 pktsSent = 0;64 65 }66 }
最后是接收的部分
总结一下,开始还是一大堆初始化,然后一直接收数据、判断是不是丢包了、处理数据、串口发送
1 static void appReceiver() 2 { 3 uint32 segNumber=0; // 数据包序列号 4 int16 perRssiBuf[RSSI_AVG_WINDOW_SIZE] = {0}; // 存储RSSI的环形缓冲区 5 uint8 perRssiBufCounter = 0; // 计数器用于RSSI缓冲区统计 6 7 perRxStats_t rxStats = {0,0,0,0}; 8 int16 rssi; 9 uint8 resetStats=FALSE; 10 11 int8 Myper[5]; 12 int8 Myrssi[2]; 13 int8 Myreceive[4]; 14 int32 temp_per; //存放掉包率 15 int32 temp_receive; //存放接收的包的个数 16 int32 temp_rssi; //存放前32个rssi值的平均值 17 uartInit(); // 初始化串口 18 19 #ifdef INCLUDE_PA 20 uint8 gain; 21 22 // Select gain (for modules with CC2590/91 only) 23 gain =appSelectGain(); 24 halRfSetGain(gain); 25 #endif 26 27 // Initialize BasicRF 初始化Basic RF 28 basicRfConfig.myAddr = RX_ADDR; 29 if(basicRfInit(&basicRfConfig)==FAILED) 30 { 31 HAL_ASSERT(FALSE); 32 } 33 //打开接收模块 34 basicRfReceiveOn(); 35 36 /* 主循环 */ 37 uartSend("PER_test: ",strlen("PER_test: ")); //串口发送数据 38 // Main loop 39 while (TRUE) 40 { 41 while(!basicRfPacketIsReady()); // 等待新的数据包 42 //查看之后发行这里的rxPacket和发送里面的txPacket是同一种数据类型 43 //basicRfReceive(指向数据缓冲区的指针,缓冲区最大数据长度,这个包的rssi值) 44 //返回缓冲区实际数据长度 45 if(basicRfReceive((uint8*)&rxPacket, MAX_PAYLOAD_LENGTH, &rssi)>0) { 46 halLedSet(2);//*************P1_1 LED2点亮 47 48 UINT32_NTOH(rxPacket.seqNumber); // 改变接收序号的字节顺序 49 segNumber = rxPacket.seqNumber; //读取包的序号 50 51 // If statistics is reset set expected sequence number to 52 // received sequence number 53 //若统计被复位,设置期望收到的数据包序号为已经收到的数据包序号 54 //怎么样被认为统计复位?在后面~ 55 if(resetStats) 56 { 57 rxStats.expectedSeqNum = segNumber; 58 59 resetStats=FALSE; 60 } 61 62 //下面这几行代码是用来计算上32个包的RSSI值的 63 //先预设一个32个长度的数组,用来存放RSSI值,一个指针,指示最旧的一个RSSI值 64 //每次获取新的包后,把最旧的RSSI值从总和处减去,再把新的RSSI值放入,并把它的值加入总和 65 // Subtract old RSSI value from sum 66 rxStats.rssiSum -= perRssiBuf[perRssiBufCounter]; // 从sum中减去旧的RSSI值 67 // Store new RSSI value in ring buffer, will add it to sum later 68 perRssiBuf[perRssiBufCounter] = rssi; // 存储新的RSSI值到环形缓冲区,之后它将被加入sum 69 rxStats.rssiSum += perRssiBuf[perRssiBufCounter]; // 增加新的RSSI值到sum 70 //如果指针超出数组最大值,复位指针 71 if(++perRssiBufCounter == RSSI_AVG_WINDOW_SIZE) { 72 perRssiBufCounter = 0; 73 } 74 75 76 //检查接收到的数据包是否是所期望收到的数据包 77 // 是所期望收到的数据包 78 if(rxStats.expectedSeqNum == segNumber) 79 { 80 rxStats.expectedSeqNum++; 81 } 82 83 // 不是所期望收到的数据包(大于期望收到的数据包的序号) 84 // 认为丢包 85 else if(rxStats.expectedSeqNum < segNumber) 86 { 87 rxStats.lostPkts += segNumber - rxStats.expectedSeqNum; 88 rxStats.expectedSeqNum = segNumber + 1; 89 } 90 91 // (小于期望收到的数据包的序号) 92 //认为是一个新的测试开始,复位统计变量 93 else 94 { 95 rxStats.expectedSeqNum = segNumber + 1; 96 rxStats.rcvdPkts = 0; 97 rxStats.lostPkts = 0; 98 } 99 rxStats.rcvdPkts++;100 101 //以下代码都是用于串口输出计算值的102 temp_receive=(int32)rxStats.rcvdPkts;103 if(temp_receive>1000)104 {105 if(halButtonPushed()==HAL_BUTTON_1){106 resetStats = TRUE;107 rxStats.rcvdPkts = 1;108 rxStats.lostPkts = 0;109 }110 }111 112 Myreceive[0]=temp_receive/100+‘0‘;113 Myreceive[1]=temp_receive%100/10+‘0‘;114 Myreceive[2]=temp_receive%10+‘0‘;115 Myreceive[3]=‘\0‘;116 uartSend("RECE:",strlen("RECE:"));117 uartSend(Myreceive,4);118 uartSend(" ",strlen(" ")); 119 120 temp_per = (int32)((rxStats.lostPkts*1000)/(rxStats.lostPkts+rxStats.rcvdPkts));121 Myper[0]=temp_per/100+‘0‘;122 Myper[1]=temp_per%100/10+‘0‘; 123 Myper[2]=‘.‘;124 Myper[3]=temp_per%10+‘0‘;125 Myper[4]=‘%‘;126 uartSend("PER:",strlen("PER:"));127 uartSend(Myper,5);128 uartSend(" ",strlen(" "));129 130 temp_rssi=(0-(int32)rxStats.rssiSum/32);131 Myrssi[0]=temp_rssi/10+‘0‘;132 Myrssi[1]=temp_rssi%10+‘0‘;133 uartSend("RSSI:-",strlen("RSSI:-"));134 uartSend(Myrssi,2); 135 uartSend("\n",strlen("\n"));136 137 halLedClear(2);138 139 halMcuWaitMs(300);140 } 141 }142 }
「ZigBee模块」组网实验-信号传输质量检测
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。