801138631e
还存在一点点bug,不难fix 2. 增加了中文字库,支持中文显示 3. 修复和优化了一些地方
160 lines
5.8 KiB
C
160 lines
5.8 KiB
C
#include "BAT_Driver.h"
|
||
|
||
const static char *ADC_TAG = "ADC";
|
||
|
||
float BAT_analogVolts = 0;
|
||
|
||
/*---------------------------------------------------------------
|
||
ADC Calibration
|
||
---------------------------------------------------------------*/
|
||
static bool example_adc_calibration_init(adc_unit_t unit, adc_channel_t channel, adc_atten_t atten, adc_cali_handle_t *out_handle)
|
||
{
|
||
adc_cali_handle_t handle = NULL;
|
||
esp_err_t ret = ESP_FAIL;
|
||
bool calibrated = false;
|
||
|
||
#if ADC_CALI_SCHEME_CURVE_FITTING_SUPPORTED
|
||
if (!calibrated) {
|
||
ESP_LOGI(ADC_TAG, "calibration scheme version is %s", "Curve Fitting");
|
||
adc_cali_curve_fitting_config_t cali_config = {
|
||
.unit_id = unit,
|
||
.chan = channel,
|
||
.atten = atten,
|
||
.bitwidth = ADC_BITWIDTH_DEFAULT,
|
||
};
|
||
ret = adc_cali_create_scheme_curve_fitting(&cali_config, &handle);
|
||
if (ret == ESP_OK) {
|
||
calibrated = true;
|
||
}
|
||
}
|
||
#endif
|
||
|
||
#if ADC_CALI_SCHEME_LINE_FITTING_SUPPORTED
|
||
if (!calibrated) {
|
||
ESP_LOGI(ADC_TAG, "calibration scheme version is %s", "Line Fitting");
|
||
adc_cali_line_fitting_config_t cali_config = {
|
||
.unit_id = unit,
|
||
.atten = atten,
|
||
.bitwidth = ADC_BITWIDTH_DEFAULT,
|
||
};
|
||
ret = adc_cali_create_scheme_line_fitting(&cali_config, &handle);
|
||
if (ret == ESP_OK) {
|
||
calibrated = true;
|
||
}
|
||
}
|
||
#endif
|
||
|
||
*out_handle = handle;
|
||
if (ret == ESP_OK) {
|
||
ESP_LOGI(ADC_TAG, "Calibration Success");
|
||
} else if (ret == ESP_ERR_NOT_SUPPORTED || !calibrated) {
|
||
ESP_LOGW(ADC_TAG, "eFuse not burnt, skip software calibration");
|
||
} else {
|
||
ESP_LOGE(ADC_TAG, "Invalid arg or no memory");
|
||
}
|
||
|
||
return calibrated;
|
||
}
|
||
|
||
// static void example_adc_calibration_deinit(adc_cali_handle_t handle)
|
||
// {
|
||
// #if ADC_CALI_SCHEME_CURVE_FITTING_SUPPORTED
|
||
// ESP_LOGI(ADC_TAG, "deregister %s calibration scheme", "Curve Fitting");
|
||
// ESP_ERROR_CHECK(adc_cali_delete_scheme_curve_fitting(handle));
|
||
|
||
// #elif ADC_CALI_SCHEME_LINE_FITTING_SUPPORTED
|
||
// ESP_LOGI(ADC_TAG, "deregister %s calibration scheme", "Line Fitting");
|
||
// ESP_ERROR_CHECK(adc_cali_delete_scheme_line_fitting(handle));
|
||
// #endif
|
||
// }
|
||
|
||
adc_oneshot_unit_handle_t adc1_handle;
|
||
bool do_calibration1_chan3;
|
||
adc_cali_handle_t adc1_cali_chan3_handle = NULL;
|
||
|
||
int adc_raw[2][10];
|
||
int voltage[2][10];
|
||
void ADC_Init(void)
|
||
{
|
||
//-------------ADC1 Init---------------//
|
||
adc_oneshot_unit_init_cfg_t init_config1 = {
|
||
.unit_id = ADC_UNIT_1,
|
||
};
|
||
ESP_ERROR_CHECK(adc_oneshot_new_unit(&init_config1, &adc1_handle));
|
||
|
||
//-------------ADC1 Config---------------//
|
||
adc_oneshot_chan_cfg_t config = {
|
||
.atten = EXAMPLE_ADC_ATTEN,
|
||
.bitwidth = ADC_BITWIDTH_DEFAULT,
|
||
};
|
||
ESP_ERROR_CHECK(adc_oneshot_config_channel(adc1_handle, EXAMPLE_ADC1_CHAN, &config));
|
||
|
||
//-------------ADC1 Calibration Init---------------//
|
||
do_calibration1_chan3 = example_adc_calibration_init(ADC_UNIT_1, EXAMPLE_ADC1_CHAN, EXAMPLE_ADC_ATTEN, &adc1_cali_chan3_handle);
|
||
|
||
// //Tear Down
|
||
// ESP_ERROR_CHECK(adc_oneshot_del_unit(adc1_handle));
|
||
// if (do_calibration1_chan3) {
|
||
// example_adc_calibration_deinit(adc1_cali_chan3_handle);
|
||
// }
|
||
}
|
||
|
||
void BAT_Init(void)
|
||
{
|
||
ADC_Init();
|
||
}
|
||
float BAT_Get_Volts(void)
|
||
{
|
||
adc_oneshot_read(adc1_handle, EXAMPLE_ADC1_CHAN, &adc_raw[0][0]);
|
||
// printf( "ADC%d Channel[%d] Raw Data: %d\r\n", ADC_UNIT_1 + 1, EXAMPLE_ADC1_CHAN, adc_raw[0][0]);
|
||
if (do_calibration1_chan3) {
|
||
ESP_ERROR_CHECK(adc_cali_raw_to_voltage(adc1_cali_chan3_handle, adc_raw[0][0], &voltage[0][0]));
|
||
// printf("ADC%d Channel[%d] Cali Voltage: %d mV\r\n", ADC_UNIT_1 + 1, EXAMPLE_ADC1_CHAN, voltage[0][0]);
|
||
BAT_analogVolts = (float)(voltage[0][0] * 3.0 / 1000.0) / Measurement_offset;
|
||
// printf("BAT voltage : %.2f V\r\n", BAT_analogVolts);
|
||
}
|
||
return BAT_analogVolts;
|
||
}
|
||
|
||
/**
|
||
* @brief 滞回锁定百分比(±1 % 死区)
|
||
* @param pct:实时算出的 0-100
|
||
* @retval 对外发布的稳定百分比
|
||
*/
|
||
int32_t BAT_Percent_Lock(int32_t pct)
|
||
{
|
||
static int32_t out = 0; // 上次对外值
|
||
if (pct >= out + 1) out = pct; // 上升门槛
|
||
if (pct <= out - 1) out = pct; // 下降门槛
|
||
return out;
|
||
}
|
||
|
||
static float lpf = 0.0f; // 上一次滤波结果
|
||
static bool first = true; // 首次赋值标志
|
||
float BAT_Get_Volts_Filtered(void)
|
||
{
|
||
float raw = BAT_Get_Volts(); // 你的原始函数
|
||
|
||
if (first) { lpf = raw; first = false; } // 第一次直接赋值
|
||
lpf = lpf + 0.05f * (raw - lpf); // α=0.05 越小刚越稳
|
||
return lpf;
|
||
}
|
||
|
||
|
||
|
||
/**
|
||
* @brief 返回电池剩余电量百分比(0~100)
|
||
* @note 基于 200 k + 100 k 分压,ADC 满量程 1.1 V
|
||
* @retval 0 已放空(≤ 3.0 V)
|
||
* 100 满电(≥ 4.2 V) 这里给到4.1V 以放置电池达不到100%的电量
|
||
* 中间线性
|
||
*/
|
||
int32_t BAT_Get_Percent(void)
|
||
{
|
||
const float volts = BAT_Get_Volts_Filtered(); // 3.0 ~ 4.2 V -> 0 ~ 100 做映射
|
||
// 限幅
|
||
if (volts <= 3.0f) return 0;
|
||
if (volts >= 4.1f) return 100;
|
||
// 滞回比较器 + 线性映射
|
||
return BAT_Percent_Lock((int32_t)((volts - 3.0f) / (4.2f - 3.0f) * 100.0f + 0.5f)); // +0.5 四舍五入
|
||
} |