NORDIC BLE SoC 软件入门例程简介 – ble_app_uart
很有朋友在拿到DK板,装好环境之后还是有些疑惑,到底该如何玩第一个例程呢? 这里我们简单给大家介绍,如何玩第一个例程:ble_app_uart !
ble_app_uart 这个例程,跟它的名字一样,是BLE和uart 透传的功能。
它将nRF52收到的串口数据,通过BLE发送给手机;将nRF52收到的BLE数据,通过nRF52的串口打印出来。可以认为这是一个简易的透传模块功能!下面就SDK15.3(最新是SDK17.02 ,但大体是一样的)的ble_app_uart 例程进行讲解。
工程文件简介
工程目录:nRF5_SDK_15.3.0_59ac345\examples\ble_peripheral\ble_app_uart\pca10040\s132\arm5_no_packs
KEIL的用户,首先按照 NORDIC BLE SOC开发环境 – 编译器 的说明弄好pack,再编译工程。
工程目录中的文件,如下图做出了基本解释。
需要注意的是,
绝大部分用户,可以修改的文件是4个文件:main.c , sdk_config.h , ble_nus.c ,ble_nus.h ,其他文件初级玩家请不要修改!
ble_nus.c 和 ble_nus.h 若要修改,请复制出来备份!
除了main.c , sdk_config.h 和device里的2个芯片启动配置文件是隶属于各个工程的,其他为文件整个SDK共享!
main() 主函数
下图是main.c文件中的main函数,其主要内容都是初始化。各函数功能参考注释描述。
其中需要注意:
- 如果log采用的串口,请不要再单独初始化uart。串口log和uart模块请不要重合使用。除了nRF52840和nRF52833之外,都只有1个串口。
- apptimer是利用RTC和软中断做出的timer,不是芯片外设中的timer。可以根据用户需要创建很多个(消耗RAM),且运行时功耗低。 使用在无需高精准计时场景非常适合的。
- BSP部分如果不需要可以关闭,最简单省事的方法如下。其他bsp操作的代码会自动失效。
- 功耗处理部分例程中只针对CPU和一些errta做了处理。程序在运行到idle_state_handle之后,SoC就进入了低功耗模式(CPU暂停工作,CPU不耗电了),并等待事件/中断来唤醒它,被唤醒之后在循环中接着运行。其他的外设如UART、timer、apptimer等不会被自动关闭,依然运行耗电中。为了让整体功耗下降,用户要根据自身应用的情景做调节,关闭不需要的外设。
- ble_stack_init是协议栈初始化函数,运行之后协议栈就启动了,可以调用协议栈的函数,协议栈函数是sd开头的函数,它们只有申明,没有定义,其用法在各自申明的注释处中有说明。协议栈启动以后,如果进行仿真,仿真停下来后再运行,程序会错误挂起。
- 初级使用时,BLE相关初始化函数流程,无特殊、无需要的情况不用修改。
- advertising_start 是开启广播,初始化完成之后运行该函数,能够搜到BLE广播了。
- printf是的输出是重映射到串口上的,可以根据需求修改printf的功能,并且它是实时输出的。
- NRF_LOG_INFO 是log模块的输出函数,其log等级是INFO,相关等级还有DEBUG,WARING等等。默认此函数是先将待输出的内容放到缓存中,不是立即输出。在调用idle_state_handle之后,内容才真正通过硬件输出。让log将缓存中的内容立刻输出的函数一般采用 NRF_LOG_PROCESS,NRF_LOG_FLUSH 等。
串口设置及接收处理
串口的相关操作是这个例程关键的部分,但也非常容易理解。其作用就是收到的串口数据通过BLE发送出去。
例程使用的是app_uart_fifo模块,它是uart与app fifo的结合,app fifo是一个软件的缓冲区。此模块将串口硬件收到的数据放入uart接收fifo,并产生接收完成事件,用户在此事件下从fifo中取出uart接收到的数据即可。uart在发送的时候,也是将待发送的数据放入fifo,并在发送完成一个字节之后,自动发送第二个字节,不会一直等待数据发送完成,不会长时间占用CPU。一般来说,app_uart_fifo模块可以满足大部分应用对串口需求。
串口数据是否通过BLE发送的标志是 ‘\n’ , ‘\r’ 和 数据长度超出 这三个标志。用户可以根据自身需求修改。
当满足发送要求后,调用ble_nus_data_send将数据通过BLE发送,并等待数据成功放入协议栈的发送队列。若返回值err_code等于0,则代表放入协议栈发送队列成功,之后协议栈会将此包数据发送出去。若返回值非0,则代表此包数据发送失败,需要用户自己重发。
回调函数uart_event_handle中有两个错误提示事件。APP_UART_COMMUNICATION_ERROR 代表串口通信错误,串口数据不稳、校验错误等均会产生次错误,原因放在app_uart_evt_t.data.error_communication中,可以在串口寄存器中找到对应原因的解释;APP_UART_FIFO_ERROR代表串口fifo产生了错误,fifo溢出等,原因放在app_uart_evt_t.data.error_code 中,查看app fifo模块的说明可以找到具体原因。但是一般来说,可以将这两个事件屏蔽,它们不会对应用带来损害。
BLE相关处理
BLE相关操作都是建立在启动协议栈之后,函数ble_stack_init()就是协议栈的配置与启动,具体配置在sdk_config.h中。
下面就初级使用中涉及到BLE相关的配置和操作做简要说明。
- 广播名字通过宏定义DEVICE_NAME的字符串来设置,并在gap_params_init函数中,使用协议栈函数sd_ble_gap_device_name_set做设置。例如该例程使用”Nordic_UART” 作为广播名字。
- 广播间隔通过宏定义APP_ADV_INTERVAL代表的数值来设置,并在广播初始化函数advertising_init中进行赋值。BLE标准中,广播间隔的范围是20ms~10.24s, 设置步长是0.625ms。例如该例程使用64,表示广播间隔是40ms。
- 广播时长通过宏定义APP_ADV_DURATION来设置,并在广播初始化函数advertising_init中进行赋值,它代表了一轮有限时间广播持续的最长时间,协议栈规定有限时间广播时长最大是180s,设置步长为10ms。例如该例程中使用18000代表180s。我们需要无限时长广播(持续广播),我们可以将数值设为0,并修改 init.advdata.flags的值为BLE_GAP_ADV_FLAGS_LE_ONLY_GENERAL_DISC_MODE。
- 连接间隔设置是一个范围,它通过宏定义MIN_CONN_INTERVAL与MAX_CONN_INTERVAL来设置,并在gap_params_init函数中进行了赋值。BLE标准中,连接间隔的范围是7.5ms~4s,设置步长为1.25ms。例程中使用MSEC_TO_UNITS来辅助用户换算,因此在设置参数时直接填入毫秒即可。例如使用MSEC_TO_UNITS(20, UNIT_1_25_MS) 设置,修改数值20就是修改连接间隔的最小值。最终的连接间隔由主从机双方协商确认。如果需要相对精确的连接间隔,比如100ms,可以设置最小为95ms,最大为105ms。
- BLE事件在ble_evt_handler回调函数中给出,其中包括 链接建立、链接断开等等。
- BLE数据接收函数是其服务回调函数,在服务初始化ble_nus_init中设置。该例程中服务回调函数是nus_data_handler,这里将BLE收到的数据传给用户。该例程中将BLE接收到的数据通过串口输出了。
注意
在实际开发当中,建议在中断回调、事件回调中不要处理太多程序,尤其是耗时较长,又带有循环的程序,例如例程中接收到数据立刻做了转发的动作。实际开发中建议将数据copy出来,在main loop中再做处理。
相信大家阅读完之后,可以在ble_app_uart上玩出很多风采!