NRF52832学习笔记(1)—— 添加自有service(基于SDK15.3)

前言:

SDK版本15.3

评估板:pca10040

在uart的例程中添加battery service

添加之前,手机连上设备之后扫描到的service如下:

NRF52832学习笔记(1)—— 添加自有service(基于SDK15.3)_第1张图片

一、分配ram空间

softdevice的flash code是确定,但ram是不确定,和sevice的多少以及以下几个宏有关:

  • #define NRF_SDH_BLE_TOTAL_LINK_COUNT 1  //一共同时可以支持多少个连接,使用默认值即可
  • #define NRF_SDH_BLE_PERIPHERAL_LINK_COUNT 1  //作为从模式的连接同时能有几个,使用默认值即可
  • #define NRF_SDH_BLE_CENTRAL_LINK_COUNT 0  //作为主模式的连接同时能有几个,使用默认值即可
  • #define NRF_SDH_BLE_GATT_MAX_MTU_SIZE 247  // MTU 值的大小,使用默认值即可,nrf51 系列中 mtu 的默认值为23
  • #define NRF_SDH_BLE_VS_UUID_COUNT 1  //用户自定义的base UUID有几个,使用默认值即可,因为例程中的uart service 使用了一个的128bit的 uuid ,所以这是 count 值为1。因为此次实验添加的是自有 service ,所以 base uuid 只有uart service 一个。每添加一个 base uuid , count 值就+1,同时每增加一个uuid,IRAM1的起始地址就要增加0x10,size 同时减少0x10。

NRF52832学习笔记(1)—— 添加自有service(基于SDK15.3)_第2张图片

  • #define NRF_SDH_BLE_GATTS_ATTR_TAB_SIZE 1408  //Attribute table总共占多少协议栈RAM空间,该值必须是4的倍数。
  • #define NRF_SDH_BLE_SERVICE_CHANGED 0  //要不要包含service change characteristic,使用默认值即可

二、代码修改

2.1 添加文件

  • 添加service文件,文件路径为..\..\..\..\..\..\components\ble\ble_services\ble_bas

NRF52832学习笔记(1)—— 添加自有service(基于SDK15.3)_第3张图片

  • 添加sensorsim文件(此文件只是为了演示电量变化而添加的传感器数据模拟器,正式项目可以不用加),文件路径为..\..\..\..\..\..\components\libraries\sensorsim

NRF52832学习笔记(1)—— 添加自有service(基于SDK15.3)_第4张图片

该文件需要在keil的工程配置文件中设置文件路径才可以使用:

NRF52832学习笔记(1)—— 添加自有service(基于SDK15.3)_第5张图片

2.2 配置sdk_config.h文件

  • 使能bas service

NRF52832学习笔记(1)—— 添加自有service(基于SDK15.3)_第6张图片

2.3 添加头文件

在main.c文件中添加 

  • #include "ble_bas.h"
  • #include "sensorsim.h"(此文件只是为了演示电量变化而添加的传感器数据模拟器,正式项目可以不用加)

2.4 添加bas实例

在main.c文件中添加实例

BLE_BAS_DEF(m_bas);                                                                 /**< Structure used to identify the battery service. */

2.5 bas service初始化

在services_init(void) api中添加以下代码:

    ble_bas_init_t     bas_init;

    // Initialize Battery Service.
    memset(&bas_init, 0, sizeof(bas_init));

    bas_init.evt_handler          = NULL;
    bas_init.support_notification = true;
    bas_init.p_report_ref         = NULL;
    bas_init.initial_batt_level   = 100;
		
    // Here the sec level for the Battery Service can be changed/increased.
    bas_init.bl_rd_sec        = SEC_OPEN;
    bas_init.bl_cccd_wr_sec   = SEC_OPEN;
    bas_init.bl_report_rd_sec = SEC_OPEN;

    err_code = ble_bas_init(&m_bas, &bas_init);
    APP_ERROR_CHECK(err_code);

到此为止,手机已经可以正常查询到设备的 bsa service了。

以下为使用 sensorsim 功能模拟设备的电量变化并主动上报

2.6 添加变量和宏定义

#define BATTERY_LEVEL_MEAS_INTERVAL     APP_TIMER_TICKS(2000)                       /**< Battery level measurement interval (ticks). */
#define MIN_BATTERY_LEVEL               81                                          /**< Minimum simulated battery level. */
#define MAX_BATTERY_LEVEL               100                                         /**< Maximum simulated 7battery level. */
#define BATTERY_LEVEL_INCREMENT         1                                           /**< Increment between each simulated battery level measurement. */

APP_TIMER_DEF(m_battery_timer_id);                                                  /**< Battery timer. */

static sensorsim_cfg_t   m_battery_sim_cfg;                         /**< Battery Level sensor simulator configuration. */
static sensorsim_state_t m_battery_sim_state;                       /**< Battery Level sensor simulator state. */

2.7 在main(void)中添加 sensor simulator 初始化和 timers start

sensor_simulator_init();
application_timers_start();

2.8 添加battery定时器

  • 在 timers_init() api中添加以下代码
    // Create timers.
    err_code = app_timer_create(&m_battery_timer_id,
                                APP_TIMER_MODE_REPEATED,
                                battery_level_meas_timeout_handler);
    APP_ERROR_CHECK(err_code);
  • 添加battery_level_meas_timeout_handler(void * p_context) api
/**@brief Function for handling the Battery measurement timer timeout.
 *
 * @details This function will be called each time the battery level measurement timer expires.
 *
 * @param[in] p_context  Pointer used for passing some arbitrary information (context) from the
 *                       app_start_timer() call to the timeout handler.
 */
static void battery_level_meas_timeout_handler(void * p_context)
{
    UNUSED_PARAMETER(p_context);
    battery_level_update();
}
  • 添加battery_level_update(void) api
/**@brief Function for performing battery measurement and updating the Battery Level characteristic
 *        in Battery Service.
 */
static void battery_level_update(void)
{
    ret_code_t err_code;
    uint8_t  battery_level;

    battery_level = (uint8_t)sensorsim_measure(&m_battery_sim_state, &m_battery_sim_cfg);

    err_code = ble_bas_battery_level_update(&m_bas, battery_level, BLE_CONN_HANDLE_ALL);
    if ((err_code != NRF_SUCCESS) &&
        (err_code != NRF_ERROR_INVALID_STATE) &&
        (err_code != NRF_ERROR_RESOURCES) &&
        (err_code != NRF_ERROR_BUSY) &&
        (err_code != BLE_ERROR_GATTS_SYS_ATTR_MISSING)
       )
    {
        APP_ERROR_HANDLER(err_code);
    }
}

三、测试

经过以上操作就可以在手机端使用bas service了。

NRF52832学习笔记(1)—— 添加自有service(基于SDK15.3)_第7张图片

 

你可能感兴趣的:(NRF52系列)