jj1989 发表于 2018-12-8 16:51

【nRF52840 DK测评】自定义BLE服务

<div class='showpostmsg'> 本帖最后由 jj1989 于 2018-12-8 17:08 编辑

## 前言
上一篇文章介绍了上手nRF52840需要的一些准备工作,通过对官方SDK例程的学习,我想你对BLE的应用应该有了初步了解。那如何在现有代码的基础上添加自己的BLE服务呢?接下来我将以官方例程模版,带你一步步添加自己的BLE服务。

---
## 准备工作
首先按照以下顺序操作,完成相关固件的烧录。
1. demo:SDK15.0.2中examples/ble_peripheral/ble_app_template
2. 这里使用gcc-arm-none-eabi进行编译,所以需要先安装好交叉编译工具链,并在sdk中的Makefile.posix文件中,配置其所在路径。
3. 终端中执行*make*命令,等待程序编译完成,如下图所示。
4. 然后执行*make flash_softdevice*命令,烧录蓝牙协议栈到开发版。5. 最后执行*make flash*命令,烧录应用程序到开发版。烧录完成后,芯片将自动复位重启,此时可以看到LED1开始闪烁,表明程序已经跑起来了。
6. 手机打开*light blue*软件,连接名为*Nordic_Template*的设备,如下图。

可以看到除了显示广播数据外,无其它服务。接下来我们将添加一个自定义的服务。

## 添加服务
首先来看services_init函数,
```c
/**@brief Function for initializing services that will be used by the application.
*/
static void services_init(void)
{
    ret_code_t         err_code;
    nrf_ble_qwr_init_t qwr_init = {0};

    // Initialize Queued Write Module.
    qwr_init.error_handler = nrf_qwr_error_handler;

    err_code = nrf_ble_qwr_init(&m_qwr, &qwr_init);
    APP_ERROR_CHECK(err_code);

    /* YOUR_JOB: Add code to initialize the services used by the application.
       ble_xxs_init_t                     xxs_init;
       ble_yys_init_t                     yys_init;

       // Initialize XXX Service.
       memset(&xxs_init, 0, sizeof(xxs_init));

       xxs_init.evt_handler                = NULL;
       xxs_init.is_xxx_notify_supported    = true;
       xxs_init.ble_xx_initial_value.level = 100;

       err_code = ble_bas_init(&m_xxs, &xxs_init);
       APP_ERROR_CHECK(err_code);

       // Initialize YYY Service.
       memset(&yys_init, 0, sizeof(yys_init));
       yys_init.evt_handler                  = on_yys_evt;
       yys_init.ble_yy_initial_value.counter = 0;

       err_code = ble_yy_service_init(&yys_init, &yy_init);
       APP_ERROR_CHECK(err_code);
   */
}
```
这里注释已经写得较清楚,在这里添加相应的代码即可添加蓝牙服务。这里我们添加一个128位UUID的服务,服务包含一个characteristic,其属性为notify。将实现的功能为当开发板的key1按键状态发生变化时,通知APP。代码如下:
```c
static void services_init(void)
{
    ret_code_t         err_code;
    nrf_ble_qwr_init_t qwr_init = {0};

    // Initialize Queued Write Module.
    qwr_init.error_handler = nrf_qwr_error_handler;

    err_code = nrf_ble_qwr_init(&m_qwr, &qwr_init);
    APP_ERROR_CHECK(err_code);
   
    //key state service
    ble_key_state_init_t    key_state_init;
    memset(&key_state_init,0,sizeof(key_state_init));
    key_state_init.data_handler = NULL;
    err_code = ble_key_state_init(&m_key_state,&key_state_init);
    APP_ERROR_CHECK(err_code);
}
```
具体代码的实现,可以参考SDK中的examples/ble_peripheral/ble_app_uart这个例程。

## 调试
接下来编译、烧录并运行,打开JLinkRTTClient,查看输出日志,出现Fatal error。如下图:

表示程序运行出错,但日志不够详细,没给出出错的原因。此时可开启DEBUG宏,然后重新编译、烧录运行,现在日志很详细了,指出了出错的原因,如下图:

提示main.c 的296行报错,错误类型为 NRF_ERROR_NO_MEM。这里添加了服务,需要设置UUID的数量,我们添加了一个服务,所以需要宏NUS_BASE_UUID设置为1。
再次编译、烧录运行,提示RAM的起始地址需要修改。如下图:

由于我们添加的服务,会单独使用一部分内存,使得留给应用程序的内存空间将减少。根据日志提示,在链接文件中修改好RAM起始地址和大小,然后再次编译并运行。此时开发版LED1开始闪烁,程序终于跑起来了,输出日志如下图:

蓝牙正在进行快速广播。
此时通过手机链接到开发版,可以看到我们刚刚添加的服务。如下图:


----
## 总结
本文简单讲解了如何添加自定义的BLE服务,具体的操作可以参考ble_app_uart例程。下一篇将介绍如何将按键状态发送给手机。
此内容由EEWORLD论坛网友jj1989原创,如需转载或用于商业用途需征得作者同意并注明出处



</div><script>                                        var loginstr = '<div class="locked">查看本帖全部内容,请<a href="javascript:;"   style="color:#e60000" class="loginf">登录</a>或者<a href="https://bbs.eeworld.com.cn/member.php?mod=register_eeworld.php&action=wechat" style="color:#e60000" target="_blank">注册</a></div>';
                                       
                                        if(parseInt(discuz_uid)==0){
                                                                                                (function($){
                                                        var postHeight = getTextHeight(400);
                                                        $(".showpostmsg").html($(".showpostmsg").html());
                                                        $(".showpostmsg").after(loginstr);
                                                        $(".showpostmsg").css({height:postHeight,overflow:"hidden"});
                                                })(jQuery);
                                        }                </script><script type="text/javascript">(function(d,c){var a=d.createElement("script"),m=d.getElementsByTagName("script"),eewurl="//counter.eeworld.com.cn/pv/count/";a.src=eewurl+c;m.parentNode.insertBefore(a,m)})(document,523)</script>

jj1989 发表于 2018-12-8 17:12

对于论坛的markdown模式已无力吐槽,各种格式混乱。同样的内容,两次发出来的格式不一样。
比如上面的序号。

btty038 发表于 2018-12-8 21:26

表示看不懂    先给楼主顶一哈   &#128077;

chenhuman 发表于 2018-12-8 21:44

写的很详细,楼主辛苦了

jj1989 发表于 2018-12-8 22:11

btty038 发表于 2018-12-8 21:26
表示看不懂    先给楼主顶一哈   &#128077;

感谢帮顶。

jj1989 发表于 2018-12-8 22:12

chenhuman 发表于 2018-12-8 21:44
写的很详细,楼主辛苦了

:handshake

okhxyyo 发表于 2018-12-8 22:59

感谢分享{:1_102:}写的很清楚明了。很抱歉论坛编辑器给你造成的不便。我们正在进行论坛改版中,新版预期采用新的编辑器,会对旧编辑器的问题进行调整。

jj1989 发表于 2018-12-8 23:31

okhxyyo 发表于 2018-12-8 22:59
感谢分享写的很清楚明了。很抱歉论坛编辑器给你造成的不便。我们正在进行论坛改版中,新版预期采 ...

期待,每次最痛苦的不是写文章,而是发帖的时候。每次都要编辑好几次,才能基本满足要求。

star_66666 发表于 2018-12-8 23:50

不错,空闲了,找时间仔细看看你的帖子,我也有个,还没时间研究呢,先支持一下了,,,,加油,,

jj1989 发表于 2018-12-9 16:14

star_66666 发表于 2018-12-8 23:50
不错,空闲了,找时间仔细看看你的帖子,我也有个,还没时间研究呢,先支持一下了,,,,加油,,

嗯,一起研究。

懒猫爱飞 发表于 2018-12-9 21:00

持续关注,有空俺也学下52840{:1_103:}

jj1989 发表于 2018-12-10 09:52

懒猫爱飞 发表于 2018-12-9 21:00
持续关注,有空俺也学下52840

做好弃用dialog的准备。:pleased:

懒猫爱飞 发表于 2018-12-10 16:44

jj1989 发表于 2018-12-10 09:52
做好弃用dialog的准备。

各家都在用^_^

star_66666 发表于 2018-12-10 23:07

有空一起来

不可一世ywd 发表于 2019-11-13 14:35

<p>有帮助,定一个</p>

领越电子 发表于 2020-5-8 17:07

sxc127 发表于 2020-11-5 10:05

<p>您好,请问在哪里可以下载到蓝牙协议栈的源码?</p>

alan000345 发表于 2020-11-9 21:07

<p>谢谢分享</p>
页: [1]
查看完整版本: 【nRF52840 DK测评】自定义BLE服务