#include "include.h" #if VBAT_DETECT_EN #define VBG_VOLTAGE sys_trim.vbg_volt #define VBAT2_COEF sys_trim.vbat_coef //AT(.com_rodata.bat) //const char bat_str[] = "VBAT: %d.%03dV\n"; AT(.com_text.port.vbat) u16 bsp_vbat_get_voltage(void) { static u16 vbat_bak = 0; u32 vbat2_val, vbat; u32 vbat2 = saradc_get_value10(VBAT2_ADCCH); vbat2_val = vbat2 * VBG_VOLTAGE * adc_cb.vrtc_val / (adc_cb.bg * adc_cb.vrtc_first); vbat = vbat2_val * VBAT2_COEF / 1000; //不同方案可能采用不同 vbat 滤波算法, 在方案对应的plugin.c中处理 plugin_vbat_filter(&vbat); //默认的取平均值算法. adc_cb.vbat_total = adc_cb.vbat_total - adc_cb.vbat_val + vbat; //均值 adc_cb.vbat_val = adc_cb.vbat_total>>5; if(adc_cb.vbat_val > vbat_bak) { vbat = adc_cb.vbat_val - vbat_bak; } else { vbat = vbat_bak - adc_cb.vbat_val; } if (vbat >= 2) { //偏差大于一定值则更新 vbat_bak = adc_cb.vbat_val; // printf(bat_str, adc_cb.vbat_val/1000, adc_cb.vbat_val%1000); } //printf(bat_str, adc_cb.vbat_val/1000, adc_cb.vbat_val%1000); return vbat_bak; } void bsp_vbat_voltage_init(void) { u32 vbat2_val; u32 vbat2 = saradc_get_value10(VBAT2_ADCCH); vbat2_val = vbat2 * VBG_VOLTAGE * adc_cb.vrtc_val / (adc_cb.bg * adc_cb.vrtc_first); adc_cb.vbat_val = vbat2_val * VBAT2_COEF / 1000; adc_cb.vbat_total = adc_cb.vbat_val << 5; sys_cb.vbat = bsp_vbat_get_voltage(); sys_cb.vbat_percent = 0xff; } int bsp_vbat_get_lpwr_status(void) { if (sys_cb.vbat <= LPWR_OFF_VBAT) { if (LPWR_OFF_VBAT) { if (!sys_cb.lpwr_cnt) { sys_cb.lpwr_cnt = 1; } else if (sys_cb.lpwr_cnt >= 10) { return 2; //VBAT低电关机 } } return 0; //VBAT低电不关机 } else { sys_cb.lpwr_cnt = 0; if (sys_cb.vbat < LPWR_WARNING_VBAT) { return 1; //VBAT低电提醒状态 } else { } return 0; } sys_cb.lpwr_cnt = 0; return 0; } void bsp_vbat_lpwr_process(void) { int vbat_sta = bsp_vbat_get_lpwr_status(); if (vbat_sta == 2) { //达到低电关机状态 func_cb.sta = FUNC_PWROFF; //低电,进入关机或省电模式 return; } else if (vbat_sta == 1) { //低电提醒状态 //低电提示音播放 sys_cb.vbat_nor_cnt = 0; if (sys_cb.lpwr_warning_cnt > LPWR_WARNING_PERIOD) { sys_cb.lpwr_warning_cnt = 0; if (sys_cb.lpwr_warning_times) { //低电语音提示次数 sys_cb.lowbat_flag = 1; plugin_lowbat_vol_reduce(); //低电降低音乐音量 if (sys_cb.lpwr_warning_times != 0xff) { sys_cb.lpwr_warning_times--; } } } } else { if ((sys_cb.lowbat_flag) && (sys_cb.vbat > 3800)) { sys_cb.vbat_nor_cnt++; if (sys_cb.vbat_nor_cnt > 40) { sys_cb.lowbat_flag = 0; sys_cb.lpwr_warning_times = LPWR_WARING_TIMES; plugin_lowbat_vol_recover(); //离开低电, 恢复音乐音量 } } } } void bat_percent_update_callback(void) { #if (USE_APP_TYPE == USE_AB_APP) bool charge_now = sys_cb.charge_sta == 1 ? true : false; if(ble_is_connect()) { ble_uplode_battery(sys_cb.vbat_percent, charge_now); } #endif } void bat_percent_update(void) { u8 bat_level = 0; u16 full_vbat = 4150; //满电电压 u16 pwroff_vbat = LPWR_OFF_VBAT; //关机电压 u16 vbat_percent = sys_cb.vbat_percent; //calc bat percent if (sys_cb.vbat > pwroff_vbat) { bat_level = ((sys_cb.vbat - pwroff_vbat) * 100) / (full_vbat - pwroff_vbat); } if (bat_level > 100){ bat_level = 100; } //update check if (sys_cb.vbat_percent == 0xff) { sys_cb.vbat_percent = bat_level; } else { if (sys_cb.charge_sta) { //充电中 if (bat_level > sys_cb.vbat_percent) { sys_cb.vbat_percent = bat_level; } } else { if (bat_level < sys_cb.vbat_percent) { sys_cb.vbat_percent = bat_level; } } } if (sys_cb.vbat_percent != vbat_percent) { bat_percent_update_callback(); } // printf("%d %d\n", full_vbat, bat_level); // printf("bat:%d%% , vbat:%d, %d, %d\n", sys_cb.vbat_percent, sys_cb.vbat, ((sys_cb.vbat - 3400) * 100), (full_vbat - 3400)); } #endif //VBAT_DETECT_EN