zoukankan      html  css  js  c++  java
  • CC2530自动安全联网

    CC2530自动联网的苦恼

    不知道博客园里面有没有人研究CC2530,也就是zigbee技术,其实我在做东西的时候很纠结一个问题,那就是我如何将设备连上后,如何通过协调者发送命令给终端呢?有什么方法可以快捷的解决这个事情呢?zigbee确实是让我们能够直接形成一个网络了,但是我们要的是能够在协调者里面直接找到相应的终端,然后直接相连不就行了吗,这样又快又好!但是在这个过程中我们经常碰到是,我们根本找不到目标终端!

    • zigbee的协调者是会给终端随机分配一个16位的短地址
    • CC2530虽然有IEEE的长地址,但是这个长地址在获取的过程中相当复杂
    • CC2530也没有非常好的demo来解决

    我的思考与想法

    既然我们无法容易的得到长地址,而且长地址的数据量也是有点大的,光使用协议,每次都输相应的长地址,这不是找死是什么,闲自己的数据还不够多吗?于是我思考了一段时间,哈哈哈,为什么我们不能自己建立映射表来对应相应的短地址,就像一张表格一样。或者说像数据库的模式学习,一个是标题栏,一个是值,这个值是短地址,但是标题栏永远不会变不就可以了吗?

    动手实现一下

    那么从何开始呢?我们不能乱碰啊!首先你得知道咋么建立网络连接吧!,等等,有人说:我没有安装文件,你说的z-stack2007那个玩意在哪呢?好吧,我把它放出来!TI的官网上早就没有这个了,因为它是version2.5a的 现在的是TI的 z-stack home 是version2.6a版的,笔者比较懒,没想用2.6a的,原因嘛~~~因为不高兴再使用新的工具去调了!

    z-satck-version 2.5

    开发工具及注册机 IAR 8.10版

    分析一下自带的zigbee的联网

    在sampleapp.c中我们来看看zigbee是如何联网的!

    afAddrType_t SampleApp_Periodic_DstAddr;
    afAddrType_t SampleApp_Flash_DstAddr;
    

    afAddrType_t 没错就是这个东西,不明白,没关系,我们使用go to defintion 去看看它是如何定义的!

    typedef enum
    {
      afAddrNotPresent = AddrNotPresent, //按照绑定表进行绑定传输
      afAddr16Bit      = Addr16Bit,// 指定目标网络地址进行单薄传输 16位
      afAddr64Bit      = Addr64Bit,
      afAddrGroup      = AddrGroup,// 组播传输 
      afAddrBroadcast  = AddrBroadcast//广播传输 
    } afAddrMode_t;
    
    typedef struct
    {
      union
      {
        uint16      shortAddr;//随机分配的短地址
        ZLongAddr_t extAddr;
      } addr;
      afAddrMode_t addrMode;//afAddrMode_t是一个枚举类型 模式参数
      uint8 endPoint;  //指定的端点号 端点241—254保留端点 范围 1-240
      uint16 panId;  // 加入的panid 就是在哪个网段上
    } afAddrType_t;
    

    看到我上面的注释了吧? 哈哈,那么我们就可以模仿它来写我们的网络协议
    回到sampleapp.c我们添加自己的对点网络。

    afAddrType_t SampleApp_Periodic_DstAddr;
    afAddrType_t SampleApp_Flash_DstAddr;
    /**自己定义的点对点的传输**/
    
      afAddrType_t SampleApp_Point_to_Point_DstAddr;
    
    /**************/
    

    ok了,那么我们上面不是说了要用映射的形式 对不对?

    uint16 Routing_Table[DEV_COUNT][1]={0} 定义路由表单那是必须的 你有多少个zigbee你就得用多少的DEV_COUNT

    这个呢就直接放在我们点对点的传输定义的下面就可以了!

      // Setup for the periodic message's destination address
      // Broadcast to everyone
      SampleApp_Periodic_DstAddr.addrMode = (afAddrMode_t)AddrBroadcast;
      SampleApp_Periodic_DstAddr.endPoint = SAMPLEAPP_ENDPOINT;
      SampleApp_Periodic_DstAddr.addr.shortAddr = 0xFFFF;
    
      // Setup for the flash command's destination address - Group 1
      SampleApp_Flash_DstAddr.addrMode = (afAddrMode_t)afAddrGroup;
      SampleApp_Flash_DstAddr.endPoint = SAMPLEAPP_ENDPOINT;
      SampleApp_Flash_DstAddr.addr.shortAddr = SAMPLEAPP_FLASH_GROUP;
    

    往下翻,你看到了吗?没错,这个就是配置我们网络模式的函数了,可以与上面的afAddrType_t定义的内容一一对应哦!
    好了 我们也可以通过自己的方法写自己的配置模式!

      // Setup for the flash command's destination address - Group 1
      SampleApp_Flash_DstAddr.addrMode = (afAddrMode_t)afAddrGroup;
      SampleApp_Flash_DstAddr.endPoint = SAMPLEAPP_ENDPOINT;
      SampleApp_Flash_DstAddr.addr.shortAddr = SAMPLEAPP_FLASH_GROUP;
    /***设定点对点的地址方案****/
      SampleApp_Point_to_Point_DstAddr.addrMode = (afAddrMode_t)Addr16Bit;//点对点模式
      SampleApp_Point_to_Point_DstAddr.endPoint = SAMPLEAPP_ENDPOINT;
      SampleApp_Point_to_Point_DstAddr.addr.shortAddr = 0xffff;//数据从发给全部设备
    /********************************/
    

    找到这个函数uint16 SampleApp_ProcessEvent( uint8 task_id, uint16 events )没错这个函数其实是发送处理函数。

    发送端处理

    uint8 buffer[4];//存放加入网络的数据
                buffer[0] = 'm';
                buffer[1] = DEV_NUM;// 设备号 你需要自己定义         
                buffer[2] = 1;
                buffer[3] = 'g';
                SampleApp_Point_to_Point_DstAddr.addr.shortAddr = 0x0000;
                if ( AF_DataRequest( &SampleApp_Point_to_Point_DstAddr,
                           &SampleApp_epDesc,
                           SAMPLEAPP_ADDNET_CLUSTERID,
                           4,
                           buffer,
                           &SampleApp_TransID,
                           AF_DISCV_ROUTE | AF_ACK_REQUEST,
                           AF_DEFAULT_RADIUS ) == afStatus_SUCCESS )
                       {
                          #ifdef DEBUG_STAGE
                                   HalUARTWrite(0,"Init EndPoint
    
    ",sizeof("Init EndPoint
    
    "));
                                 //HalLedSet(LED1,LED_ON);
                          #endif 
                       }
                    else
                      {
                      // Error occurred in request to send.
                       }
                /*****原函数被注释
                // Start sending the periodic message in a regular interval.
                osal_start_timerEx( SampleApp_TaskID,
                                  SAMPLEAPP_SEND_PERIODIC_MSG_EVT,
                                  SAMPLEAPP_SEND_PERIODIC_MSG_TIMEOUT );
                */
    

    接收端处理

    找到这个函数void SampleApp_MessageMSGCB( afIncomingMSGPacket_t *pkt )这个是接受端的处理函数

          uint8 *str = NULL;
          uint8 buffer[4];//用于处理应答
          uint16 shortaddr;//用来存放短地址
          str = pkt->cmd.Data;
          switch ( pkt->clusterId )
    { 
       case SAMPLEAPP_ADDNET_CLUSTERID://入网处理
         
              if(pkt->cmd.Data[0]=='m' && pkt->cmd.Data[3]=='g' && pkt->srcAddr.addr.shortAddr != 0)
              {
                HalLedSet(LED1,LED_ON);//协调者led1亮 表示找到了网络
                shortaddr = pkt->srcAddr.addr.shortAddr;//把收到的终端的地址保存
                Routing_Table[pkt->cmd.Data[1]][pkt->cmd.Data[2]] = shortaddr;  //对应的房间设备的路由表建立                    
               
                         HalUARTWrite(0,&asc_16[Routing_Table[pkt->cmd.Data[1]][pkt->cmd.Data[2]]/4096],1);
                         HalUARTWrite(0,&asc_16[Routing_Table[pkt->cmd.Data[1]][pkt->cmd.Data[2]]%4096/256],1);
                         HalUARTWrite(0,&asc_16[Routing_Table[pkt->cmd.Data[1]][pkt->cmd.Data[2]]%256/16],1);
                         HalUARTWrite(0,&asc_16[Routing_Table[pkt->cmd.Data[1]][pkt->cmd.Data[2]]%16],1);
            
                 buffer[0] = 'r';//进行回复          
                 buffer[1] = 0;
                 buffer[2] = 0;
                 buffer[3] = 'a';
                 SampleApp_Point_to_Point_DstAddr.addr.shortAddr = shortaddr;//并把应答信息发送给终端 入网成功
                 if ( AF_DataRequest( &SampleApp_Point_to_Point_DstAddr, &SampleApp_epDesc,
                               SAMPLEAPP_ADDNET_CLUSTERID,
                               4,
                               buffer,
                               &SampleApp_TransID,
                               AF_DISCV_ROUTE | AF_ACK_REQUEST,
                               AF_DEFAULT_RADIUS ) == afStatus_SUCCESS )
                {
                 //  HalUARTWrite(0,"get searchmsg
    
    ",sizeof("get searchmsg
    
    "));      
                 //  HalUARTWrite(0,"bind one end",12);
                   HalLedSet(LED1,LED_OFF);//协调者led1灯灭 表示曾找到网络
                }
                else
                {
                  // Error occurred in request to send.
                }
             }
    

    然后我们对接受到的数据信息进行分析,有头带m尾g的我们就入网,且回应协调者r00a 我收到了的意思

    SAMPLEAPP_ADDNET_CLUSTERID这个又是从哪冒出来的呢? 嘿嘿就在sampleapp.c的头文件里面添加自己的轮回任务ID

    申明

    如果您转了我的文章呢,非常之感谢,但请您表明一下出处就可以了,一个链接的事情嘛~~再次感谢各位对我的支持!

  • 相关阅读:
    UITabBarController生命周期(使用storyoard搭建)
    ios应用数据存储方式(归档)
    ios应用数据存储方式(偏好设置)
    使用picker View控件完成一个简单的选餐应用
    ios应用数据存储方式(XML属性列表-plist)
    控制器的View的创建
    控制器的创建
    权限管理具体代码实现
    gitHub相关
    初始Ajax
  • 原文地址:https://www.cnblogs.com/samuelwnb/p/4250859.html
Copyright © 2011-2022 走看看