智能手表:电源检查

发布于:2025-08-04 ⋅ 阅读:(8) ⋅ 点赞:(0)

本文分享一个嵌入式设备中常用的电池状态监测函数,通过AD采样获取电池电压,经滤波和计算后得到电量百分比,并在OLED屏幕上动态显示电量图标及百分比数值。适用于STM32等单片机的电池管理模块,代码可直接移植使用。

AD 采样→电压计算→容量转换→OLED 显示

  • 开机时:PB12 是低电平、PB13 是高电平 → 触发 “AD 采样→电量显示” 流程,设备正常检测、显示电池电量;
  • 关机时:PB12 变为高电平、PB13 变为低电平 → 关闭 “AD 采样→电量显示” 流程,设备不再检测电量,降低功耗;
  • 上电初始化:刚通电时,PB12 初始化为低电平、PB13 初始化为高电平 → 直接进入 “开机” 模式,确保电量检测能工作。
  1. 通过AD读取电压值,转化为电压

AD 12 位(最大 4095),参考电压 3.3V,且无分压电路
实际电压 = (ADValue / 4095.0) × 3.3

2,由于电压值不稳定,设计进行滤波

循环多次(如 3000 次)调用AD_GetValue(),累加采样值后取平均值。

3,动态显示

计算电池的百分比

Battery_Capacity=(ADValue-3276)*100/819;

(ADValue - 3276):计算当前 AD 值与最低电压 AD 值的差值,代表当前电压在有效范围内的偏移量

除以819:将偏移量归一化到 0-1 的范围,得到相对满电的比例

乘以100:转换为百分比形式

当 ADValue=3276 时,计算结果为 0%(电池放空)

当 ADValue=3276+819=4095 时,计算结果为 100%(电池满电)

4. OLED 显示逻辑设计

  • 显示内容:电量百分比(数字 +%)、动态电池图标。
  • 分情况处理
    1. 电量 100%:显示完整电池图标,直接输出 “100%”。
    2. 电量 10%~99%:显示基础图标,按比例清除部分区域(模拟电量条),如 50% 时清除一半区域。
    3. 电量<10%:显示基础图标,清除大部分区域(突出低电量),调整数字显示位置避免残留。
uint16_t ADValue; //AD采样原始数据
float VBAT;				//计算后的电池电压
int Battery_Capacity;	//电池容量百分比(0-100%)


void Show_Battery(void)
{
	int sum=0;	
	//AD采样滤波(3000次采样平均,减少噪声)
	for(int i=0;i<3000;i++)
	{
		ADValue=AD_GetValue(); //得到AD值
		sum+=ADValue;
		
	}
	ADValue=sum/3000; //平均滤波后的AD值
	
	//计算电池的电压
	VBAT=(float)ADValue/4095*3.3;
	
	//计算电量百分比(线性转换)
	Battery_Capacity=(ADValue-3276)*100/819;
	if(Battery_Capacity<0)Battery_Capacity=0;
	
	//OLED_ShowNum(64,0,ADValue,4,OLED_6X8);
	//OLED_Printf(64,8,OLED_6X8,"VBAT:%.2f",VBAT);
	OLED_ShowNum(85,4,Battery_Capacity,3,OLED_6X8);
	OLED_ShowChar(103,4,'%',OLED_6X8);
	//根据电池的动态显示电池的图标
	if(Battery_Capacity==100)OLED_ShowImage(110,0,16,16,Battery);
	else if(Battery_Capacity>=10&&Battery_Capacity<100)
	{
		OLED_ShowImage(110,0,16,16,Battery);
		OLED_ClearArea((112+Battery_Capacity/10),5,(10-Battery_Capacity/10),6);
		OLED_ClearArea(85,4,6,8);
	}
	
	else
	{
		OLED_ShowImage(110,0,16,16,Battery);
		OLED_ClearArea(112,5,10,6);
		OLED_ClearArea(85,4,12,8);
	}
}

void Show_Clock_UI(void)
{
	MyRTC_ReadTime();
	OLED_Printf(0,0,OLED_6X8,"%d-%d-%d",MyRTC_Time[0],MyRTC_Time[1],MyRTC_Time[2]);
	OLED_Printf(16,16,OLED_12X24,"%02d:%02d:%02d",MyRTC_Time[3],MyRTC_Time[4],MyRTC_Time[5]);
	OLED_ShowString(0,48,"菜单",OLED_8X16);
	OLED_ShowString(96,48,"设置",OLED_8X16);
	
	Show_Battery();
}


网站公告

今日签到

点亮在社区的每一天
去签到