TLSR低电检测

低电检测需要使用ADC对电源电压进行测量。
首先是要对ADC模块进行必要的 了解。
初步打算是写一个battery_check.c和battery_check.h,
确保app_config.h文件中的宏BATT_CHECK_ENABLE是打开的,不去做修改
#define BATT_CHECK_ENABLE 1
注意事项:
1.必须使用GPIO输入通道;
可使用的GPIO输入通道为PB0~PB7、PC4、PC5对应的input channel.
使用GPIO input channel对电源电压进行ADC采样,有两种实现方式。
(1)电源连接到GPIO input channel,在硬件电路设计上,将电源直接和GPIO input channel连接,在ADC初始化时,将GPIO设为高阻态,此时GPIO上的电压等于电源电压,直接进行ADC采样即可。
(2)电源不接触GPIO input channel。硬件电路上不需要电源和GPIO input channel连接。需要借助GPIO 的输入高电平来测量。8258内部电路结构设计可以保证GPIO输出高电平的电压值和电源电压值永远相等。
那么GPIO输出的 高电平可以作为电源电压,通过该GPIO input channel 进行ADC采样。
在此可选第二种电源不接触GPIO input channel的方式,选择的GPIO是PB7。
选PB7为GPIO input channel,其作为普通GPIO功能,初始化所有状态使用默认状态即可,不做特殊修改。
#define GPIO_VBAT_DETECT GPIO_PB7
#define PB7_FUNC AS_GPIO
#define PB7INPUT_ENABLE 0
#define ADC_INPUT_PCHN B7P
需要进行ADC采样时,PB7输出高电平:
gpio_set_output_en(GPIO_VBAT_DETECT ,1);
gpio_write(GPIO_VBAT_DETECT ,1);

ADC采样结束后,可以将PB7的输出态关了,也可以不关。

2.只能使用差分模式

3.必须使用Dfifo模式获得ADC采样值
unsigned int adc_sample_and_get_result(void);

低电检测单独使用
1.低电检测初始化
参考adc_vbat_detect_init(void)
{
adc_power_on_sar_adc(0);
//add adc configuration
adc_power_on_sar_adc(1);
}

sar adc power on 与power off之前的配置,user 尽量不要去修改,使用这些默认的设置就行。user如果选择了不同的GPIO input channel,直接修改宏 ADC_INPUT_PCHN的定义就可以。user硬件电路如果采用了电源连接到GPIO_input_channel的设计,需要将GPIO_VBAT_DETECT输出高电平的操作去掉。
adc_vbat_detect_init初始化函数在app_battery_power_check中调用的code为:
if(!adc_hw_initialized){
adc_hw_initialized = 1;
adc_vbat_detect_init();
}
这里使用了一个变量adc_hw_initialized,只有该变量为0时,调用一次初始化,并将其置1;该变量为1时不再初始化。adc_hw_initialized在下面API中也会被操作。
void battery_set_detect_enable (int en)
{
lowBattDet_enable = en;

if(!en){
	adc_hw_initialized = 0;   //need initialized again
}

}
使用了adc_hw_initialized的设计可以实现的功能有:
1.与其他ADC任务切换;
先不考虑sleep mode的影响,只分析低电检测与其他ADC任务的切换。
因为需要考虑低电检测与其他ADC任务的切换使用,可能出现adc_vbat_detect_init被多次执行,所以不能写到user initialization中,必须在main_loop中实现。
第一次执行app_battery_power_check函数时,adc_vbat_detect_init被执行,且后面不会被反复执行。
一旦ADC other task需要执行时,将抢走ADC的使用权,确保ADC other task初始化时必须调用battery_set_detect_enable(0),此时会将adc_hw_initialized清零。
等ADC other task完成后,交出ADC的使用权。app_battery_power_check再次执行,由于adc_hw_initialized值为0,必须再次执行adc_vbat_detect_init,这样就保证了低电检测每次切回来时都会重新初始化。
2.对suspend和deepsleep retention的自适应处理
将sleep mode考虑进来。
adc_hw_initialized这个变量使用必须定义成一个 data段或bss段上的变量,不能定义到retention_data上。定义在data段或bss段可以保证每次deep sleep retention wake_up后在执行software bootloader时这个变量会被重新初始化为0;而sleep wake_up后这个变量可以保持不变。
adc_vbat_detect_init函数里面配置的register的共同特征是:在suspend mode下不掉电,可以保存状态;在deepsleep retention mode下会掉电。
如果MCU进入suspend mode,醒来后再次执行app_battery_power_check时,adc_hw_initialized的值和suspend之前一致,不需要重新执行adc_vbat_detect_init函数。
如果MCU进入deep sleep retention mode,醒来后adc_hw_initialized为0,必须重新执行adc_vbat_detect_init,ADC相关的register状态需要被重新配置。
adc_vbat_detect_init函数中设定的register的状态可以在suspend期间保持不掉电。
参考文档“PM”部分对suspend mode的说明可知,Dfifo相关的寄存器在suspend mode会掉电,所以以下两句

你可能感兴趣的:(嵌入式,物联网)