目前手里面有几个项目用的是nrf51822这款蓝牙芯片。由于我从未接触过蓝牙协议,所以在很多地方磕磕绊绊的,所以最近准备系统学习一下该芯片。并做一下笔记放在我的博客里面。系统学习资料来源于B站青峰电子。视频名称为 蓝牙nrf51822视频教程资料 编程开发 协议栈开发 青峰电子例程。
协议栈初始化
ble_stack_init
static void ble_stack_init(void)
{
uint32_t err_code;
//时钟初始化宏
// Initialize the SoftDevice handler module. PPM(百万分之一)
SOFTDEVICE_HANDLER_INIT(NRF_CLOCK_LFCLKSRC_XTAL_20_PPM, NULL);
//协议栈
#if defined(S110) || defined(S130) || defined(S132)
// Enable BLE stack.
ble_enable_params_t ble_enable_params;
memset(&ble_enable_params, 0, sizeof(ble_enable_params));
#if (defined(S130) || defined(S132))
ble_enable_params.gatts_enable_params.attr_tab_size = BLE_GATTS_ATTR_TAB_SIZE_DEFAULT;
#endif
ble_enable_params.gatts_enable_params.service_changed = IS_SRVC_CHANGED_CHARACT_PRESENT;
err_code = sd_ble_enable(&ble_enable_params);
APP_ERROR_CHECK(err_code);
#endif
//调度机制的核心
// Register with the SoftDevice handler module for BLE events.
err_code = softdevice_ble_evt_handler_set(ble_evt_dispatch);//蓝牙事件
APP_ERROR_CHECK(err_code);
// Register with the SoftDevice handler module for BLE events.
err_code = softdevice_sys_evt_handler_set(sys_evt_dispatch);//系统事件
APP_ERROR_CHECK(err_code);
}
回调派发函数
回调派发函数,分两个部分,一个是蓝牙事件派发,一个是系统事件派发。不同于CC240等蓝牙芯片带操作系统,nrf系列蓝牙处理器采用派发方式。当蓝牙协议栈有事件需要处理的时候,就会用到蓝牙事件派发。当系统有事件处理的时候就用到系统事件派发。
蓝牙事件派发
static void ble_evt_dispatch(ble_evt_t * p_ble_evt)
{
dm_ble_evt_handler(p_ble_evt);//设备管理事件处理函数
ble_conn_params_on_ble_evt(p_ble_evt);//连接参数管理处理函数,必要
bsp_btn_ble_on_ble_evt(p_ble_evt);//板级蓝牙事件处理函数
on_ble_evt(p_ble_evt);//通用的事件处理函数,必要
ble_advertising_on_ble_evt(p_ble_evt);//广播蓝牙事件处理函数,必要
/*YOUR_JOB add calls to _on_ble_evt functions from each service your application is using
ble_xxs_on_ble_evt(&m_xxs, p_ble_evt);//添加自己的服务处理函数
ble_yys_on_ble_evt(&m_yys, p_ble_evt);
*/
}
evt_id传递事件。
在ble_ranges.h定义了一组事件ID。事件字节区间不定,有1个字节,2个字节,4个字节等。
协议栈抛出事件ID进来时,例如是BLE_GAP_EVT_CONNECTED。在派发函数采用轮询的方式,看各个事件处理函数是否关注这个事件ID,如果关注的花,也就是在程序总定义事件处理函数需要执行对应的操作。
系统事件派发
static void sys_evt_dispatch(uint32_t sys_evt)
{
pstorage_sys_event_handler(sys_evt);//内部存储器的应用
ble_advertising_on_sys_evt(sys_evt);//系统广播应用
}
pstorage_sys_event_handler将在之后章节详细说明。一样是根据ID来处理事件。通过sd_evt_get获取事件ID,然后由处理事件函数进行相关的处理。
协议栈GAP入门
通用访问配置文件(GAP),该profile保证不通过的Bluetooth产品可以互相发现对方并建立连接。
GAP属于主协议栈层。
GAP初始化
GAP介绍
GAP定义了蓝牙设备如何发现和建立于其他设备的安全(或者不安全)连接。它处理一些一般模式的业务(如询问、命名和搜索)和一些安全性问题(如担保),同时还处理一些有关连接的业务(如链路建立、信道和连接建立)。
GAP规定的是一些一般性的运行任务。因此,它具有强制性,并作为所有其他蓝牙设备应用规范的基础。
GAP是所有其他配置文件的基础,它定义了在蓝牙设备间建立基带链路的通用方法。除此之外,GAP还定义了下列内容:
- 必须在所有蓝牙设备中实施的功能
- 发现和链接设备的通用步骤
- 基本用户界面术语
GAP确保了应用程序和设备间的高度互操作性,还允许开发人员利用现有的定义更加容易的定义新的配置文件。GAP处理未连接的两个设备间的发现和建立连接过程
此配置文件定义了一些通用的操作,这些操作可供引用GAP的配置文件,以及实施多个配置文件的设备使用。GAP确保了两个蓝牙设备可通过蓝牙技术交换信息,以发现彼此支持的应用程序。不符合任何其他蓝牙配置文件的蓝牙设备必须与GAP符合以确保基本的互操作性和共存。
GAP软件设计分析
static void gap_params_init(void)
{
uint32_t err_code;
ble_gap_conn_params_t gap_conn_params;
ble_gap_conn_sec_mode_t sec_mode;
//设置连接的安全模式
BLE_GAP_CONN_SEC_MODE_SET_OPEN(&sec_mode);
err_code = sd_ble_gap_d

最低0.47元/天 解锁文章
2441





