STC8H 锂电池电量检测程序
#include "STC8H.h"
#include <stdio.h>
#include <math.h>
// 定义ADC通道(根据实际连接修改)
#define BAT_ADC_CHANNEL 0
// 电池参数
#define FULL_VOLTAGE 4.2f // 满电电压(4.2V)
#define EMPTY_VOLTAGE 3.3f // 空电电压(3.3V)
#define VOLTAGE_DIVIDER_RATIO 2.0f // 分压电阻比例 (R1+R2)/R2
// 电量状态
typedef enum {
BATTERY_EMPTY = 0,
BATTERY_LOW,
BATTERY_MEDIUM,
BATTERY_HIGH,
BATTERY_FULL
} BatteryStatus;
// 全局变量
float battery_voltage = 0.0f;
int battery_percentage = 0;
int is_charging = 0; // 充电状态标志
float last_valid_voltage = 3.7f; // 上次有效电压值
// 初始化ADC
void ADC_Init() {
P1M0 &= ~(1 << BAT_ADC_CHANNEL); // 设置P1.x为高阻输入
P1M1 |= (1 << BAT_ADC_CHANNEL);
ADCCFG = 0x0F; // 设置ADC时钟为系统时钟/2/16
ADC_CONTR = 0x80; // 打开ADC电源
__nop(); __nop(); __nop(); __nop(); // 等待ADC电源稳定
}
// 读取ADC值
unsigned int ADC_Read(unsigned char channel) {
ADC_CONTR = 0x80 | channel; // 选择通道并启动ADC
__nop(); __nop(); __nop(); __nop(); // 等待转换完成
while (!(ADC_CONTR & 0x20)); // 等待ADC完成
ADC_CONTR &= ~0x20; // 清除完成标志
return (ADC_RES << 8) | ADC_RESL; // 返回10位ADC结果
}
// 获取电池电压(带滤波)
float Get_Battery_Voltage() {
unsigned int adc_sum = 0;
float voltage;
int i;
// 多次采样取平均
for (i = 0; i < 16; i++) {
adc_sum += ADC_Read(BAT_ADC_CHANNEL);
// 短延时
for (volatile int j = 0; j < 100; j++);
}
// 计算电压值
voltage = (adc_sum / 16.0f) * (5.0f / 1024.0f) * VOLTAGE_DIVIDER_RATIO;
return voltage;
}
// 更新电池电量百分比
void Update_Battery_Percentage() {
float current_voltage = Get_Battery_Voltage();
// 简单的抗干扰处理:如果变化过大,则认为是干扰
if (fabs(current_voltage - battery_voltage) > 0.5f) {
current_voltage = battery_voltage; // 忽略这次读数
}
// 充电状态下可以更新电压
if (is_charging) {
battery_voltage = current_voltage;
last_valid_voltage = current_voltage;
}
// 非充电状态下,电压只能下降
else {
if (current_voltage < last_valid_voltage) {
battery_voltage = current_voltage;
last_valid_voltage = current_voltage;
}
}
// 计算电量百分比 (线性估算)
if (battery_voltage >= FULL_VOLTAGE) {
battery_percentage = 100;
} else if (battery_voltage <= EMPTY_VOLTAGE) {
battery_percentage = 0;
} else {
battery_percentage = (int)((battery_voltage - EMPTY_VOLTAGE) /
(FULL_VOLTAGE - EMPTY_VOLTAGE) * 100.0f);
battery_percentage = battery_percentage > 100 ? 100 : battery_percentage;
}
}
// 获取电池状态
BatteryStatus Get_Battery_Status() {
if (battery_percentage <= 10) return BATTERY_EMPTY;
if (battery_percentage <= 30) return BATTERY_LOW;
if (battery_percentage <= 70) return BATTERY_MEDIUM;
if (battery_percentage < 100) return BATTERY_HIGH;
return BATTERY_FULL;
}
// 检测充电状态(根据实际硬件连接修改)
void Check_Charging_Status() {
// 这里需要根据实际硬件连接来检测充电状态
// 例如通过检测充电IC的状态引脚或USB连接状态
// 这里只是示例,实际需要修改
is_charging = 0; // 假设默认不在充电
}
void main() {
// 初始化
ADC_Init();
// 初始读取
battery_voltage = Get_Battery_Voltage();
last_valid_voltage = battery_voltage;
Update_Battery_Percentage();
while (1) {
// 检测充电状态
Check_Charging_Status();
// 更新电池信息
Update_Battery_Percentage();
// 这里可以添加显示电量或其他处理
// ...
// 延时一段时间后再次检测
Delay_ms(1000); // 需要实现延时函数
}
}
// 简单的延时函数
void Delay_ms(unsigned int ms) {
unsigned int i, j;
for (i = 0; i < ms; i++) {
for (j = 0; j < 1000; j++) {
__nop();
}
}
}
程序说明
-
ADC初始化:配置ADC通道和参数,用于读取电池电压。
-
电压读取与滤波:
-
采用16次采样取平均的方法减少随机噪声
-
通过分压电阻比例计算实际电池电压
-
-
抗干扰处理:
-
如果当前电压与上次电压差值过大(>0.5V),则认为是干扰,忽略本次读数
-
非充电状态下,电压只能下降不能上升
-
-
电量计算:
-
采用线性估算方法,根据满电和空电电压计算百分比
-
电量百分比限制在0-100%范围内
-
-
充电状态检测:
-
需要根据实际硬件连接实现充电状态检测
-
使用注意事项
-
需要根据实际硬件修改:
-
ADC通道号
-
分压电阻比例(VOLTAGE_DIVIDER_RATIO)
-
充电状态检测逻辑
-
-
可以通过修改FULL_VOLTAGE和EMPTY_VOLTAGE来适应不同的锂电池特性
-
如需更精确的电量检测,可以考虑:
-
使用库仑计芯片
-
实现更复杂的电池放电曲线算法
-
增加温度补偿
-
-
延时函数需要根据实际时钟频率调整
这个程序提供了基本的电池电量检测功能,并确保了在非充电状态下电量只降不升的特性,同时具有一定的抗干扰能力。

浙公网安备 33010602011771号