基于蓝牙协议栈的CC2540蓝牙广播

我使用的是官方的协议栈,下载地址在这里:链接:https://pan.baidu.com/s/1kpzgGxyuqLQLheLdu90PTQ?pwd=0000 
提取码:0000

下载好协议栈后我们打开协议栈的文件夹,找到BLE-CC254x-1.5.2.0\Projects\ble\SimpleBLEPeripheral\CC2540DB

然后打开2540的工程,看到协议栈的结构如下:

  • SimpleBLEPeripheral:是主要的应用程序文件夹,包含了实现 BLE 外围设备功能的源代码和头文件。appBLEPeripheral.c 是应用程序的入口点,负责初始化和配置 BLE 协议栈和硬件。osal_SimpleBLEPeripheral.c 是操作系统抽象层 (OSAL) 的文件,负责管理任务和事件。SimpleBLEPeripheral.h 是头文件,定义了一些常量和变量。
  • HAL:是硬件抽象层 (HAL) 的文件夹,包含了 hal.h 头文件,用于包含所有 HAL 模块的头文件。HAL 模块提供了一些通用的硬件接口和功能,例如 ADC, GPIO, LCD, LED, UART 等。
  • LIB:是库文件夹,包含了 lib.h 头文件,用于包含一些通用的库函数的头文件,库函数提供了一些基本的数据类型,内存管理,调试,错误处理等功能。
  • INCLUDE:是包含文件夹,包含了 include.h 头文件,用于包含一些 BLE 协议栈相关的头文件。这些头文件定义了一些 BLE 协议栈的数据结构,常量,枚举,函数等。
  • OSAL:是操作系统抽象层 (OSAL) 的文件夹,包含了一些 OSAL 相关的源代码和头文件。OSAL 提供了一些操作系统相关的功能,例如任务管理,事件处理,定时器,信号量,互斥锁,非易失性存储等。
  • PROFILES:是 BLE 服务和特征的文件夹,包含了一些实现 BLE 服务和特征的源代码和头文件。这些文件定义了一些 BLE 服务和特征的 UUID, 属性, 值, 回调函数等。
  • TOOLS:这个文件夹是工具文件夹,包含了一些辅助的工具文件

大概了解了项目结构,加下来来看看代码是如何运行的~

SimpleBLEPeripheral_Main是是 BLE 协议栈的入口点,即从该函数开始执行

意思即,当我们编译运行协议栈时,以下函数将从上到下依次运行进行各项初始化

蓝牙参数修改

BLE参数配置位于simpleBLEPeripheral.c


// How often to perform periodic event
#define SBP_PERIODIC_EVT_PERIOD                   5000  //这是一个周期性事件的间隔,单位是毫秒,表示每隔 5000 毫秒执行一次周期性事件,例如检查电池电量,更新连接参数等。

// What is the advertising interval when device is discoverable (units of 625us, 160=100ms)
#define DEFAULT_ADVERTISING_INTERVAL          160       //广播间隔,单位是 625 微秒,表示设备在可发现模式下的广播周期,160 表示 100 毫秒。

// Limited discoverable mode advertises for 30.72s, and then stops
// General discoverable mode advertises indefinitely


//发现模式,有两种选择,一种是有限可发现模式,表示设备只广播 30.72 秒,然后停止;
//另一种是一般可发现模式,表示设备无限期地广播。这个宏的值取决于是否定义了 CC2540_MINIDK 宏,如果定义了,就是有限可发现模式,否则就是一般可发现模式。
#if defined ( CC2540_MINIDK )
#define DEFAULT_DISCOVERABLE_MODE             GAP_ADTYPE_FLAGS_LIMITED
#else
#define DEFAULT_DISCOVERABLE_MODE             GAP_ADTYPE_FLAGS_GENERAL
#endif  // defined ( CC2540_MINIDK )

// Minimum connection interval (units of 1.25ms, 80=100ms) if automatic parameter update request is enabled
#define DEFAULT_DESIRED_MIN_CONN_INTERVAL     80        //最小连接间隔,单位是 1.25 毫秒,表示如果启用了自动连接参数更新请求,设备希望的最小连接间隔,80 表示 100 毫秒。

// Maximum connection interval (units of 1.25ms, 800=1000ms) if automatic parameter update request is enabled
#define DEFAULT_DESIRED_MAX_CONN_INTERVAL     800       //最大连接间隔,单位是 1.25 毫秒,表示如果启用了自动连接参数更新请求,设备希望的最大连接间隔,800 表示 1000 毫秒。

// Slave latency to use if automatic parameter update request is enabled
#define DEFAULT_DESIRED_SLAVE_LATENCY         0         //从机延迟,表示如果启用了自动连接参数更新请求,设备允许的最大连续丢失连接事件的次数,0 表示不允许丢失任何连接事件。

// Supervision timeout value (units of 10ms, 1000=10s) if automatic parameter update request is enabled
#define DEFAULT_DESIRED_CONN_TIMEOUT          1000      //连接超时,单位是 10 毫秒,表示如果启用了自动连接参数更新请求,设备允许的最大连接事件间隔,1000 表示 10 秒。

// Whether to enable automatic parameter update request when a connection is formed
#define DEFAULT_ENABLE_UPDATE_REQUEST         TRUE      //表示是否启用自动连接参数更新请求,当设备与中心设备建立连接后,是否向中心设备发送连接参数更新请求,TRUE 表示启用,FALSE 表示禁用。

// Connection Pause Peripheral time value (in seconds)
#define DEFAULT_CONN_PAUSE_PERIPHERAL         6         //连接暂停外围设备的时间值,单位是秒,表示当设备与中心设备建立连接后,多长时间内不允许中心设备发起连接参数更新请求,6 表示 6 秒。

// Company Identifier: Texas Instruments Inc. (13)
#define TI_COMPANY_ID                         0x000D    //公司标识符,表示设备的制造商,0x000D 表示 Texas Instruments Inc. 

#define INVALID_CONNHANDLE                    0xFFFF    //一个无效的连接句柄,表示设备没有与任何中心设备建立连接,0xFFFF 表示无效值

// Length of bd addr as a string
#define B_ADDR_STR_LEN                        15        //蓝牙地址字符串的长度,表示设备的蓝牙地址转换为字符串后的字符数,15 表示 15 个字符,例如 “00:12:34:56:78:9A”。

/*********************************************************************
 * TYPEDEFS
 */

/*********************************************************************
 * GLOBAL VARIABLES
 */

/*********************************************************************
 * EXTERNAL VARIABLES
 */

/*********************************************************************
 * EXTERNAL FUNCTIONS
 */

/*********************************************************************
 * LOCAL VARIABLES
 */
static uint8 simpleBLEPeripheral_TaskID;   // Task ID for internal task/event processing

static gaprole_States_t gapProfileState = GAPROLE_INIT;

// GAP - SCAN RSP data (max size = 31 bytes)
/*
*       这里是修改广播标识的,可以修改为自己喜欢的广播名称
*/
static uint8 scanRspData[] =
{
  // complete name
  0x14,   // length of this data
  GAP_ADTYPE_LOCAL_NAME_COMPLETE,
  0x53,   // 'S'
  0x69,   // 'i'
  0x6d,   // 'm'
  0x70,   // 'p'
  0x6c,   // 'l'
  0x65,   // 'e'
  0x42,   // 'B'
  0x4c,   // 'L'
  0x45,   // 'E'
  0x50,   // 'P'
  0x65,   // 'e'
  0x72,   // 'r'
  0x69,   // 'i'
  0x70,   // 'p'
  0x68,   // 'h'
  0x65,   // 'e'
  0x72,   // 'r'
  0x61,   // 'a'
  0x6c,   // 'l'

  // connection interval range
  0x05,   // length of this data
  GAP_ADTYPE_SLAVE_CONN_INTERVAL_RANGE,
  LO_UINT16( DEFAULT_DESIRED_MIN_CONN_INTERVAL ),   // 100ms
  HI_UINT16( DEFAULT_DESIRED_MIN_CONN_INTERVAL ),
  LO_UINT16( DEFAULT_DESIRED_MAX_CONN_INTERVAL ),   // 1s
  HI_UINT16( DEFAULT_DESIRED_MAX_CONN_INTERVAL ),

  // Tx power level
  0x02,   // length of this data
  GAP_ADTYPE_POWER_LEVEL,
  0       // 0dBm
};

最后简单分析一下OSAL:

/*********************************************************************
 * GLOBAL VARIABLES
 */

// The order in this table must be identical to the task initialization calls below in osalInitTask.

/*
*  定义了一个任务处理函数的数组,包含了各个协议栈层和应用层的事件处理函数;
*/
const pTaskEventHandlerFn tasksArr[] =
{
  LL_ProcessEvent,                                                  // task 0
  Hal_ProcessEvent,                                                 // task 1
  HCI_ProcessEvent,                                                 // task 2
#if defined ( OSAL_CBTIMER_NUM_TASKS )
  OSAL_CBTIMER_PROCESS_EVENT( osal_CbTimerProcessEvent ),           // task 3
#endif
  L2CAP_ProcessEvent,                                               // task 4
  GAP_ProcessEvent,                                                 // task 5
  SM_ProcessEvent,                                                  // task 6
  GATT_ProcessEvent,                                                // task 7
  GAPRole_ProcessEvent,                                             // task 8
  GAPBondMgr_ProcessEvent,                                          // task 9
  GATTServApp_ProcessEvent,                                         // task 10
  SimpleBLEPeripheral_ProcessEvent                                  // task 11
};

/*
*  定义了一个任务数量的常量,等于任务处理函数数组的长度;
*/
const uint8 tasksCnt = sizeof( tasksArr ) / sizeof( tasksArr[0] );

/*
*  定义了一个任务事件的指针,用于存储每个任务的事件标志;
*/
uint16 *tasksEvents;

/*********************************************************************
 * FUNCTIONS
 *********************************************************************/

/*********************************************************************
 * @fn      osalInitTasks
 *
 * @brief   This function invokes the initialization function for each task.
 *
 * @param   void
 *
 * @return  none
 */

/*
*  在osalInitTasks函数中,为每个任务分配一个任务ID,并调用相应的初始化函数;
*/
void osalInitTasks( void )
{
  uint8 taskID = 0;

  tasksEvents = (uint16 *)osal_mem_alloc( sizeof( uint16 ) * tasksCnt);

  /* The tasksEvents allocated pointer must be valid */
  
  /*
   *  为每个任务分配一块内存空间,用于存储任务事件标志,并将其清零;
   */
  if (tasksEvents != NULL)
  {
  	osal_memset( tasksEvents, 0, (sizeof( uint16 ) * tasksCnt));
  }
  else
  {
    HAL_ASSERT_FORCED();
  }
  
  /*
  *  调用LL、Hal、HCI、L2CAP、GAP、SM、GATT、GAPRole、GAPBondMgr、GATTServApp和SimpleBLEPeripheral等模块的初始化函数,完成各个模块的配置;
  */
  
  /* LL Task */
  LL_Init( taskID++ );

  /* Hal Task */
  Hal_Init( taskID++ );

  /* HCI Task */
  HCI_Init( taskID++ );

#if defined ( OSAL_CBTIMER_NUM_TASKS )
  /* Callback Timer Tasks */
  osal_CbTimerInit( taskID );
  taskID += OSAL_CBTIMER_NUM_TASKS;
#endif

  /* L2CAP Task */
  L2CAP_Init( taskID++ );

  /* GAP Task */
  GAP_Init( taskID++ );

  /* SM Task */
  SM_Init( taskID++ );
  
  /* GATT Task */
  GATT_Init( taskID++ );

  /* Profiles */
  GAPRole_Init( taskID++ );
  GAPBondMgr_Init( taskID++ );

  GATTServApp_Init( taskID++ );

  /* Application */
  SimpleBLEPeripheral_Init( taskID );
}

简单的来说,就是协议栈编译运行后,初始化OSAL,在协议栈中是采用任务调度的方式来运行的,官方的协议栈其实在编译运行后就会启动我们的广播,然后我们的其他设备就可以找到CC2540发出的广播,然后我们就可以连接到CC2540

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值