Files
Bionic_sphere/Lib/BAT_Driver/BAT_Driver.c
T
Misaki 801138631e 1. 花了几天时间基于lvgl8.3封装了lvgl_cpp,写了一些基本需要的控件,支持链式调用
还存在一点点bug,不难fix
2. 增加了中文字库,支持中文显示
3. 修复和优化了一些地方
2025-09-27 05:43:43 +08:00

160 lines
5.8 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#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 四舍五入
}