打印
[牛人杂谈]

DXBT-05蓝牙通讯

[复制链接]
1148|9
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
最近买了个DXBT-05,应公司需求,必须做一对多。核心芯片用的是TI的CC2541,我在网上看,说是这个芯片在广播模式下可以实现一对多,但我找不到相对应的指令,有谁用过这个芯片吗???
沙发
huangcunxiake| | 2017-8-16 22:20 | 只看该作者
没用过啊,你去TI官网问问。

使用特权

评论回复
板凳
zhuotuzi| | 2017-8-16 23:29 | 只看该作者

1、开启广播(simpleBLEPeripheral.c的SimpleBLEPeripheral_Init中)

在应用层开启广播功能其实非常简单,只要把TRUE传给GAPRole_SetParameter函数中的GAPROLE_ADVERT_ENABLED就可以了。



使用特权

评论回复
地板
zhuotuzi| | 2017-8-16 23:31 | 只看该作者

七、解析协议栈在开启广播的操作后做了什么

1、GAPRole_SetParameter函数中的GAPROLE_ADVERT_ENABLED

case GAPROLE_ADVERT_ENABLED:  
  if ( len == sizeof( uint8 ) )  
  {  
    uint8 oldAdvEnabled = gapRole_AdvEnabled;  
    gapRole_AdvEnabled = *((uint8*)pValue);  
  
    if ( (oldAdvEnabled) && (gapRole_AdvEnabled == FALSE) )  
    {  
      // Turn off Advertising  
      if ( gapRole_state == GAPROLE_ADVERTISING )  
      {  
        VOID GAP_EndDiscoverable( gapRole_TaskID );  
      }  
    }  
    else if ( (oldAdvEnabled == FALSE) && (gapRole_AdvEnabled) )  
    {  
      // Turn on Advertising  
      if ( (gapRole_state == GAPROLE_STARTED)  
          || (gapRole_state == GAPROLE_WAITING)  
          || (gapRole_state == GAPROLE_WAITING_AFTER_TIMEOUT) )  
      {  
        VOID osal_set_event( gapRole_TaskID, START_ADVERTISING_EVT );  
      }  
    }  
  }  
  else  
  {  
    ret = bleInvalidRange;  
  }  
  break;  

其中gapRole_AdvEnabled默认是TRUE

static uint8  gapRole_AdvEnabled = TRUE;
首先,每次进到这个函数里,就会把gapRole_AdvEnabled的值保存到oldAdvEnabled,再把新的状态写到gapRole_AdvEnabled。也就是这两句:
uint8 oldAdvEnabled = gapRole_AdvEnabled;  
gapRole_AdvEnabled = *((uint8*)pValue);  


使用特权

评论回复
5
zhuotuzi| | 2017-8-16 23:32 | 只看该作者
其次,对oldAdvEnabled(旧的广播开关状态)和gapRole_AdvEnabled(新传入的广播开关状态)这两个变量进行了判断:

1)在广播状态下,想关闭广播----->关闭广播

2)在不广播的状态下,想开启广播--->开启广播

然而代码中并没有将另外两种情况编写进来,也就是

3)在广播状态下,还想开启广播

4)在不广播的状态下,还想关闭广播

协议栈把这两种情况划入了else的bleInvalidRange。


第2)种情况的开广播,调用了gapRole_TaskID任务中的START_ADVERTISING_EVT事件。
else if ( (oldAdvEnabled == FALSE) && (gapRole_AdvEnabled) )  
{  
  // Turn on Advertising  
  if ( (gapRole_state == GAPROLE_STARTED)  
      || (gapRole_state == GAPROLE_WAITING)  
      || (gapRole_state == GAPROLE_WAITING_AFTER_TIMEOUT) )  
  {  
    VOID osal_set_event( gapRole_TaskID, START_ADVERTISING_EVT );  
  }  
}  

2、START_ADVERTISING_EVT事件
if ( events & START_ADVERTISING_EVT )  
{  
  if ( gapRole_AdvEnabled )  
  {  
    gapAdvertisingParams_t params;  
  
    // Setup advertisement parameters  
    params.eventType = gapRole_AdvEventType;  
    params.initiatorAddrType = gapRole_AdvDirectType;  
    VOID osal_memcpy( params.initiatorAddr, gapRole_AdvDirectAddr, B_ADDR_LEN );  
    params.channelMap = gapRole_AdvChanMap;  
    params.filterPolicy = gapRole_AdvFilterPolicy;  
  
    if ( GAP_MakeDiscoverable( gapRole_TaskID, ¶ms ) != SUCCESS )  
    {  
      gapRole_state = GAPROLE_ERROR;  
        
      // Notify the application with the new state change  
      if ( pGapRoles_AppCGs && pGapRoles_AppCGs->pfnStateChange )  
      {  
        pGapRoles_AppCGs->pfnStateChange( gapRole_state );  
      }  
    }  
  }  
  return ( events ^ START_ADVERTISING_EVT );  
}  

事件中调用GAP_MakeDiscoverable即可开启广播。
如果广播不成功,则会调用函数指针pGapRoles_AppCGs指向的回调函数,并且传入参数GAPROLE_ERROR,以此来通知应用层广播不成功。

那么调用的又是哪个回调函数呢?

追踪一下pGapRoles_AppCGs发现有个注册回调函数的函数
/********************************************************************* 
* [url=home.php?mod=space&uid=247401]@brief[/url]   Does the device initialization.
*
* Public function defined in peripheral.h.
*/  
bStatus_t GAPRole_StartDevice( gapRolesCBs_t *pAppCallbacks )  
{  
  if ( gapRole_state == GAPROLE_INIT )  
  {  
    // Clear all of the Application callbacks  
    if ( pAppCallbacks )  
    {  
      pGapRoles_AppCGs = pAppCallbacks;  
    }  
  
    // Start the GAP  
    gapRole_SetupGAP();  
  
    return ( SUCCESS );  
  }  
  else  
  {  
    return ( bleAlreadyInRequestedMode );  
  }  
}  

使用特权

评论回复
6
zhuotuzi| | 2017-8-16 23:33 | 只看该作者
再追踪一下这个注册函数,发现在应用层的SBP_START_DEVICE_EVT事件中对此进行了注册
if ( events & SBP_START_DEVICE_EVT )  
{  
  // Start the Device  
  VOID GAPRole_StartDevice( &simpleBLEPeripheral_PeripheralCBs );  
  
  // Start Bond Manager  
  VOID GAPBondMgr_Register( &simpleBLEPeripheral_BondMgrCBs );  
  
  // Set timer for first periodic event  
  osal_start_timerEx( simpleBLEPeripheral_TaskID, SBP_PERIODIC_EVT, SBP_PERIODIC_EVT_PERIOD );  
  
  return ( events ^ SBP_START_DEVICE_EVT );  
}  
所以当广播开启不成功之后,会调用simpleBLEPeripheral_PeripheralCBs的回调函数peripheralStateNotificationCB的GAPROLE_ERROR
// GAP Role Callbacks  
static gapRolesCBs_t simpleBLEPeripheral_PeripheralCBs =  
{  
  peripheralStateNotificationCB,  // Profile State Change Callbacks  
  NULL                            // When a valid RSSI is read from controller (not used by application)  
};  
case GAPROLE_ERROR:  
  {  
    #if (defined HAL_LCD) && (HAL_LCD == TRUE)  
      HalLcdWriteString( "Error",  HAL_LCD_LINE_3 );  
    #endif // (defined HAL_LCD) && (HAL_LCD == TRUE)  
  }  
  break;
到此,广播过程就结束了,很简单吧,哈哈。

使用特权

评论回复
7
稳稳の幸福| | 2017-8-17 16:08 | 只看该作者
楼上的讲的对吗。

使用特权

评论回复
8
shen_hao|  楼主 | 2017-8-18 10:14 | 只看该作者
zhuotuzi 发表于 2017-8-16 23:29
1、开启广播(simpleBLEPeripheral.c的SimpleBLEPeripheral_Init中)在应用层开启广播功能其实非常简单,只 ...

谢谢回答:

请问应用层指的是??手机吗?你这些函数调用库是哪里的库???我这个蓝牙模块是要和单片机相连的,请问在这个情况,可以调用这个函数吗??

希望解答

使用特权

评论回复
9
shen_hao|  楼主 | 2017-8-18 10:15 | 只看该作者
zhuotuzi 发表于 2017-8-16 23:31
七、解析协议栈在开启广播的操作后做了什么1、GAPRole_SetParameter函数中的GAPROLE_ADVERT_ENABLED其中gap ...

谢谢回答:

请问应用层指的是??手机吗?你这些函数调用库是哪里的库???我这个蓝牙模块是要和单片机相连的,请问在这个情况,可以调用这个函数吗??

希望解答

使用特权

评论回复
10
shen_hao|  楼主 | 2017-8-18 10:17 | 只看该作者
zhuotuzi 发表于 2017-8-16 23:32
其次,对oldAdvEnabled(旧的广播开关状态)和gapRole_AdvEnabled(新传入的广播开关状态)这两个变量进行 ...

谢谢回答:

请问应用层指的是??手机吗?你这些函数调用库是哪里的库???我这个蓝牙模块是要和单片机相连的,请问在这个情况,可以调用这个函数吗??

希望解答

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

79

主题

230

帖子

2

粉丝