首先打开 sdk 下的工程模板 在以下路径中
XXXX\Keil_v5\ARM\Pack\NordicSemiconductor\nRF_Examples\9.0.0\ble_peripheral\ble_app_template\pca10028\s110\arm5打开工程后,可以发现该模板的框架和一般工程例子基本是一样的。区别就是有一些函数内部并未实现,比如services_init() 。
Main 函数的整体初始化流程都是通用。

[cpp] view plain copy    
  1. int main(void)
  2. {
  3. uint32_t err_code;
  4. bool erase_bonds;
  5. // Initialize.
  6. timers_init();
  7. buttons_leds_init(&erase_bonds);
  8. ble_stack_init();
  9. device_manager_init(erase_bonds);
  10. gap_params_init();
  11. advertising_init();
  12. services_i nit();
  13. conn_params_init();
  14. // Start execution.
  15. application_timers_start();
  16. err_code = ble_advertising_start(BLE_ADV_MODE_FAST);
  17. APP_ERROR_CHECK(err_code);
  18. // Enter main loop.
  19. for (;;)
  20. {
  21. power_manage();
  22. }
  23. }

这一讲我们来在该模板上创建个使用最少资源的服务。
我们只是创建一个服务这个服务具有可写和通知的特性。从而实现手机发数 这个服务具有可写和通知的特性。从而实现手机发数 据给设备,然后对数做 加 1操作 后再返回给手机。所以我们没有使用:定时器、按键定时器、按键led、绑定功能、链接参数、更新操作、所以上面的main函数我们精简成如下:

[cpp] view plain copy    
  1. int main(void)
  2. {
  3. uint32_t err_code;
  4. bool erase_bonds;
  5. ble_stack_init();
  6. gap_params_ init();
  7. advertising_init();
  8. services_init();
  9. err_code = ble_advertising_start(BLE_ADV_MODE_FAST);
  10. APP_ERROR_CHECK(err_code);
  11. // Enter main loop.
  12. for (;;)
  13. {
  14. power_manage();
  15. }
  16. }

这个时候编译工程下载到板子后是可以搜索设备的。只是连接后并没有服务,下面我们来创建一个服务。 要实现的就是上面services_init() 函数。首先我们需要定义一个自己的服务结构体来记录这相关些信息。直接在 main.c 文件的上面定义如下结构体。

[cpp] view plain copy    
  1. typedef struct BlkMyServiceTag{
  2. uint16_t conn_handle;              // 连接后用 来记录下句柄,供续使连接后用
  3. uint16_t service_handle;           // 保存服务的句柄
  4. ble_gatts_char_handles_t handle;   // 保存特性句柄
  5. }BlkMyService;

然后定义一个全局变量
BlkMyService my_service; // 这个全局变量保存了我们的服务相关信息

然后实现 service_init() 函数。
这里不使用模板工程中 建议的初始化方法,为简单起见我 们就直接在该函数里面调用服务添加和特征值。

为方便也是直接就在 main.c 文件中实现如下函数

[cpp] view plain copy    
  1. void services_init(void){
  2. ble_uuid_t service_uuid;
  3. service_uuid.type = BLE_UUID_TYPE_BLE;
  4. service_uuid.uuid = MY_UUID;
  5. // 添加服务
  6. sd_ble_gatts_service_add(BLE_GATTS_SRVC_TYPE_PRIMARY,&service_uuid,&my_service.service_handle);
  7. ble_gatts_char_ md_t char_md;
  8. ble_gatts_attr_t attr_char_value;
  9. ble_gatts_attr_md_t cccd_md;
  10. ble_gatts_attr_md_t attr_md;
  11. BLE_GAP_CONN_SEC_MODE_SET_OPEN(&cccd_md.read_perm);
  12. BLE_GAP_CONN_SEC_MODE_SET_OPEN(&cccd_md.write_perm);
  13. cccd_md.vloc           = BLE_GATTS_VLOC_ STACK;
  14. char_md.p_cccd_md      = &cccd_md;
  15. char_md.props.notify   = 1;
  16. char_md.props.write    = 1;
  17. char_md.p_pf           = NULL;
  18. char_md.p_user_desc    = NULL;
  19. char_md.p_sccd_md      = NULL;
  20. char_md.p_user_desc_md = NULL;
  21. attr_md.rd_auth = 0;
  22. attr_md.wr_auth = 0;
  23. BLE_GAP_CONN_SEC_MODE_SET_OPEN(&attr_md.read_perm);
  24. BLE_GAP_CONN_SEC_MODE_SET_OPEN(&attr_md.write_perm);
  25. attr_md.vloc = BLE_GATTS_VLOC_STACK;
  26. attr_md.vlen = 1;
  27. ble_uuid_t val_uuid;
  28. val_uuid.type   = BLE_UUID_TYPE_BLE;
  29. val_uuid.uu id  = 0x5678;
  30. attr_char_value.p_uuid     = &val_uuid;
  31. attr_char_value.p_md       = &attr_md;
  32. attr_char_value.init_len   = sizeof(uint8_t);
  33. attr_char_value.init_offs  = 0;
  34. attr_char_value.max_len    = 20;
  35. // 添加特征值。
  36. sd_ble_gatts_characteristic_add(my_service.servi ce_handle, &char_md, attr_value,&my_service.handle);
  37. }

到这里服务以及其中的特征值都已经创建好了。编译工程下载后,手机连接设备可以看到服务列表中已经有了我们添加的服务uuid 为0x1234,点击服务也可以看到其中的特征值 uuid 为0x5678;服务创建完后就是与手机通信了。我们要实现的是手机发送一个数据,设备收到后对数据做加 1 操作后再发回给手机。

手机发给设备的数据最终会被打包成一个写事件结构然后交给 app 。
先实现对写事件的处理。就是将数据加一然后在发送回给手机。
当然发送数据给手机之前,我们要知道之前,我们要知道 conn_handle,这在手机连接的时候 app 会收到这个事件,记录下句柄就可以了。

我们针对写事件实 我们实现如下的数据操作和发送函(为方便都是直接在 main.c 文件中实现 )

[cpp] view plain copy    
  1. void service_write_handle(ble_evt_t *p_evt){
  2. uint16_t data_len;
  3. uint8_t data;
  4. data_len = sizeof(uint8_t);
  5. data = p_ble_evt ->evt.gatts_params.write.data[0];
  6. data++;
  7. ble_gatts_hvx_params_t params;
  8. hvx_params.handle   = my_service.char_handle.val ue_handle;
  9. hvx_params.offset   = 0;
  10. hvx_params.p_data   = &data;
  11. hvx_params.p_len    = &data_len;
  12. hvx_params.type     = BLE_GATT_HVX_NOTIFICATION;
  13. sd_ble_gatts_hvx(my_service.conn_handle,&hvx_params);
  14. }

然后实现的服务处理函数如下

[cpp] view plain copy    
  1. void my_server_handler(ble_evt_t *p_evt){
  2. switch (p_ble_evt ->header.evt_id)
  3. {
  4. case BLE_GAP_EVT_CONNECTED:
  5. my_service.conn_handl =p_ble_evt ->evt.gap_conn_handle;
  6. break;
  7. case BLE_GATTS_EVT_WRITE:
  8. service_write_handle(p_ble_evt);
  9. break ;
  10. default:
  11. // No implementation needed.
  12. break;
  13. }
  14. }

最后我们将这个 服务事件处理函数 添加到事件派发函数中

[cpp] view plain copy    
  1. static void ble_evt_dispatch(t * p_evt)
  2. {
  3. dm_ble_evt_handler(p_evt);
  4. ble_conn_params_on_evt(p_evt);
  5. bsp_btn_ble_on_b le_evt(p_ble_evt);
  6. on_ble_evt(p_evt);
  7. ble_advertising_on_evt(p_evt);
  8. // 添加到这里
  9. my_server_handler(p_ble_evt);
  10. }

编译工程下载后 ,手机连接上进入服务的特征值勾选使能 notify 功能, 然后发送数据就可以看到收加 1 的数据了

BLE-NRF51822教程6-创建一个自己的服务相关推荐

  1. Scott Mitchell 的ASP.NET 2.0数据教程之一: 创建一个数据访问层

    原文 | 下载本教程中的编码例子 | 下载本教程的英文PDF版 导言 作为web开发人员,我们的生活围绕着数据操作.我们建立数据库来存储数据,写编码来访问和修改数据,设计网页来采集和汇总数据.本文是研 ...

  2. java写七彩文字_【PS精选案例教程】创建一个漂亮的七彩文字

    原标题:[PS精选案例教程]创建一个漂亮的七彩文字 效果图: 步骤1. 新建一个文档(大小随意) 步骤2. 滤镜→渲染→云彩 步骤3. 可以按Ctrl+Alt+F增加效果 步骤4. Ctrl+J复制一 ...

  3. [转]VS2010 教程:创建一个 WPF 应用程序 (第一节)

    [转]VS2010 教程:创建一个 WPF 应用程序 (第一节) http://msdn.microsoft.com/zh-cn/ff629048(zh-cn) Extended WPF Toolki ...

  4. php生成占位图,Laravel4创建一个占位图片服务例子

    下面我来给大家转一个关于Laravel4创建一个占位图片服务例子,使用Composer安装intervention/image库,代码如下: composer require intervention ...

  5. 「六」创建一个带 weblogic 服务的基础镜像

    Weblogic Weblogic 简单介绍以及其在 Docker 环境下的特殊应用 WebLogic是美国Oracle公司出品的一个application server确切的说是一个基于JAVAEE ...

  6. Kile5安装教程和创建一个工程举例【图文STM32F407ZE芯片为例】

    文章目录 [一]开始安装 keil5 STM32F407ZE为例 [二]STM32工程创建步骤 [三]安装J-Link驱动+ST-LINK驱动及教程 [四]STM32的命名规则举例 --->面试 ...

  7. PS网页设计教程XXIII——创建一个售卖iPhone 5应用程序的网站

    作为编码者,美工基础是偏弱的.我们可以参考一些成熟的网页PS教程,提高自身的设计能力.套用一句话,"熟读唐诗三百首,不会作诗也会吟". 本系列的教程来源于网上的PS教程,都是国外的 ...

  8. 【Unity教程】创建一个完整的驾驶游戏

    专业游戏设计 你会学到什么 在unity HDRP创建一个完整的驾驶游戏 定制不同类型的汽车 将人工智能汽车和人工智能航路点系统添加到你的赛道上 添加汽车展厅菜单以解锁和购买新车 在Blender中设 ...

  9. VS2010 教程:创建一个 WPF 应用程序 (第一节)

    来自:https://msdn.microsoft.com/zh-cn/library/ff629048.aspx [原文发表地址] VS2010 Tutorial: Build a WPF App ...

  10. ROM制作教程 如何创建一个刷机包

    目前有好几种方法来安装软件或是库文件到你的Android手机上.你可以使用市场程序来查找并安装软件,也可以使用adb命令行工具来安装或是发送文件到你的Android文件系统中.这些方法对于操作单个文件 ...

最新文章

  1. d3.js 旋转图形_【IOS游戏推荐】百万畅销游戏刚从STEAM移植至IOS平台,在极端地形中冒险前进!——旋转轮胎:泥泞奔驰...
  2. Linux原始套接字实现分析---转
  3. java 获取网络带宽_Java开发网 - 一个测网络延迟和带宽的程序,发10M的数据有问题...
  4. JAVA常用设计模式(一、单例模式、工厂模式)
  5. 3650m5服务器内存选择 ibm_各大品牌服务器租用价格表明细(附详细表单)
  6. PHP Smarty template for website
  7. 计算机硬件知识教学的信息化手段,《计算机硬件组成》教学设计
  8. 提效80%|一次【Jmeter】实践的接口自动化
  9. idea 新增html页面或者是修改html文件后,target不会同步更新
  10. Android 再爆新漏洞,9.0 以下所有手机全部中招!
  11. 建立数据通道,解决IMX6边编码边解码的问题
  12. gsp计算机管理制度,GSP飞检项目——质量体系文件
  13. c语言实现AD采样后FFT算法,实践“玩转FFT算法...任你移植”,正确AD采样及生成函数表...
  14. Python 离线安装 Extension Packages
  15. 推荐一个不错的在线制图网站---ProcessOn
  16. 迅视财经 五条特色大街上线
  17. [深度学习]动手学深度学习笔记-12
  18. Visual Stdio 中的error C2001: 常量中有换行符
  19. Unity3D 无限滚动列表
  20. 2.7、信息系统项目典型生命周期模型

热门文章

  1. JDK8新特性之接口默认方法与静态方法
  2. 多线程:什么是ThreadLocal?应用场景?
  3. String : string的长度?string的子串?
  4. 【Scratch】青少年蓝桥杯_每日一题_4.13_猫捉老鼠
  5. GoEasy导入依赖的时候报错,包用不了,maven导包
  6. rocm平台_痛击NV CUDA!AMD ROCm开放计算平台瓜熟蒂落
  7. oracle 日结 数据量大,如何对一个oracle11gsql语
  8. 模块化数据机房具备的五大优势
  9. 乱乱乱!那些惨不忍睹的机房布线
  10. Python之pandas:pandas.set_option函数的参数详细解释