Zigbee学习之路3(单播实验)

嘿,又和大家见面了 ,下面我们就正式开始学习各种通信方式了。
言归正传, 在Zigbee网络里,模块之间要进行通信,发射模块非常明确知道接收模块的网络地址,以这个地址发送数据给接收模块,叫单播。
模块在入网的时候, 父节点随机分配网络地址给子节点,但是协调器模块在网络里的地址永远是0x0000.

下面就从单播实验说起,附件,我会上传一个我的单播实验云地址  会上传一个实验包,大家可以下载结合看

单播实验百度云地址:http://pan.baidu.com/s/1bpJ35HP



一、单个任务挂钩一个端点!!!!!!!!!!!!!


1、发送数据的流程
在SDApp.c文件里的SDApp_MY_EVT  事件处理中按钮1 按下的相关处理代码




 char theMessageData[] ="Hello lao da";//通过终端传输到协调器利用串口打印的字符串
                 
             SDApp_DstAddr.addrMode = (afAddrMode_t)Addr16Bit;
            SDApp_DstAddr.addr.shortAddr = 0x0000;//协调器接收模块的网络地址
            // Take the first endpoint, Can be changed to search through endpoints
            SDApp_DstAddr.endPoint =SDApp_ENDPOINT ;//接收模块的端点房间号
         
              
             //&SDApp_epDesc结构体 端点描述符有源端点的信息,即SDApp_ENDPOINT也是10
       AF_DataRequest( &SDApp_DstAddr, &SDApp_epDesc,
                       SDApp_CLUSTERID,//目标端点镞,房间里的接收人数据宏也是1,2个字节,所以在射频0x0001
                       (byte)osal_strlen( theMessageData ) + 1,//发送字符串的长度
                       (byte *)&theMessageData,//字符串内容数组的首地址
                       &SDApp_TransID,
                       AF_DISCV_ROUTE, AF_DEFAULT_RADIUS )




           P1SEL &=0Xfe;// 1111 1110  通过led闪烁判断数据传输次数 接收数据出现延时问题 需要的数据位 传输数据为一帧一帧的传输
           P1DIR |=0X01;
           P1_0 ^=1;




2、接收数据的流程(以函数讲解)


void SDApp_MessageMSGCB( afIncomingMSGPacket_t *pkt )
//afIncomingMSGPacket_t *pkt为无线数据包内容 
{
//  switch ( pkt->clusterId )
//  {
//    case SDApp_CLUSTERID:
//      // "the" message
//#if defined( LCD_SUPPORTED )
//      HalLcdWriteScreen( (char*)pkt->cmd.Data, "rcvd" );
Draw_BMP(0,0,128,8,BMP) ; 
//#elif defined( WIN32 )
//      WPRINTSTR( pkt->cmd.Data );
//#endif
//      LCD_P16x16Ch(8,4,pkt->cmd.Data[100]);
  
  //注,是否要以上注释内容都对数据传输运行无影响,
     Draw_BMP(0,0,128,8,BMP);
      Uart_Send_String(pkt->cmd.Data,pkt->cmd.DataLength);
//      break;
//  }
}




数据传输原理:
                            端点 (Endpoint)

1、他是一个字节编号的,数据收和发送的基本单元,在模块通信的时候,发送模块必须指定收发双方模块的网络地址和端点一致,这样,才能挂载在一起。
2、端点要使用必须要和模块里的某个任务挂钩定义;
   首先每一个端点可以看成是一个1个字节数字编号的开有一扇门的房间,数据最终的目标是进入到无线数据包指定的目标端点房间,而取无线数据这个相关的代码在任务事件处理函数里,TI协议栈有那么多的任务事件处理函数,所以必须要指定在哪个任务事件处理函数 来取这个无线数据包里面的有用数据。
3、一个端点只能挂钩在一个任务上,而一个任务可以挂钩多个端点,且端点对所有的任务是公用的,定义一个少一个。
    一个端点加入可以挂钩在多个任务上,那么接收模块接到无线数据时候,这个时候同一个端点有多个任务事件处理函数去处理,不合理;一个任务上挂多个端点(6 7 挂应用层任务),发送给协调器模块的6 7端点的数据都会进入到应用层任务事件处理函数里来,仅仅做个判断到底是投递到6房间还是7号房间就可以了。




结合代码,定义端点和任务挂钩在基础实验的代码里是那些代码 
SDApp.c
void SDApp_Init( byte task_id ) //定义了10号端点并且和这个模块的应用层任务挂钩
{
..
// Fill out the endpoint description.
  SDApp_epDesc.endPoint = 10;//SDApp_ENDPOINT; 此端点编号为10
  SDApp_epDesc.task_id = &SDApp_TaskID; 和我们应用层任务挂钩
  SDApp_epDesc.simpleDesc
            = (SimpleDescriptionFormat_t *)&SDApp_SimpleDesc;//更加详细的描述这个端点一些情况就像我们定义一个编号房间,描述房间里大概有多少人之类的信息。
  SDApp_epDesc.latencyReq = noLatencyReqs;//差不多




  // Register the endpoint description with the AF
  afRegister( &SDApp_epDesc );//这个函数必须要调用才能完成整个挂钩操作
..
}
所以,基本实验室0xA406 10 0x0000 10  无线数据包发出去以后,首先目标协调器模块的网络地址0x0000对上了,协调器可以拿到这个无线数据包在底层任务,判断10号端点房间已经定义且和我们应用层任务挂钩,那么这个无线数据包发送一个消息
到们应用层任务    
case AF_INCOMING_MSG_CMD:
          SDApp_MessageMSGCB( MSGpkt );
          break;
端点在带编号的房子,代码里一个结构体SDApp_epDesc
 在消息处理里,把hello lao da 通过串口送出去
Uart_Send_String(pkt->cmd.Data,pkt->cmd.DataLength); 


镞 ClusterID
镞就是相当于端点房间里面的人,是接收最终的目标。这东西是2个字节编号,
在射频发送的时候,必须要指定接收模块的镞,发送模块不需要指定。






二,多个任务挂钩一个端点执行!!!!!!!!!!!!!!!!




结合代码发送模块:
  在发送模块里,我们用的数据发送源端点,也是10,所以我们也定义这个10端点也挂钩应用层任务,原则上,外部给我们终端模块10号端点来数据,也会进入终端应用层任务事件处理 函数里。而我们这个端点仅仅这里作为发送模块,但是我们要实用10端点,必须要挂钩定义。
if(0==P0_1)//按钮3按下
       {
          char theMessageData[] = "hello word";
          //char themessagedata[]="hello word";
//          LS164_BYTE(3);
//         P1_1 =0;
//          LCD_CLS();
//          Draw_BMP(0,0,128,8,BMP);     //图片显示
          
          SDApp_DstAddr.addrMode = (afAddrMode_t)Addr16Bit;
            SDApp_DstAddr.addr.shortAddr = 0x0000;//接收模块的网络地址
            // Take the first endpoint, Can be changed to search through endpoints
            SDApp_DstAddr.endPoint = 7;//接收模块的端点房间号
            
           
            //发送函数 //SDApp_epDesc 结构体 端点描述符有源端点的信息,也是10
   if( AF_DataRequest( &SDApp_DstAddr, &SDApp_epDesc,
                       0x0001,//目标端点镞,房间里的接收人数据宏是1,2个字节,所以在射频0x0001
                       (byte)osal_strlen( theMessageData ) + 1,//发送字符串的长度
                       (byte *)&theMessageData, 
                                   &SDApp_TransID,
                                   AF_DISCV_ROUTE, AF_DEFAULT_RADIUS )== afStatus_SUCCESS );
           P1SEL &=0Xfe;// 1111 1110 
           P1DIR |=0X01;//此处点亮led 显示的数据为需要的数据位
           P1_0 ^=1;
       
       }
//       if(0==P2_0)
//       {//按钮4按下
//         char theMessageData[] ="hello huanhuan";
//            SDApp_DstAddr.addrMode = (afAddrMode_t)Addr16Bit;
//            SDApp_DstAddr.addr.shortAddr = 0x0000;
//            // Take the first endpoint, Can be changed to search through endpoints
//            SDApp_DstAddr.endPoint = 7;
//            
//           if( AF_DataRequest( &SDApp_DstAddr, &SDApp_epDesc,
//                                   0x0002,
//                                   (byte)osal_strlen( theMessageData ) + 1,
//                                   (byte *)&theMessageData,
//                                   &SDApp_TransID,
//                                   AF_DISCV_ROUTE, AF_DEFAULT_RADIUS )== afStatus_SUCCESS) ;
//       }
       if(0==P2_0)//按钮4按下
       {
         char theMessageData[] = "Hello huan ";
            SDApp_DstAddr.addrMode = (afAddrMode_t)Addr16Bit;
            SDApp_DstAddr.addr.shortAddr = 0x0000;
            // Take the first endpoint, Can be changed to search through endpoints
            SDApp_DstAddr.endPoint = 8;
            
            if(AF_DataRequest( &SDApp_DstAddr, &SDApp_epDesc,
                                   0x0002,
                                   (byte)osal_strlen( theMessageData ) + 1,
                                   (byte *)&theMessageData,
                                   &SDApp_TransID,
                                   AF_DISCV_ROUTE, AF_DEFAULT_RADIUS) == afStatus_SUCCESS) ;
//         P1_0=0;
//          LS164_BYTE(4);
         
//         LCD_CLS();
//        for(i=0; i<8; i++)
//        {
//            LCD_P16x16Ch(i*16,0,i);  //点阵显示
//            LCD_P16x16Ch(i*16,2,i+8);
//            LCD_P16x16Ch(i*16,4,i+16);
//            LCD_P16x16Ch(i*16,6,i+24);
//        } 
       }
接收模块:
           在SDapp.c里面,SDApp_Init函数里面添加




  SDApp_epDesc.endPoint = 7;
  SDApp_epDesc.task_id = &SDApp_TaskID;
  SDApp_epDesc.simpleDesc
            = (SimpleDescriptionFormat_t *)&SDApp_SimpleDesc;
  SDApp_epDesc.latencyReq = noLatencyReqs;




  // Register the endpoint description with the AF
  afRegister( &SDApp_epDesc );
  
  SDApp_epDesc1.endPoint = 8;//SDApp_ENDPOINT;
  SDApp_epDesc1.task_id = &SDApp_TaskID;
  SDApp_epDesc1.simpleDesc
            = (SimpleDescriptionFormat_t *)&SDApp_SimpleDesc;
  SDApp_epDesc1.latencyReq = noLatencyReqs;




  // Register the endpoint description with the AF
  afRegister( &SDApp_epDesc1 );  








当然,在前面需要声明:
    endPointDesc_t SDApp_epDesc;//7号端点的结构体 端点描述符
    endPointDesc_t SDApp_epDesc1;//8号








最后,在void SDApp_MessageMSGCB( afIncomingMSGPacket_t *pkt )函数里,
      if(7==pkt->endPoint)
  {//外来数据包要投入到7号端点房间
      switch ( pkt->clusterId )//clusterId ==镞ID
      {
          case 0x0001://led1
            Draw_BMP(0,0,128,8,BMP);//显示图片
            Uart_Send_String(pkt->cmd.Data,pkt->cmd.DataLength);将发送模块发送的字符串,接收模块接收到的数据在串口上面打印出来
            
            P1SEL &=0XFE;//1111 1110  LED1
            P1DIR |=0X01;// 
            P1_0 ^=1;
            break;
            
//          case 0x0002:
//                        Uart_Send_String(pkt->cmd.Data,pkt->cmd.DataLength);
//            P2SEL &=0XFD;// 1111 1101;
//            P2DIR |=0X02;
//            P2_1 ^=1;
//            break;    
           
      }
  }
  
    if(8==pkt->endPoint)
  {
      switch ( pkt->clusterId )
      {
          case 0x0002://led3
           LCD_CLS();   
        LCD_P8x16Str(44,0,"saler");   
        LCD_P8x16Str(20,2,"OLED DISPLAY");   




        LCD_P8x16Str(8,4,"TEL:15283869923"); 
        LCD_P6x8Str(20,6,"[email protected]");       
        LCD_P6x8Str(20,
7,"2016-11-21 23:42");   
            Uart_Send_String(pkt->cmd.Data,pkt->cmd.DataLength);
            P1SEL &=0XEF;// 1110 1111 LED3
            P1DIR |=0X10;
            
            P1_4 ^=1;
           break;
      }
  }
     


最后,使用了olcd 实现了zigbee点播数据的通信,也使用了串口显示发送的字符串
分别使用了单个镞挂载一个端点的实验,和多个镞挂载一个端点的实验  





你可能感兴趣的:(zigbee)