基于蓝牙协议栈的电池电量服务
摘要:在理解协议栈和ADC的基础上,就可以讲讲蓝牙低功耗设备如何添加电池服务(这里的电池指的是:纽扣电池CR2032, 3V ),让蓝牙主机可以知道蓝牙设备的电池电量。可以设置一个电池低电量的临界值,当电池的电量低于这个临界值时,就提醒用户更换电池。为了实现这个功能,需要用到HAL层的halAdc.c与halAdc.h两个文件来配置处理器的ADC模块,然后还需要在此基础上用到电池电量的配置文件:Battservice.c与Battservice.h。通过CC2540 的ADC模块来测量外接电池的电量:VADD5/3作为ADC的采样通道,参考电压选择芯片内部1.25V的参考电压,以10位精度采样,有效位为9位,最大的AD值为511,也就是说1.25V对应的AD值为511。对于纽扣电池3V来说,电池的电压在2V~3V之间可以正常给芯片供电,电池电压与电池电量之间的关系为:
2V <==> 0%
3V <==> 100%
因为选择AVDD5/3通道,正常使用的电池电压输入到ADC上实际上为2/3V~3/3V,即0.66V~1V,计算得到AD值为273~409(0.66/1.25*511 ~ 1/1.25*511)。最后可以得到采样到的AD值与电量的关系:
273 <==> 0%
409 <==> 100%
计算公式:Battery Level = (adc - 273) / (409 - 273) * 100
根据上面的公式,就可以计算得到蓝牙设备的电池电量。
检测到电池电量后,需要通过蓝牙上传。这时则需要向GATT增加电池服务,蓝牙设备会发送电池电量的通告给主机,这样的话蓝牙主机端(如手机等)看到蓝牙设备的电池电量。电池电量的通告只有在下面2种情况下才会发送:1、第一次连接时;2、电池电量较少时。可以设置一个电池电量的临界提醒值,当电池电量达到这个临界值时,就会给蓝牙主机发送通告,提醒用户更换蓝牙设备的电池。
下面就正式开始讲讲蓝牙的电池服务。
1、跟ADC相关的几个变量
(1)电池电压3V对应的AD值BATT_ADC_LEVEL_3V=409
define BATT_ADC_LEVEL_3V 409
(2)电池电压2V对应的AD值BATT_ADC_LEVEL_2V=273
define BATT_ADC_LEVEL_2V 273
(c)最低电量所对应的AD值battMinLevel=273
static uint16 battMinLevel = BATT_ADC_LEVEL_2V;
(d)最高电量所对应的AD值battMaxLevel=409
static uint16 battMaxLevel = BATT_ADC_LEVEL_3V;
(e)电池电量的临界值(提醒换电池的电量)battCriticalLevel
static uint8 battCriticalLevel;
(f)电池电压的AD值采样通道设置成VDD/3通道battServiceAdcCh
static uint8 battServiceAdcCh = HAL_ADC_CHANNEL_VDD;
2、跟ADC采样相关的几个回调函数
(1)AD测量设置回调函数battServiceSetupCB,在AD采样之前调用。
typedef void (*battServiceSetupCB_t)(void);
static battServiceSetupCB_t battServiceSetupCB = NULL;
(2)AD测量结束回调函数battServiceTeardownCB,在AD测量结束时调用。
typedef void (*battServiceTeardownCB_t)(void);
static battServiceTeardownCB_t battServiceTeardownCB = NULL;
(3)AD测量计算回调函数battServiceCalcCB,在AD测量后调用这个函数用来计算电池电量。
typedef uint8 (*battServiceCalcCB_t)(uint16 adcVal);
static battServiceCalcCB_t battServiceCalcCB = NULL;
3、用户自定义的电池服务应用回调函数battServiceCB,在操作电池服务写属性时调