1. 流程图
2. 执行过程
- 发送端给转发端广播一个hello的数据包
- 转发端接收到hello数据包后,p2p发送一个ack数据包给发送端
- 发送端接收到ack后解析,随机选择一个地址p2p发送光照数据
- 假设光照数据发送给了4407,则转发端4407转发光照数据给接受端
- 接收端接收显示数据
3. 源码
#include <iocc2530.h>
#include "hal_mcu.h"
#include "hal_assert.h"
#include "hal_board.h"
#include "hal_rf.h"
#include "basic_rf.h"
#include <stdio.h>
#include "info.h"
#include "string.h"
#include <stdlib.h>
#define RF_CHANNEL 12 // 2.4 GHz RF channel
#define PAN_ID 0x1810 // 班级
#define SEND_ADDR 0x4402 // 发送
#define RECV_ADDR 0x4404 // 接收
#define TRUN_ADDR 0x4407 // 转发 0x4407 0x4408 0x4409
#define NODE_TYPE 1 //0:接收节点,1:发送节点, 2转发节点
static basicRfCfg_t basicRfConfig;
static int address_three[3]; //存放三个地址
void send_sun(void){
uint8 ret; //判断光照数据的发送
int j;
static unsigned int send_counter = 0; //发送次数计数器
j=(int)(2*rand()/(RAND_MAX+1.0)); //随机生成一个0-2之间的一个整数
while(TRUE){
char pTxData[128]; //定义数据包
int AdcValue; //光照数据
AdcValue = getADC();
sprintf(pTxData,"%d\r\n",AdcValue);
//随机选择一个地址进行发送
ret = basicRfSendPacket(address_three[j], (uint8*)pTxData, sizeof pTxData);
printf("{data=send node send %d times}",++send_counter); //在LCD上显示发送次数
if (ret == SUCCESS) {
hal_led_on(1);
halMcuWaitMs(100);
hal_led_off(1);
halMcuWaitMs(900);
} else {
hal_led_on(1);
halMcuWaitMs(1000);
hal_led_off(1);
}
}
}
//根据传来的ack存储地址到数组
void selected_Ack(char* Ackdata ){
char* a7 = "a";
char* a8 = "b";
char* a9 = "c";
if(strcmp(a7, Ackdata) == 0){ //如果ack = a,就将0x4407地址信息存储到数组脚标0的位置
address_three[0] = 0x4407;
}
if(strcmp(a8, Ackdata) == 0){ //如果ack = b,就将0x4408地址信息存储到数组脚标1的位置
address_three[1] = 0x4408;
}
if(strcmp(a9, Ackdata) == 0){ //如果ack = c,就将0x4409地址信息存储到数组脚标2的位置
address_three[2] = 0x4409;
}
}
/* 射频模块发送数据函数 */
void rfSendData(void){
int reln;
char hellodata[20] = {'h','e','l','l','o'}; //一个hello数据包
uint8 Ackdata[30]; //转发节点 传来的ack数据包
int length_addr; //地址数组内元素个数
basicRfReceiveOn(); //开启射频接收器
while (TRUE) {
//广播hello数据包
basicRfSendPacket(0xffff, (uint8*)hellodata, sizeof hellodata);
//接受传来的ack包
while(!basicRfPacketIsReady());
reln = basicRfReceive(Ackdata, sizeof Ackdata, NULL);
if(reln> 0) {
Ackdata[reln] = 0;
printf("{data="); //将收到的
printf((char *)Ackdata); //数据
printf("}"); //在LCD上显示出来
}
selected_Ack((char *)Ackdata); //根据传来的ack包将三个地址存储到数组上
length_addr = sizeof(address_three)/sizeof(address_three[0]); //得到地址数组的元素个数
if(length_addr == 3){ //如果传来三个地址了就跳出循环
break;
}
}
send_sun(); //发送光照数据
}
//p2p发送ack 给发送地址
int Turn_ack(void){
char Ackdata[30]; //需要发送的ack数据包
int ret;
switch(TRUN_ADDR) //根据地址来给ack数据包赋值
{
case 0x4407:
Ackdata[0]='a';
break;
case 0x4408:
Ackdata[0]='b';
break;
case 0x4409:
Ackdata[0]='c';
break;
}
//给发送节点 发送ack数据包
ret = basicRfSendPacket(SEND_ADDR, (uint8*)Ackdata, sizeof Ackdata);
return ret;
}
//转发结点:接受hello数据包,p2p发送ack和广播光照数据包
void TURN(void)
{
int rlen_two; //判断接收的hello包
uint8 ret; //判断发送的ack包
int rlen; //判断接收光照数据包
uint8 apRxData[128]; //光照数据
uint8 hellodata[20]; //接收的 hello的数据包
static unsigned int rec_counter = 0; //发送次数计数器
printf("{data=recv node start up...}");
basicRfReceiveOn(); //开启射频接收器
while (TRUE) {
while(!basicRfPacketIsReady());
rlen_two = basicRfReceive(hellodata, sizeof hellodata, NULL); //接受到的hello数据包
if(rlen_two>0) //如果接收到hello数据包了
{
//p2p发送ack到 发送节点
ret = Turn_ack();
if (ret == SUCCESS) //如果ack发送成功
{
//接受光照数据
rlen = basicRfReceive(apRxData, sizeof apRxData, NULL);
if(rlen > 0) { //如果接受到光照数据
apRxData[rlen] = 0;
printf("{data="); //将收到的
printf((char *)apRxData); //数据和
printf("counter %d",++rec_counter); //接收到数据的次数
printf("}"); //在LCD上显示出来
//本来下一行的步骤应该和发送节点一致,就是改一下Turn_ack()和selected_Ack 的3个地址信息就行
//为了减少代码修改,我直接p2p发送给:接收节点
basicRfSendPacket(0x4404, (uint8*)apRxData, sizeof apRxData);
}
}
}
}
}
/* 射频模块接收数据函数 */
void rfRecvData(void)
{
uint8 pRxData[128]; //存放光照数据
int rlen;
static unsigned int rec_counter = 0; //发送次数计数器
printf("{data=recv node start up...}");
basicRfReceiveOn(); //开启射频接收器
// Main loop
while (TRUE) {
while(!basicRfPacketIsReady());
rlen = basicRfReceive(pRxData, sizeof pRxData, NULL);
if(rlen > 0) {
pRxData[rlen] = 0;
printf("{data="); //将收到的
printf((char *)pRxData); //数据和
printf("counter %d",++rec_counter); //接收到数据的次数
printf("}"); //在LCD上显示出来
if (pRxData > 1000){ //当接受到的光敏数据大于1000 D7灯就亮
hal_led_on(7);
}else{
hal_led_off(7);
}
}
}
}
// uint8 ret;
// basicRfReceiveOff(); //关闭射频接收器
int getADC(void)
{
unsigned int value;
P0SEL |= 0x02;
ADCCON3 = (0xB1); //选择AVDD5为参考电压;12分辨率;P0_1 ADC
ADCCON1 |= 0x30; //选择ADC的启动模式为手动
ADCCON1 |= 0x40; //启动AD转化
while(!(ADCCON1 & 0x80)); //等待ADC转化结束
value = ADCL >> 2;
value |= (ADCH << 6); //取得最终转化结果,存入value中
return ((value) >> 2);
}
void main(void)
{
halMcuInit(); //初始化mcu
hal_led_init(); //初始化LED
hal_uart_init(); //初始化串口
lcd_dis(); //在LCD上显示实验内容、MAC地址等相关信息
if (FAILED == halRfInit()) { // halRfInit()为射频初始化函数
HAL_ASSERT(FALSE);
}
// Config basicRF
basicRfConfig.panId = PAN_ID; //panId
basicRfConfig.channel = RF_CHANNEL; //通信信道
basicRfConfig.ackRequest = TRUE; //应答请求
#ifdef SECURITY_CCM
basicRfConfig.securityKey = key; //安全秘钥
#endif
// Initialize BasicRF
switch(NODE_TYPE)
{
case 0:
basicRfConfig.myAddr = RECV_ADDR; //接收地址
break;
case 1:
basicRfConfig.myAddr = SEND_ADDR; //发送地址
break;
case 2:
basicRfConfig.myAddr = TRUN_ADDR;
break;
}
if(basicRfInit(&basicRfConfig)==FAILED) {
HAL_ASSERT(FALSE);
}
switch(NODE_TYPE)
{
case 0:
rfRecvData(); //接收数据
break;
case 1:
rfSendData(); //发送数据
break;
case 2:
TURN();
break;
}
}
4. 执行结果图
五个传感器分别代表流程图上的五个地址