1. 前言
上一章我们介绍了如何将官方提供的例子在板子上跑起来,本章我们将自己从零开始实现心率推送的功能。
2. 创建空工程
命名为Hrs。
新建的空工程是可以编译通过且烧录进去可以运行的。
3. 配置硬件资源
需要用一个LED闪烁来作为系统正常运行的指示,同时串口打印也要配置(其实空工程这两个已经配置过的,这里再次演示)。
选择LED 1 。
还可以直接查看代码。
PUART配置(P32, P37):
4. 蓝牙配置
4.1 入口
4.2 GATT 配置
4.3 添加心率推送服务
4.4 保存
保存后可以看到代码中已经包含了心率推送相关。
const uint8_t gatt_database[] =
{
/* Primary Service: Generic Access */
PRIMARY_SERVICE_UUID16 (HDLS_GAP, __UUID_SERVICE_GENERIC_ACCESS),
/* Characteristic: Device Name */
CHARACTERISTIC_UUID16 (HDLC_GAP_DEVICE_NAME, HDLC_GAP_DEVICE_NAME_VALUE, __UUID_CHARACTERISTIC_DEVICE_NAME, LEGATTDB_CHAR_PROP_READ, LEGATTDB_PERM_READABLE),
/* Characteristic: Appearance */
CHARACTERISTIC_UUID16 (HDLC_GAP_APPEARANCE, HDLC_GAP_APPEARANCE_VALUE, __UUID_CHARACTERISTIC_APPEARANCE, LEGATTDB_CHAR_PROP_READ, LEGATTDB_PERM_READABLE),
/* Primary Service: Generic Attribute */
PRIMARY_SERVICE_UUID16 (HDLS_GATT, __UUID_SERVICE_GENERIC_ATTRIBUTE),
/* Primary Service: Heart Rate */
PRIMARY_SERVICE_UUID16 (HDLS_HRS, __UUID_SERVICE_HEART_RATE),
/* Characteristic: Heart Rate Measurement */
CHARACTERISTIC_UUID16 (HDLC_HRS_HEART_RATE_MEASUREMENT, HDLC_HRS_HEART_RATE_MEASUREMENT_VALUE, __UUID_CHARACTERISTIC_HEART_RATE_MEASUREMENT, LEGATTDB_CHAR_PROP_NOTIFY, LEGATTDB_PERM_NONE),
/* Descriptor: Client Characteristic Configuration */
CHAR_DESCRIPTOR_UUID16_WRITABLE (HDLD_HRS_HEART_RATE_MEASUREMENT_CLIENT_CHAR_CONFIG, __UUID_DESCRIPTOR_CLIENT_CHARACTERISTIC_CONFIGURATION, LEGATTDB_PERM_READABLE | LEGATTDB_PERM_WRITE_REQ),
};
5. 编写应用代码
5.1 系统运行指示灯
/* Initaializing GPIO's */
wiced_hal_gpio_configure_pin(WICED_P27, GPIO_OUTPUT_ENABLE | GPIO_PULL_UP, GPIO_PIN_OUTPUT_HIGH);
/* Turn on LED1 */
wiced_hal_gpio_set_pin_output(WICED_P27, 0);
5.2 蓝牙
5.2.1 修改设备名称
uint8_t BT_LOCAL_NAME[] = {'H', 'r', 'm', '\0'};
uint8_t app_gap_device_name[] = {'H', 'r', 'm', };
5.2.2 广播数据
这部分代码在空工程建立的时候默认是有的,现在只需将注释去掉。
/* TODO - set advertisement data for your app */
app_set_advertisement_data();
wiced_result_t app_set_advertisement_data(void)
{
wiced_bt_ble_advert_elem_t adv_elem[3];
wiced_result_t result;
uint8_t num_elem = 0;
uint8_t flag = BTM_BLE_GENERAL_DISCOVERABLE_FLAG | BTM_BLE_BREDR_NOT_SUPPORTED;
adv_elem[num_elem].advert_type = BTM_BLE_ADVERT_TYPE_FLAG;
adv_elem[num_elem].len = sizeof(uint8_t);
adv_elem[num_elem].p_data = &flag;
num_elem++;
adv_elem[num_elem].advert_type = BTM_BLE_ADVERT_TYPE_NAME_COMPLETE;
adv_elem[num_elem].len = strlen((const char *)wiced_bt_cfg_settings.device_name);
adv_elem[num_elem].p_data = (uint8_t *)wiced_bt_cfg_settings.device_name;
num_elem++;
result = wiced_bt_ble_set_raw_advertisement_data(num_elem, adv_elem);
return result;
}
5.2.3 广播数据中增加心率服务UUID
wiced_result_t app_set_advertisement_data(void)
{
wiced_bt_ble_advert_elem_t adv_elem[3];
wiced_result_t result;
uint8_t num_elem = 0;
uint8_t flag = BTM_BLE_GENERAL_DISCOVERABLE_FLAG | BTM_BLE_BREDR_NOT_SUPPORTED;
adv_elem[num_elem].advert_type = BTM_BLE_ADVERT_TYPE_FLAG;
adv_elem[num_elem].len = sizeof(uint8_t);
adv_elem[num_elem].p_data = &flag;
num_elem++;
adv_elem[num_elem].advert_type = BTM_BLE_ADVERT_TYPE_NAME_COMPLETE;
adv_elem[num_elem].len = strlen((const char *)wiced_bt_cfg_settings.device_name);
adv_elem[num_elem].p_data = (uint8_t *)wiced_bt_cfg_settings.device_name;
num_elem++;
uint16_t hrm_uuid = __UUID_SERVICE_HEART_RATE;
adv_elem[num_elem].advert_type = BTM_BLE_ADVERT_TYPE_16SRV_COMPLETE;
adv_elem[num_elem].len = sizeof(hrm_uuid);
adv_elem[num_elem].p_data = (uint8_t *)&hrm_uuid;
num_elem++;
result = wiced_bt_ble_set_raw_advertisement_data(num_elem, adv_elem);
return result;
}
5.2.4 开始广播
/* TODO - start advertisement */
wiced_bt_start_advertisements(BTM_BLE_ADVERT_UNDIRECTED_HIGH, BLE_ADDR_PUBLIC, NULL);
5.2.5 持续广播
设置为持续广播:因为广播模式是BTM_BLE_ADVERT_UNDIRECTED_HIGH,将high_duty_duration赋值为0.
5.2.6 注册 app_gatt_callback
这部分代码在空工程建立的时候默认是有的,现在只需将注释去掉。
/* TODO - register for GATT callbacks if needed by your application */
gatt_status = wiced_bt_gatt_register(app_gatt_callback);
5.2.7 gatt_database 初始化
这部分代码在空工程建立的时候默认是有的,现在只需将注释去掉。
/* TODO - initialize GATT database created by Bluetooth Configurator here if needed by your application */
gatt_status = wiced_bt_gatt_db_init(gatt_database, gatt_database_len);
5.2.8 导入蓝牙SDK包
因为涉及到蓝牙,所以需要SDK支持。
6. 编译下载看现象
下载进去后,可以用 nRF Connect 扫描到它的存在,确实是心率带设备:
7. 写在最后
本文主要关注工程的建立,以及对硬件资源和蓝牙的配置。