1 NRF52840 SDK 基础
1.1 GATT Service
蓝牙协议中定义 GATT service 为:
“A service is a collection of data and associated behaviors to accomplish a particular function or feature. [...] A service definition may contain […] mandatory characteristics and optional characteristics.”
可以简单理解为为了实现一定的功能,将所用到的数据和动作集合成一个整体。蓝牙协议已定义好一些固定的服务,例如 0x1800 Generic Access, 0x180F Battery Service,0x180A Device Informati0on, 0x180D Heart Rate 等。
1.2 Characteristic
蓝牙协议中定义 Characteristic 为:
“A characteristic is a value used in a service along with properties and configuration information about how the value is accessed and information about how the value is displayed or represented.”
图 1.2-1 GATT 服务和特征关系
在服务的基础上,可以理解特征为实际承载和传输信息的地方。服务、特征和 UUID 的关系可以简单理解为图 1.2-1 的关系,储藏室内有一个文件柜,文件柜有三个抽屉,每个抽屉上有各自的标号,那么这个文件柜可以看做是服务,抽屉可以看做是特征,而抽屉上的标号可以看做是 UUID,信息就是抽屉里的文件。
1.3 读写流程
nrf52840 的 GATT Service 服务读写流程有较大不同。如图 1.3-1 所示:
图 1.3-1 GATT Service 读写流程
Read:外部设备通过 GATT Service 发过来的信息,被协议栈打包,通过事件的形式传递给应用层,在应用层需要调用 observe 函数来监控各事件,在从其中解析出需要的数据。
Write:在应用层将需要发送的数据打包,调用协议栈函数 sd_ble_gatts_hvx()传递给协议栈,协议栈会根据其收到的参数来选择通过哪一个服务的哪一个特征,以什么形式发送出去。
1.4 设备和软件
设备:nRF52840 开发板,PCA10056
SDK:nRF5_SDK_15.2.0
SoftDevice:s140_nrf52_6.1.1
IDE: Keil5.21 + SourceInsight4.0
PC 端烧录工具 nRF Connect + nrfjprog
手机端测试工具:nRF Connect
2 新建和配置工程
1. 新建工程,设备选择 nRF52840 吗,如下图所示。
图 1.4‑1 新建工程
2. 选择扩展包,选择CMSIS-CORE, Device-Startup,如下图所示。
图 1.4‑2 选择扩展包
3. 在工程目录example/ble_peripheral/ble_app_sean下新建文件夹config,存放配置文件,复制一份sdk_config.h 到工程目录下,如下图所示。
图 1.4‑3 准备sdk_config
为了在调试时可以从串口看到调试NRF_LOG_INFO的信息,确保在sdk_config.h中有添加NRF_LOG_BACKEND_UART_ENABLED。
// <e> NRF_LOG_BACKEND_UART_ENABLED - nrf_log_backend_uart - Log UART backend
//==========================================================
#ifndef NRF_LOG_BACKEND_UART_ENABLED
#define NRF_LOG_BACKEND_UART_ENABLED 1
#endif
// <o> NRF_LOG_BACKEND_UART_TX_PIN - UART TX pin
#ifndef NRF_LOG_BACKEND_UART_TX_PIN
#define NRF_LOG_BACKEND_UART_TX_PIN 6
#endif
// <o> NRF_LOG_BACKEND_UART_BAUDRATE - Default Baudrate
// <323584=> 1200 baud
// <643072=> 2400 baud
// <1290240=> 4800 baud
// <2576384=> 9600 baud
// <3862528=> 14400 baud
// <5152768=> 19200 baud
// <7716864=> 28800 baud
// <10289152=> 38400 baud
// <15400960=> 57600 baud
// <20615168=> 76800 baud
// <30801920=> 115200 baud
// <61865984=> 230400 baud
// <67108864=> 250000 baud
// <121634816=> 460800 baud
// <251658240=> 921600 baud
// <268435456=> 1000000 baud
#ifndef NRF_LOG_BACKEND_UART_BAUDRATE
#define NRF_LOG_BACKEND_UART_BAUDRATE 30801920
#endif
// <o> NRF_LOG_BACKEND_UART_TEMP_BUFFER_SIZE - Size of buffer for partially processed strings.
// <i> Size of the buffer is a trade-off between RAM usage and processing.
// <i> if buffer is smaller then strings will often be fragmented.
// <i> It is recommended to use size which will fit typical log and only the
// <i> longer one will be fragmented.
#ifndef NRF_LOG_BACKEND_UART_TEMP_BUFFER_SIZE
#define NRF_LOG_BACKEND_UART_TEMP_BUFFER_SIZE 64
#endif
4. 添加工程文件
- 在Application中添加main.c , sdk_config.h
- 在Board Definition中添加boards.c
- 在Board Support中添加bsp.c, bsp_btn_ble.c
- 在UTF8/UTF16 converter中添加utf.c
- 在nRF_BLE中添加ble_advdata.c, ble_advertisng.c, ble_conn_params.c, ble_conn_state.c, ble_link_ctx_manager.c, ble_srv_common.c, nrf_ble_gatt.c, nrf_ble_qwr.c
- 在nRF_Drivers中添加nrf_drv_clock.c, nrf_drv_uart.c, nrf_clock.c, nrfx_gpiote.c, nrfx_power_clock.c, nrfx_prs.c, nrfx_uart.c, nrfx_uarte.c.
- 在nRF_Libraries中添加 app_button.c, app_error.c, app_error_handle_keil.c, app_error_weak.c, app_util_platform.c, app_scheduler.c, app_timer.c, crc16.c, fds.c, hardfault_implementation.c, nrf_assert.c, nrf_atfifo.c, nrf_atflags.c nrf_atomic.c, nrf_balloc.c, nrf_fprintf.c, nrf_fprintf_format.c, nrf_fstorage.c, nrf_fstroage_sd.c, nrf_pwr_mgmt.c, nrf_section_iter.c, nrf_strerror.c, sensorsim.c. nrf_memobj.c, nrf_ringbuf.c
- 在nRF_Log中添加:nrf_log_backend_rtt.c, nrf_log_backend_serial.c, nrf_log_default_backends.c, nrf_log_frontend.c, nrf_log_str_formatter.c
- 在nRF_Segger_RTT中添加SEGGER_RTT.c, SEGGER_RTT_Syscalls_KEIL.c, SEGGER_RTT_printf.c
- 在nRF_SoftDevice中添加nrf_sdh.c, nrf_sdh_ble.c, nrf_sdh_soc.h
5. 在Option for Target ‘nrf52840_sean’中,配置
Target:
图 1.4‑4 配置工程Target
Output:
图 1.4‑5 配置工程Output
C/C++: 在Define写:BOARD_PCA10056 CONFIG_GPIO_AS_PINRESET FLOAT_ABI_HARD NRF52840_XXAA NRF_SD_BLE_API_VERSION=6 S140 SOFTDEVICE_PRESENT SWI_DISABLE0 __HEAP_SIZE=8192 __STACK_SIZE=8192
其他选项按下图配置: