BLE-NRF51822教程6-创建一个自己的服务
2016-02-01 11:50
816 查看
首先打开 sdk 下的工程模板 在以下路径中
XXXX\Keil_v5\ARM\Pack\NordicSemiconductor\nRF_Examples\9.0.0\ble_peripheral\ble_app_template\pca10028\s110\arm5打开工程后,可以发现该模板的框架和一般工程例子基本是一样的。区别就是有一些函数内部并未实现,比如services_init() 。
Main 函数的整体初始化流程都是通用。
这一讲我们来在该模板上创建个使用最少资源的服务。
我们只是创建一个服务这个服务具有可写和通知的特性。从而实现手机发数 这个服务具有可写和通知的特性。从而实现手机发数 据给设备,然后对数做 加 1操作 后再返回给手机。所以我们没有使用:定时器、按键定时器、按键led、绑定功能、链接参数、更新操作、所以上面的main函数我们精简成如下:
这个时候编译工程下载到板子后是可以搜索设备的。只是连接后并没有服务,下面我们来创建一个服务。 要实现的就是上面services_init() 函数。首先我们需要定义一个自己的服务结构体来记录这相关些信息。直接在 main.c 文件的上面定义如下结构体。
然后定义一个全局变量
BlkMyService my_service; // 这个全局变量保存了我们的服务相关信息
然后实现 service_init() 函数。
这里不使用模板工程中 建议的初始化方法,为简单起见我 们就直接在该函数里面调用服务添加和特征值。
为方便也是直接就在 main.c 文件中实现如下函数
到这里服务以及其中的特征值都已经创建好了。编译工程下载后,手机连接设备可以看到服务列表中已经有了我们添加的服务uuid 为0x1234,点击服务也可以看到其中的特征值 uuid 为0x5678;服务创建完后就是与手机通信了。我们要实现的是手机发送一个数据,设备收到后对数据做加 1 操作后再发回给手机。
手机发给设备的数据最终会被打包成一个写事件结构然后交给 app 。
先实现对写事件的处理。就是将数据加一然后在发送回给手机。
当然发送数据给手机之前,我们要知道之前,我们要知道 conn_handle,这在手机连接的时候 app 会收到这个事件,记录下句柄就可以了。
我们针对写事件实 我们实现如下的数据操作和发送函(为方便都是直接在 main.c 文件中实现 )
然后实现的服务处理函数如下
XXXX\Keil_v5\ARM\Pack\NordicSemiconductor\nRF_Examples\9.0.0\ble_peripheral\ble_app_template\pca10028\s110\arm5打开工程后,可以发现该模板的框架和一般工程例子基本是一样的。区别就是有一些函数内部并未实现,比如services_init() 。
Main 函数的整体初始化流程都是通用。
int main(void) { uint32_t err_code; bool erase_bonds; // Initialize. timers_init(); buttons_leds_init(&erase_bonds); ble_stack_init(); device_manager_init(erase_bonds); gap_params_init(); advertising_init(); services_i nit(); conn_params_init(); // Start execution. application_timers_start(); err_code = ble_advertising_start(BLE_ADV_MODE_FAST); APP_ERROR_CHECK(err_code); // Enter main loop. for (;;) { power_manage(); } }
这一讲我们来在该模板上创建个使用最少资源的服务。
我们只是创建一个服务这个服务具有可写和通知的特性。从而实现手机发数 这个服务具有可写和通知的特性。从而实现手机发数 据给设备,然后对数做 加 1操作 后再返回给手机。所以我们没有使用:定时器、按键定时器、按键led、绑定功能、链接参数、更新操作、所以上面的main函数我们精简成如下:
int main(void) { uint32_t err_code; bool erase_bonds; ble_stack_init(); gap_params_ init(); advertising_init(); services_init(); err_code = ble_advertising_start(BLE_ADV_MODE_FAST); APP_ERROR_CHECK(err_code); // Enter main loop. for (;;) { power_manage(); } }
这个时候编译工程下载到板子后是可以搜索设备的。只是连接后并没有服务,下面我们来创建一个服务。 要实现的就是上面services_init() 函数。首先我们需要定义一个自己的服务结构体来记录这相关些信息。直接在 main.c 文件的上面定义如下结构体。
typedef struct BlkMyServiceTag{ uint16_t conn_handle; // 连接后用 来记录下句柄,供续使连接后用 uint16_t service_handle; // 保存服务的句柄 ble_gatts_char_handles_t handle; // 保存特性句柄 }BlkMyService;
然后定义一个全局变量
BlkMyService my_service; // 这个全局变量保存了我们的服务相关信息
然后实现 service_init() 函数。
这里不使用模板工程中 建议的初始化方法,为简单起见我 们就直接在该函数里面调用服务添加和特征值。
为方便也是直接就在 main.c 文件中实现如下函数
void services_init(void){ ble_uuid_t service_uuid; service_uuid.type = BLE_UUID_TYPE_BLE; service_uuid.uuid = MY_UUID; // 添加服务 sd_ble_gatts_service_add(BLE_GATTS_SRVC_TYPE_PRIMARY,&service_uuid,&my_service.service_handle); ble_gatts_char_ md_t char_md; ble_gatts_attr_t attr_char_value; ble_gatts_attr_md_t cccd_md; ble_gatts_attr_md_t attr_md; BLE_GAP_CONN_SEC_MODE_SET_OPEN(&cccd_md.read_perm); BLE_GAP_CONN_SEC_MODE_SET_OPEN(&cccd_md.write_perm); cccd_md.vloc = BLE_GATTS_VLOC_ STACK; char_md.p_cccd_md = &cccd_md; char_md.props.notify = 1; char_md.props.write = 1; char_md.p_pf = NULL; char_md.p_user_desc = NULL; char_md.p_sccd_md = NULL; char_md.p_user_desc_md = NULL; attr_md.rd_auth = 0; attr_md.wr_auth = 0; BLE_GAP_CONN_SEC_MODE_SET_OPEN(&attr_md.read_perm); BLE_GAP_CONN_SEC_MODE_SET_OPEN(&attr_md.write_perm); attr_md.vloc = BLE_GATTS_VLOC_STACK; attr_md.vlen = 1; ble_uuid_t val_uuid; val_uuid.type = BLE_UUID_TYPE_BLE; val_uuid.uu id = 0x5678; attr_char_value.p_uuid = &val_uuid; attr_char_value.p_md = &attr_md; attr_char_value.init_len = sizeof(uint8_t); attr_char_value.init_offs = 0; attr_char_value.max_len = 20; // 添加特征值。 sd_ble_gatts_characteristic_add(my_service.servi ce_handle, &char_md, attr_value,&my_service.handle); }
到这里服务以及其中的特征值都已经创建好了。编译工程下载后,手机连接设备可以看到服务列表中已经有了我们添加的服务uuid 为0x1234,点击服务也可以看到其中的特征值 uuid 为0x5678;服务创建完后就是与手机通信了。我们要实现的是手机发送一个数据,设备收到后对数据做加 1 操作后再发回给手机。
手机发给设备的数据最终会被打包成一个写事件结构然后交给 app 。
先实现对写事件的处理。就是将数据加一然后在发送回给手机。
当然发送数据给手机之前,我们要知道之前,我们要知道 conn_handle,这在手机连接的时候 app 会收到这个事件,记录下句柄就可以了。
我们针对写事件实 我们实现如下的数据操作和发送函(为方便都是直接在 main.c 文件中实现 )
void service_write_handle(ble_evt_t *p_evt){ uint16_t data_len; uint8_t data; data_len = sizeof(uint8_t); data = p_ble_evt ->evt.gatts_params.write.data[0]; data++; ble_gatts_hvx_params_t params; hvx_params.handle = my_service.char_handle.val ue_handle; hvx_params.offset = 0; hvx_params.p_data = &data; hvx_params.p_len = &data_len; hvx_params.type = BLE_GATT_HVX_NOTIFICATION; sd_ble_gatts_hvx(my_service.conn_handle,&hvx_params); }
然后实现的服务处理函数如下
void my_server_handler(ble_evt_t *p_evt){ switch (p_ble_evt ->header.evt_id) { case BLE_GAP_EVT_CONNECTED: my_service.conn_handl =p_ble_evt ->evt.gap_conn_handle; break; case BLE_GATTS_EVT_WRITE: service_write_handle(p_ble_evt); break ; default: // No implementation needed. break; } }最后我们将这个 服务事件处理函数 添加到事件派发函数中
static void ble_evt_dispatch(t * p_evt) { dm_ble_evt_handler(p_evt); ble_conn_params_on_evt(p_evt); bsp_btn_ble_on_b le_evt(p_ble_evt); on_ble_evt(p_evt); ble_advertising_on_evt(p_evt); // 添加到这里 my_server_handler(p_ble_evt); }编译工程下载后 ,手机连接上进入服务的特征值勾选使能 notify 功能, 然后发送数据就可以看到收加 1 的数据了
相关文章推荐
- 内存溢出和内存泄露
- NSURLSession简介
- iOSCoreAnimation CAKeyFrameAnimation 详解
- Git入门手册
- 电商网站架构案例
- Spring webapp Junit测试
- IOS CALayer 详解
- 流苏岛之混沌境
- unity3d中脚本生命周期(MonoBehaviour lifecycle)
- XML文件转换成 HTML
- README: 算法竞赛入门
- 解决winform中的panel重绘闪烁问题
- leetcode第一刷_Set Matrix Zeroes
- iOSCoreAnimation CABasicAnimation 详解
- Unity3d中BlinnPhong光照模型注解
- BLE-NRF51822教程5-静态密码设置
- C++开发ActiveX控件相关
- 数据保护API
- 高逼格UI-ASD(Android Support Design)
- JSP与Servlet的介绍说明