• CC2431 代码分析①-CC2431 喊出第一声


    CC2431 是一款可以基于RSSI 定位的 芯片。 

    定位原理,通过RSSI 强度换算距离。

    可以打个类似的比方,一个人站在群山之间,每个山头都有一个地理坐标,然后大喊一声,各个方向会返回回声,通过回声强度换算成离各个山头的距离,最后通过数学几何计算出自己站立的坐标。

    在CC2431 中实现方法是,CC2431 喊一嗓子,其他参考节点收到这个信息后,又向CC2431 喊了一嗓子。参考节点的位置是已知的,CC2431 把参考节点“喊话声音”RSSI 换算成距离,然后根据其它参考节点的位置信息通过数学几何算出自己的位置。

    CC2431 内置了硬件计算器计算数学几何,无需软件算法所以比较简单。当然可以通过软件在CC2430 上实现最后这个数学几何问题。

     其实原理很简单,实现方法也非常明了!

    具体代码

    代码直接看CC2431“喊话”

    初始化代码先不看,直接看Event相关。

        case ZDO_STATE_CHANGE:
    #if defined( RTR_NWK )
            NLME_PermitJoiningRequest( 0 );
    #endif
            /* Broadcast the X,Y location for any passive listeners in order to
             * register this node.
             */
            osal_start_timerEx( BlindNode_TaskID, BLINDNODE_FIND_EVT,
                                                  BLINDNODE_FIND_DELAY );
            break;
    
          default:
            break;
    

    当设备启动成功加入网络后都会触发时间ZDO_STATE_CHANGE,上面宏里面的code是没有执行(可以从工程中发现没有定义RTR_NWK),后面是定时执行时间BLNDNODE_FIND_EVT,而且从上面的英文可以看出CC2431 准备向any passive listensers 发信息了,也就是喊一嗓子!

    接着看BLNDNODE_FIND_EVT 这个事件是如何处理的。

      if ( events & BLINDNODE_FIND_EVT )
      {
        BlindNode_FindRequest();
    
        return ( events ^ BLINDNODE_FIND_EVT );
      }
    

    处理方法直接了当,调用了函数   BlindNode_FindRequest();

    接着往下追代码

    /*********************************************************************
     * @fn      BlindNode_FindRequest
     *
     * @brief   Start a sequence of blasts and calculate position.
     *
     * @param   none
     *
     * @return  none
     */
    void BlindNode_FindRequest( void )
    {
      if ( state == eBnIdle )
      {
        startBlast();
      }
    }
    

     从上面的code可以看到首先需要判断目前的状态state是否是idle(空闲状态),这个state是个全局变量,在初始化函数中首先被设置为idle状态。

    void BlindNode_Init( uint8 task_id )
    {
      BlindNode_TaskID = task_id;
    
      state = eBnIdle;
    
      config.loc.param_a = LOC_DEFAULT_A;
      config.loc.param_n = LOC_DEFAULT_N;
    

    这个全局变量会伴随我们分析code的很大一部分时间。

    既然满足eBnIdle那么就会调用Startblast();也就是正在开始“喊一嗓子了”

    /*********************************************************************
     * @fn      startBlast
     *
     * @brief   Start a sequence of blasts and calculate position.
     *
     * @param   none
     *
     * @return  none
     */
    static void startBlast( void )
    {
      uint8 idx;
      afAddrType_t dstAddr;
      dstAddr.addrMode = afAddrBroadcast;
      dstAddr.addr.shortAddr = NWK_BROADCAST_SHORTADDR_DEVALL;
      dstAddr.endPoint = LOCATION_REFNODE_ENDPOINT;
    
      if ((ZDO_Config_Node_Descriptor.CapabilityFlags & CAPINFO_RCVR_ON_IDLE) == 0)
      {
        // Turn the receiver on while idle - temporarily.
        idx = true;
        ZMacSetReq( ZMacRxOnIdle, &idx );
      }
      SampleApp_Sleep( FALSE );
    
      for ( idx = 0; idx < BLINDNODE_MAX_REF_NODES; idx++ )
      {
        refNodes[idx].addr = INVALID_NODE_ADDR;
      }
    
      (void)AF_DataRequest( &dstAddr, (endPointDesc_t *)&epDesc,
                             LOCATION_RSSI_BLAST, 0,
                             NULL, &transId,
                             AF_SKIP_ROUTING, 1 );
      rspCnt = 0;
      blastCnt = BLINDNODE_BLAST_COUNT;
      state = eBnBlastOut;
      osal_start_timerEx( BlindNode_TaskID, BLINDNODE_BLAST_EVT, BLINDNODE_BLAST_DELAY );
    }
    

     

    CC2431 (盲节点)调用StartBlast()喊出第一声,这也只是个开始!

    第一步先分析到这里,欲知后事,请听下回分解!

    CC2431定位套餐推荐:https://item.taobao.com/item.htm?id=527836022363

    博客讨论一些室内定位(DWM1000/CC2431/CC2530) 以及一些随性的技术。博文可以转载,但需要注明出处!
  • 相关阅读:
    HDU2149-Public Sale
    分页和多条件查询功能
    hdu 4691 最长的共同前缀 后缀数组 +lcp+rmq
    BZOJ 2588 Count on a tree (COT) 是持久的段树
    windows 设置脚本IP
    hdu 4912 Paths on the tree(树链拆分+贪婪)
    分散式-ubuntu12.04安装hadoop1.2.1
    struts详细解释拦截器
    Codeforces 459E Pashmak and Graph(dp+贪婪)
    C#中的数据格式转换 (未完待更新)
  • 原文地址:https://www.cnblogs.com/tuzhuke/p/5914347.html
Copyright © 2020-2023  润新知