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) 以及一些随性的技术。博文可以转载,但需要注明出处!
原文地址:https://www.cnblogs.com/tuzhuke/p/5914347.html