

//// Battery attribute valuesstatic const u8 my_batCharVal[5] = {CHAR_PROP_READ | CHAR_PROP_NOTIFY | CHAR_PROP_INDICATE,U16_LO(BATT_LEVEL_INPUT_DP_H), U16_HI(BATT_LEVEL_INPUT_DP_H),U16_LO(CHARACTERISTIC_UUID_BATTERY_LEVEL), U16_HI(CHARACTERISTIC_UUID_BATTERY_LEVEL)};

voidsend_battery_value_to_app(){static unsigned int clock_cnt = 0;static unsigned char value = 0;if(clock_time_exceed(clock_cnt, 1000000)){clock_cnt = clock_time();value++;// blc_gatt_pushHandleValueNotify (BLS_CONN_HANDLE, BATT_LEVEL_INPUT_DP_H, (u8 *)&value, 1);blc_gatt_pushHandleValueIndicate(BLS_CONN_HANDLE, BATT_LEVEL_INPUT_DP_H, (u8 *)&value, 1);}}
blc_gatt_pushHandleValueIndicate为发送指示的api,将value的值发送给主机app
备注:send_battery_value_to_app()函数需要放入主函数里面,不然无法发出数据
/*** @brief This function is used to indicate the Characteristic Value from a server to a client.* @param[in] connHandle - connection handle* @param[in] attHandle - attribute handle.* @param[in] p - data buffer pointer* @param[in] len - data byte number* @return Status - 0x00: command succeeded; 0x01-0xFF: command failed*/ble_sts_t blc_gatt_pushHandleValueIndicate(u16 connHandle, u16 attHandle, u8 *p, int len);
connHandle:连接句柄,如下说明
/*** @brief LE connection handle for slave & master role* Telink single connection SDK support only one ACL Slave or only one Master connection,* We use constant connection handle value for them in controller to simplify design and development,* so user can use these two connection handle directly.* attention: If using Telink multiple connection SDK, connection handle must be managed dynamically !!!*/#define BLM_CONN_HANDLE 0x0080 //ACL Master connection handle#define BLS_CONN_HANDLE 0x0040 //ACL Slave connection handle
attHandle:属性句柄,我们这里要填写的是my_batVal属性的句柄,如何查找my_batVal的句柄,请看4小节
p:数据指针,也就是我们需要传入数据的指针
len:数据的长度
4、my_batVal的句柄

如上图所示,我们需要知道红框里面的句柄值,通过查看该特征属性值的特征声明就可以知道红框里面的句柄为多少,那么特征属性值的特征声明在哪里呢,如下图所示


由上图可以看到句柄值为BATT_LEVEL_INPUT_DP_H,如果对这个数组的结构定义有疑问的话,请看我的这篇文章手把手教你:BLE特征声明与特征值代码抓包全解析
备注:该特征的值支持读和通知,读的意思是允许主机读取我的数值,通知的意思是我可以通过通知的方式将数据发送给主机,不需要主机的回复,参见第2小节,我使用的是通知。




#if (UART_PRINT_DEBUG_ENABLE)#define DEBUG_INFO_TX_PIN GPIO_PB2#define PULL_WAKEUP_SRC_PB2 PM_PIN_PULLUP_10K#define PB2_OUTPUT_ENABLE 1#define PB2_DATA_OUT 1#endif

unsigned char rec_confirm_inf_cnt = 0;voidsend_battery_value_to_app(){static unsigned int clock_cnt = 0;static unsigned char value = 0;if(clock_time_exceed(clock_cnt, 1000000)){clock_cnt = clock_time();if(blc_ll_getCurrentState() == BLS_LINK_STATE_CONN){printf("send cnt = %d,rec cnt = %d\n",value,rec_confirm_inf_cnt);value++;blc_gatt_pushHandleValueIndicate(BLS_CONN_HANDLE, BATT_LEVEL_INPUT_DP_H, (u8 *)&value, 1);}}}
blc_ll_getCurrentState(),当前状态的判断,如下是该函数的解释,总共有5种状态,这里的函数判断的是,当前是否在连接状态
/*** @brief this function is used to get LE stack current state* @param[in] none.* @return BLE link layer state:* BLS_LINK_STATE_IDLE* BLS_LINK_STATE_ADV* BLS_LINK_STATE_SCAN* BLS_LINK_STATE_INIT* BLS_LINK_STATE_CONN*/u8 blc_ll_getCurrentState(void);
printf:打印函数,用于打印发送和接收的次数
6.3、串口日志截图

由上图可以看出,接收和发送的次数错位了,也就是丢了一包,下一篇将结合对丢包的情况进行分析
7、手机上使用nRF Connect工具进行查看BLE发送过来的数据信息
7.1、查找vSample广播包,并点击CONNECT

7.2、查看服务列表,点开Battery Service,查看Battery Level的值

8、使用开发板实物图片介绍

上面三根线是下载端口,下面的一根线是串口打印端口