NRF51822蓝牙服务(6)——显示设备信息

ぐ巨炮叔叔 提交于 2019-12-10 23:05:00

前言

有时候开发项目,我们希望能通过蓝牙直接读取到设备的信息,例如制造商、固件版本、硬件版本和软件版本等信息。所以,今天我们就直接使用官方提供的服务来实现这个需求。

实验分析

首先,我们需要把官方驱动例程添加到我们的工程(这里使用前面用到的串口例程)目录里面:

路径是:工程目录\components\ble\ble_services\ble_dis

接着,我们去看看官方提供给我们的接口函数:

ble_dis.h:

/**@brief Device Information Service init structure. This contains all possible characteristics 
 *        needed for initialization of the service.
 */
typedef struct
{
    ble_srv_utf8_str_t             manufact_name_str;           /**< Manufacturer Name String. */
    ble_srv_utf8_str_t             model_num_str;               /**< Model Number String. */
    ble_srv_utf8_str_t             serial_num_str;              /**< Serial Number String. */
    ble_srv_utf8_str_t             hw_rev_str;                  /**< Hardware Revision String. */
    ble_srv_utf8_str_t             fw_rev_str;                  /**< Firmware Revision String. */
    ble_srv_utf8_str_t             sw_rev_str;                  /**< Software Revision String. */
    ble_dis_sys_id_t *             p_sys_id;                    /**< System ID. */
    ble_dis_reg_cert_data_list_t * p_reg_cert_data_list;        /**< IEEE 11073-20601 Regulatory Certification Data List. */
    ble_dis_pnp_id_t *             p_pnp_id;                    /**< PnP ID. */
    ble_srv_security_mode_t        dis_attr_md;                 /**< Initial Security Setting for Device Information Characteristics. */
} ble_dis_init_t;

/**@brief Function for initializing the Device Information Service.
 *
 * @details This call allows the application to initialize the device information service. 
 *          It adds the DIS service and DIS characteristics to the database, using the initial
 *          values supplied through the p_dis_init parameter. Characteristics which are not to be
 *          added, shall be set to NULL in p_dis_init.
 *
 * @param[in]   p_dis_init   The structure containing the values of characteristics needed by the
 *                           service.
 *
 * @return      NRF_SUCCESS on successful initialization of service.
 */
uint32_t ble_dis_init(const ble_dis_init_t * p_dis_init);

接下来,我们直接开始应用层的代码实现:

#include "ble_dis.h"

#define MANUFACTURER_NAME               "Sam_Man"                                  /**< Manufacturer. Will be passed to Device Information Service. */
#define HARDWARE_REVISION               "Sam_Hard"
#define SOFTWARE_REVISION               "V2.0"
#define FIRMWARE_REVISION               "S110"

将ble_dis.h包含,并宏定义需要显示的字符串。

接下来,修改服务初始化函数:

/**@brief Function for initializing services that will be used by the application.
 */
static void services_init(void)
{
    uint32_t       err_code;
    ble_nus_init_t nus_init;
	ble_dis_init_t dis_init;
    
    memset(&nus_init, 0, sizeof(nus_init));
    nus_init.data_handler = nus_data_handler;   
    err_code = ble_nus_init(&m_nus, &nus_init);
    APP_ERROR_CHECK(err_code);
	
	// Initialize Device Information Service.
    memset(&dis_init, 0, sizeof(dis_init));

    ble_srv_ascii_to_utf8(&dis_init.manufact_name_str, (char *)MANUFACTURER_NAME);
    ble_srv_ascii_to_utf8(&dis_init.hw_rev_str, (char *)HARDWARE_REVISION);
    ble_srv_ascii_to_utf8(&dis_init.sw_rev_str, (char *)SOFTWARE_REVISION);
    ble_srv_ascii_to_utf8(&dis_init.fw_rev_str, (char *)FIRMWARE_REVISION);
    
    BLE_GAP_CONN_SEC_MODE_SET_OPEN(&dis_init.dis_attr_md.read_perm);
    BLE_GAP_CONN_SEC_MODE_SET_NO_ACCESS(&dis_init.dis_attr_md.write_perm);

    err_code = ble_dis_init(&dis_init);
    APP_ERROR_CHECK(err_code);
}

到这里,就完成了所有操作。是不是很简单,就是这么简单。

结果验证

  • 手机连接蓝牙,我们可以看到新增一个设备信息服务
  • 这个服务包含几个只读的特性
  • 把这几个特定都更新一遍,就会发现特征值正是我们定义的字符串

题外话

问:为什么我们定义的私有服务,在调试软件上面显示的名称总是unknown呢?有没有办法让私有服务的名称有意义呢?

答:没有办法实现。因为Battery Service,Heart rate这些服务对应的UUID都是在蓝牙联盟注册过的,全世界通用的,而自己定义服务时定义的uuid肯定是自定义的,并没有注册过,所以必然显示unknown。

总结

通过这个实验,我们学会了如何显示设备的信息。

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!