物联网通信_闲聊协议

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. 执行结果图

五个传感器分别代表流程图上的五个地址
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值