本文将基于Nordic nRF5 SDK开发我们的第一个BLE应用程序——Blinky(类似跑马灯小程序),哪怕你之前没有任何BLE开发经验,也不用担心,只要跟着文中所述步骤,你就可以一步步搭建自己的第一个BLE应用程序。通过这个Blinky程序的搭建,你将体会到BLE的一些基本概念,对BLE将会有一个非常直观的认识,为后续自己的BLE应用程序开发打下一个坚实的基础。

如果你已经有一些BLE应用开发经验,只是对Nordic产品开发不熟,那么建议你可以直接去阅读下一篇文章:手把手教你开发BLE数据透传应用程序

下文所述的代码工程我已经将其上传到百度云盘中,有需要的同学可以到如下链接下载:

  • 链接: https://pan.baidu.com/s/1FKTfY3Q_zBVvviO7KC7Gyg#list/path=%2Fblog   密码: y8fb

1. 开发准备

1)      nRF52或者nRF51开发板1块。请参考“Nordic nRF51/nRF52开发流程说明”,购买相应开发板(DK)。

2)      开发环境搭建。简述如下(详细说明请参考“Nordic nRF51/nRF52开发环境搭建”):

  1. 安装Keil5 MDK
  2. 安装SDK。SDK下载链接:https://www.nordicsemi.com/Software-and-Tools/Software/nRF5-SDK/Download#infotabs。如果你开发的是nRF52系列,请选择最新版SDK(当前是SDK15.3.0);如果你开发的是nRF51系列,请下载nRF5 SDK12.3.0(nRF51最高SDK版本只能到12.3.0,后续SDK就不再支持nRF51
  3. 安装ARM CMSIS4.5.0,下载链接:https://github.com/ARM-software/CMSIS/releases/download/v4.5.0/ARM.CMSIS.4.5.0.pack。
  4. 安装Keil5 Device Family Pack,下载链接:https://www.nordicsemi.com/Software-and-Tools/Development-Tools/nRF-MDK/Download#infotabs,请选择“Pack,3-clause BSD license”
  5. 安装nRF5 Command Line Tools,下载链接(Windows版):https://www.nordicsemi.com/Software-and-Tools/Development-Tools/nRF5-Command-Line-Tools/Download#infotabs。
  6. 安装安卓版或者iOS版nRF connect。iOS版nRF connect请到苹果app store下载,搜索“nRF”即可以找到。安卓版nRF connect可以到Nordic Github官网上下载,下载链接为:https://github.com/NordicSemiconductor/Android-nRF-Connect/releases
  7. 安装PC版nRF connect或者nRFgo studio。PC版nRF connect下载链接(Windows版):https://www.nordicsemi.com/Software-and-Tools/Development-Tools/nRF-Connect-for-desktop/Download#infotabs。

注:如果你使用的是Linux系统/Mac系统,或者你使用的不是Keil5-MDK,请参考“Nordic nRF51/nRF52开发环境搭建”来搭建你的开发环境。

2. 运行Blinky程序

请按照如下步骤运行SDK自带的Blinky程序

1)      确认自己的芯片型号或者开发板。如果采用Nordic官方开发板的话,芯片型号和开发板编号对应关系如下:

  • nRF52832和nRF52810对应开发板编号为PCA10040。虽然52832和52810共用同一块开发板,但是他们在SDK中的项目编号是不一样的,52832对应PCA10040目录,52810对应PCA10040e目录,由于52810和52832 PIN to PIN兼容,软件也是完全兼容的,因此SDK很多项目只有PCA10040的目录,而没有PCA10040e目录,此时需要你自己来建立PCA10040e对应的目录和工程,具体说明可参考:https://infocenter.nordicsemi.com/index.jsp?topic=%2Fcom.nordic.infocenter.sdk5.v15.3.0%2Fnrf52810_user_guide.html。
  • nRF52840和nRF52811对应开发板编号为PCA10056。虽然52840和52811共用同一块开发板,但是他们在SDK中的项目编号是不一样的,52840对应PCA10056目录,52811对应PCA10056e目录,由于52811和52840 PIN to PIN兼容,软件也是完全兼容的,因此SDK很多项目只有PCA10056的目录,而没有PCA10056e目录,此时需要你自己来建立PCA10056e对应的目录和工程,具体说明可参考:https://infocenter.nordicsemi.com/index.jsp?topic=%2Fcom.nordic.infocenter.sdk5.v15.3.0%2Fnrf52811_user_guide.html&cp=5_1_5_1。
  • nRF52840 dongle编号为PCA10059
  • nRF51系列对应开发板编号为PCA10028

这里我会以nRF52832开发板PCA10040为例阐述整个开发过程,其他开发板与之类似,大家自己可以举一反三来开始自己的开发之旅。

2)      将开发板与PC机通过USB线相连,同时打开开发板电源(将左下角的拨位开关打到“ON”位置),打开桌面版nRF Connect,选择启动“Programmer”应用,由于驱动之前已经安装好了,设备可以立即识别成功。执行“Erase all”操作,以擦除芯片原始内容。

3)      打开SDK中的Blinky程序。对于blinky程序,如果是52832开发板,请打开:nRF5_SDK_15.3.0_59ac345\examples\ble_peripheral\ble_app_blinky\pca10040\s132\arm5_no_packs;如果是51822开发板,请打开:nRF5_SDK_12.3.0_d7731ad\examples\ble_peripheral\experimental_ble_app_blinky\pca10028\s130\arm5_no_packs

后续将以52832开发板为例来阐述,51822与之类似就不再阐述了

注:Nordic SDK例程目录结构为:SDK版本/ examples /协议角色/例子名称/开发板型号/协议栈型号/工具链类型/具体工程,比如下面例子:

Nordic每一个例子都支持5种工具链:Keil5/Keil4/IAR/GCC/SES,如下所示:

4)      编译上面的blinky程序。如果你已经按照之前的说明配置好了开发环境,那么这里编译是不会报任何错的。(如果你遇到了编译错误,请重新按照前面说明去搭建你的开发环境,不要怀疑SDK例子代码有问题哦)

5)      程序下载。程序下载包括2步:先下载softdevice,再下载应用。Softdevice是Nordic蓝牙协议栈的名称,整个开发过程中只需下载一次。应用就是我们这里的blinky程序。

  • 蓝牙协议栈下载(整个开发周期只下载一次)。在Keil ‘select target’下拉列表中,默认选择的是Keil工程对应的Target,即‘nrf52832_xxaa’。但我们还可以选择另一个target ‘flash_s132_nrf52_6.1.1_softdevice’,即softdevice对应的target,然后点击“下载download”(不需要编译哦!),此时会把softdevice下载到开发板中。

  • 应用下载。重新选择Target:‘nrf52832_xxaa’,点击“下载Download”,此时会把Blinky程序下载到开发板中。此时开发板的LED1常亮,表示程序运行正常。

6)      打开手机蓝牙和手机版nRF connect。在nRF connect中,你将看到一个广播设备:Nordic_Blinky,这个就是我们的开发板。

7)      连接设备。点击“CONNECT”,手机将与设备建立连接,并开始服务发现过程,连接成功后,LED1熄灭,LED2点亮,最后将得到如下界面。

由上图可见,Blinky程序包含三个service:Generic Access(GAP),Generic Attribute(GATT),以及Nordic LED Button Service,GAP和GATT都是标准的蓝牙service,Nordic LED Button Service是Blinky程序自定义的service,它又具体包括两个characteristic:Button和LED。

8)      测试Blinky程序。点击右上角的“Enable CCCDs”以使能notification,如下:

按下开发板上的Button1按键,你会发现nRF connect中的Button characteristic Value会实时显示按键状态:pressed或者released。

点击nRF connect中的LED characteristic右边的向上箭头,选择“ON”并“SEND”,你会发现开发板的LED3将点亮;选择“OFF”并“SEND”,LED3又将熄灭。

3. 修改Blinky程序

3.1 修改广播名称

如前所述,Blinky程序默认的广播名字是:Nordic_Blinky,我们现在将其修改为“My_Blinky”,怎么做呢?我们在Keil中全文搜索“Nordic_Blinky”,发现有如下宏定义:

#define DEVICE_NAME                     "Nordic_Blinky"

我们只需将这里的Nordic_Blinky换成My_Blinky,即

#define DEVICE_NAME                     "My_Blinky"

就可以实现我们的目标了。重新编译下载blinky程序,在nRF connect中,你将看到:

你再全文搜索一下“DEVICE_NAME”,你会发现广播名字其实是通过如下API来完成修改的:

    err_code = sd_ble_gap_device_name_set(&sec_mode,(const uint8_t *)DEVICE_NAME,strlen(DEVICE_NAME));

注:Keil的搜索功能非常好用,很多问题都可以通过它来解决

3.2 修改广播间隔

如nRF connect界面所示,blinky程序的广播间隔大概为40ms左右,现在为了节省功耗,我们将其改为200ms,通过搜索,我们可以看到如下宏定义:

#define APP_ADV_INTERVAL                64                                      /**< The advertising interval (in units of 0.625 ms; this value corresponds to 40 ms). */

因此为了将广播间隔改为200ms,只需将APP_ADV_INTERVAL改成200/0.625 = 320,即

#define APP_ADV_INTERVAL                320

重新编译下载blinky程序,在nRF connect中,你将发现广播间隔已改为200ms了:

3.3 修改Button characteristic行为 (设备发数据给手机)

现在的Blinky程序,只有按下开发板的Button1时,nRF connect的Button characteristic 值才会更新。我们现在新增一个功能:当按下开发板的Button 2时,让Button characteristic value更新为5(注: nRF connect把1当成按键按下,把0当成按键释放,为了更直观,我们没有选择0或者1,而是随便选择一个值:5)。我们先找到Button1按下的回调函数,如下所示:

        case LEDBUTTON_BUTTON:NRF_LOG_INFO("Send button state change.");err_code = ble_lbs_on_button_change(m_conn_handle, &m_lbs, button_action);if (err_code != NRF_SUCCESS &&err_code != BLE_ERROR_INVALID_CONN_HANDLE &&err_code != NRF_ERROR_INVALID_STATE &&err_code != BLE_ERROR_GATTS_SYS_ATTR_MISSING){APP_ERROR_CHECK(err_code);}break;

可以看出,我们是通过ble_lbs_on_button_change来更新Button characteristic的值的,ble_lbs_on_button_change具体函数实现如下所示:

uint32_t ble_lbs_on_button_change(uint16_t conn_handle, ble_lbs_t * p_lbs, uint8_t button_state){ble_gatts_hvx_params_t params;uint16_t len = sizeof(button_state);memset(&params, 0, sizeof(params));params.type   = BLE_GATT_HVX_NOTIFICATION;params.handle = p_lbs->button_char_handles.value_handle;params.p_data = &button_state;params.p_len  = &len;return sd_ble_gatts_hvx(conn_handle, &params);}

我们可以仿照Button1的做法,来添加Button2的代码。首先初始化app_button模块,让button2按下事件可以被button_event_handler捕获,如下:

    static app_button_cfg_t buttons[] ={{LEDBUTTON_BUTTON, false, BUTTON_PULL, button_event_handler},{BSP_BUTTON_1, false, BUTTON_PULL, button_event_handler}};

然后在button_event_handler调用ble_button2_send(uint16_t conn_handle, ble_lbs_t * p_lbs, uint8_t val),以更新Button characteristic的值,代码如下所示:

        case BSP_BUTTON_1:NRF_LOG_INFO("Button2 pressed.");ble_button2_send(m_conn_handle, &m_lbs, 5);break;

ble_button2_send(uint16_t conn_handle, ble_lbs_t * p_lbs, uint8_t val)实现代码如下所示:

uint32_t ble_button2_send(uint16_t conn_handle, ble_lbs_t * p_lbs, uint8_t val){ble_gatts_hvx_params_t params;uint16_t len = sizeof(val);memset(&params, 0, sizeof(params));params.type   = BLE_GATT_HVX_NOTIFICATION;params.handle = p_lbs->button_char_handles.value_handle;  //Button characteristic value handleparams.p_data = &val;params.p_len  = &len;return sd_ble_gatts_hvx(conn_handle, &params);      }

重新编译下载blinky程序,连接设备,使能cccd,按下Button2,你会看到Button characteristic的值变为5:

3.4 修改LED characteristic行为(手机发数据给设备)

由于nRF connect把LED characteristic的值写死了,只能发送“ON”或者“OFF”,前面也测试过,发送“ON”之后,LED3将点亮,其实这里的“ON”,就是数值1。我们现在增加一个新的功能:在收到“ON”命令后,把LED4 toggle一下。

这个实现起来比较简单,我们只需在led_write_handler中添加bsp_board_led_invert(BSP_BOARD_LED_3),整体代码如下所示:

static void led_write_handler(uint16_t conn_handle, ble_lbs_t * p_lbs, uint8_t led_state){if (led_state){bsp_board_led_on(LEDBUTTON_LED);NRF_LOG_INFO("Received LED ON!");bsp_board_led_invert(BSP_BOARD_LED_3);}else{bsp_board_led_off(LEDBUTTON_LED);NRF_LOG_INFO("Received LED OFF!");}}

重新编译下载blinky程序,连接设备,你会发现第一次发送“ON”,LED4点亮,第二次发送“ON”,LED4又将熄灭。

通过全文搜索“led_write_handler”,你会发现这个函数是被ble_lbs.c中的on_write调用,而on_write又被ble_lbs_on_ble_evt调用,而ble_lbs_on_ble_evt就是我们的BLE事件回调函数,每当softdevice收到LED characteristic的写操作时,都会调用它,这就是通过nRF connect操作设备的过程和原理。

上述代码工程我已经将其上传到百度云盘中,有需要的同学可以到如下链接下载:

  • 链接: https://pan.baidu.com/s/1FKTfY3Q_zBVvviO7KC7Gyg#list/path=%2Fblog   密码: y8fb

下载“tutorial_ble_app_blinky_SDK15_3_0.rar”,然后解压缩到SDK15.3.0如下目录下:nRF5_SDK_15.3.0_59ac345\examples\ble_peripheral\

即可成功编译。

4. 开发手机端Blinky程序

Nordic同时提供手机端的Blinky程序,该程序源代码完全向用户开放,以帮助用户快速开发自己的第一个Android或者iOS BLE应用程序。用户可以先到app store下载iOS版nRF blinky,或者到Github下载Android版nRF blinky(下载链接:https://github.com/NordicSemiconductor/Android-nRF-Blinky/releases)。手机版的nRF Blinky跟前面介绍的Blinky固件是配合工作的,通过手机版nRF Blinky可以对前面的blinky固件进行操作。nRF Blinky app图标如下所示:

nRF Blinky操作界面如下所示:

  • nRF Blinky Android版源代码及开发说明请参考:https://github.com/NordicSemiconductor/Android-nRF-Blinky
  • nRF Blinky iOS版源代码及开发说明请参考:https://github.com/NordicSemiconductor/iOS-nRF-Blinky

这篇文章主要让大家对BLE有个大概的认识,后面我会专门写一篇文章来介绍上面提到的BLE service,characteristic,write,notify以及CCCD等,以帮助大家深刻理解这些概念,感兴趣的读者请参考:

手把手教你开发BLE数据透传应用程序

转载于:https://www.cnblogs.com/iini/p/8996025.html

开发你的第一个BLE应用程序—Blinky相关推荐

  1. Moblin v2开发环境设置——创建一个新应用程序

    (翻译:徐诚 http://blog.csdn.net/shizhebsys 保留版权) 这里是开始Moblin开发重要起点.本页描述如何创建一个简单的应用程序,并且介绍少数有用的工具帮助你快速启动开 ...

  2. 如何成为Web开发人员—编写第一个Web应用程序

    Where to begin? This is perhaps the most common question asked by all newcomers to IT. There are so ...

  3. imx6 android 最新,IMX6开发板创建第一个Android应用程序helloworld

    运行行 AndroidStudio 程序.如下图,选择创建一个新的 androidstudio 工程(基于 迅为-i.mx6开发板) 应用名称改为"helloworld",项目保存 ...

  4. [培训-DSP快速入门-4]:C54x DSP开发环境与第一个C语言程序

    作者主页(文火冰糖的硅基工坊):https://blog.csdn.net/HiWangWenBing 本文网址:https://blog.csdn.net/HiWangWenBing/article ...

  5. iOS 11开发教程(三)运行第一个iOS 11程序

    iOS 11开发教程(三)运行第一个iOS 11程序 运行iOS11程序 创建好项目之后,就可以运行这个项目中的程序了.单击运行按钮,如果程序没有任何问题的话,会看到如图1.6和1.7的运行效果. 图 ...

  6. Xamarin iOS开发实战第1章使用C#编写第一个iOS应用程序

    Xamarin iOS开发实战第1章使用C#编写第一个iOS应用程序 C#原本是用来编写Windows以及Windows Phone的应用程序.自从Xamarin问世后,C#的作用就发生了很大的变化. ...

  7. 《Unity 3D 游戏开发技术详解与典型案例》——1.3节第一个Unity 3D程序

    本节书摘来自异步社区<Unity 3D 游戏开发技术详解与典型案例>一书中的第1章,第1.3节第一个Unity 3D程序,作者 吴亚峰 , 于复兴,更多章节内容可以访问云栖社区" ...

  8. java的应用程序开发_开发一个Java应用程序(1)

    开发一个Java应用程序(1) App Engine上的Java Web应用程序通过Java Servlet标准接口与应用程序服务器交互.一个应用程序由一个或多个类组成,这些类都扩展自一个servle ...

  9. 只需6步,教你从零开发一个签到小程序

    摘要:针对于具备瞬时流量.业务场景比较简单的小程序,开发者借助FunctionGraph,可以方便快捷的搭建一个健壮的小程序后台. 本文分享自华为云社区<智慧校园想搞好,FunctionGrap ...

  10. 一个程序如何连接到外网_如何从头开始开发一个微信小程序

    网上有很多的人在问:怎么开发一个微信小程序?今天我来给大家详细讲讲如何申请开发并部署一个微信小程序,大家看完这篇文章后就能够自己运营一个属于自己的小程序了. 现在的小程序有百度小程序,头条小程序,支付 ...

最新文章

  1. 设置按钮不可见_华为手机居然有【3种录屏方法】,很多人都不知道,真的太实用了...
  2. Linux下的tar归档及解压缩功能详解
  3. BZOJ3123: [Sdoi2013]森林
  4. Python-学生信息管理系统.exe
  5. 数据结构与算法专题——第十二题 Trie树
  6. leetcode91. 解码方法
  7. 东华大学计算机年薪,东华大学公布应届毕业生薪酬:本科生月薪中位数6637元...
  8. api文档数据量太大崩溃_Tableau的API操作(一)-取消任务刷新
  9. 美股本周第二次熔断:道指大跌近10% 费城半导体指数大跌11%
  10. 写入和读取外部存储文件
  11. docker 镜像修改的配置文件自动还原_基于Docker搭建Redis一主两从三哨兵
  12. 在做UDP传输的时候,出现的这个问题,哪个大佬能帮忙看一看啊
  13. c语言求布尔矩阵的乘积,离散数学 关系矩阵的布尔乘法的简便方法
  14. python词云分析 jieba+wordcloud 按词频生成词云
  15. lvgl chart
  16. ICTCLAS代码学习笔记之CSpan类
  17. 手机显示DNS服务器异常,手机dns服务器异常怎么设置
  18. 自己整理的运维面试题,必须会。
  19. NLP模型笔记2022-03:简单理解nlp句法分析
  20. 常见花材的固定的方法有哪些_别再傻傻只知道使用花泥了,这4种纯天然花材固定方法你该试试!...

热门文章

  1. linux系统ss命令详解,ss命令 - Linux命令大全 | linux教程
  2. ubuntu linux安装google输入法
  3. 16G DWDM SFP+光模块特性及解决方案
  4. 【分享-世界著名的免费摄影图库】 素材中国, 高清壁纸 - PxHere摄影图库
  5. Python实现视频中的音频提取
  6. Android之音频和视频的提取
  7. 化学到底是不是一个好专业?该不该转行?————试图以此文终结所有相关讨论
  8. react 网页截图
  9. 为什么说服务逻辑,才是SaaS的底层逻辑
  10. CSP-2022 游寄