当前位置: 首页 > news >正文

ADC电压检测实现电池电量百分比显示

目录

1、使用一阶滞后滤波

2、查表 + 分段判断

3、结构体数组 + 插值法

4、迟滞机制(电量一直在跳是噪声干扰或负载波动导致电压抖动)

5、低功耗采样建议

6、升级

7、电压型迟滞回差(Hysteresis)电量判断(四格电量显示)

核心参数

代码示例


1、使用一阶滞后滤波

#define ALPHA 0.2f static float filtered_voltage = 0.0f; filtered_voltage = ALPHA * raw_voltage + (1.0f - ALPHA) * filtered_voltage;

2、查表 + 分段判断

uint8_t Calculate_Battery_Level(float voltage) { if (voltage >= 4.15f) return 100; if (voltage >= 4.00f) return 90; if (voltage >= 3.90f) return 80; if (voltage >= 3.80f) return 70; if (voltage >= 3.70f) return 60; if (voltage >= 3.60f) return 50; if (voltage >= 3.50f) return 40; if (voltage >= 3.45f) return 30; if (voltage >= 3.40f) return 20; if (voltage >= 3.35f) return 10; if (voltage >= 3.30f) return 5; return 0; }

3、结构体数组 + 插值法

typedef struct { float voltage; uint8_t level; } soc_point_t; const soc_point_t battery_curve[] = { {4.20f, 100}, {3.90f, 80}, {3.70f, 50}, {3.50f, 20}, {3.30f, 0} }; #define CURVE_SIZE (sizeof(battery_curve)/sizeof(battery_curve[0])) uint8_t interpolate_soc(float voltage) { if (voltage >= battery_curve[0].voltage) return 100; if (voltage <= battery_curve[CURVE_SIZE-1].voltage) return 0; for (int i = 0; i < CURVE_SIZE - 1; i++) { if (voltage > battery_curve[i+1].voltage) { float ratio = (voltage - battery_curve[i+1].voltage) / (battery_curve[i].voltage - battery_curve[i+1].voltage); return battery_curve[i+1].level + (uint8_t)(ratio * (battery_curve[i].level - battery_curve[i+1].level)); } } return 0; }

4、迟滞机制(电量一直在跳是噪声干扰或负载波动导致电压抖动

#define BATT_HYSTERESIS 2 // ±2%以内不更新 if (abs(new_level - displayed_level) >= BATT_HYSTERESIS) { Update_Display(new_level); displayed_level = new_level; }

5、低功耗采样建议

  • 用定时器触发ADC,避免CPU轮询
  • 平时关闭ADC时钟,采样时再开启
  • 在Stop Mode下通过RTC唤醒,完成一次采样后继续睡眠、

6、升级

  • 加NTC测温,做温度补偿
  • 接入充电管理芯片的状态中断
  • 实现简易库仑积分(用电流×时间估算耗电)
  • 结合蓝牙上报历史电量曲线,做健康度分析

7、电压型迟滞回差(Hysteresis)电量判断(四格电量显示)

简单一句话:升档用高电压门槛,降档用更低的电压门槛,防止电压在临界点小幅抖动时电量格来回闪

核心参数

#define BATT_HYSTERESIS_MV 30U //回差30mV

代码示例

/** * @brief 根据毫伏值获取电池格数 (0-4格),增加全域迟滞回差 H=20mV * @param voltage_mv 滤波之后毫伏值 (3000-4200mV) */ uint16_t textVbat = 0; #define BATT_HYSTERESIS_MV 20U //回差 uint8_t Get_Battery_Levels(uint16_t voltage_mv) { // static保存上一次输出电量等级,实现迟滞回差 static uint8_t last_level = 0; const float K = (47.0f + 24.0f) / 24.0f; //电阻分压比 uint16_t real_vbat = (uint16_t)(voltage_mv * K + 0.5f); textVbat = real_vbat; //升格阈值 const uint16_t LVL4_UP = 3950; const uint16_t LVL3_UP = 3700U; const uint16_t LVL2_UP = 3450U; const uint16_t LVL1_UP = 3200U; //降格阈值 = 升格阈值 - 回差 const uint16_t LVL4_DOWN = LVL4_UP - BATT_HYSTERESIS_MV; const uint16_t LVL3_DOWN = LVL3_UP - BATT_HYSTERESIS_MV;//3700U-20=3780U const uint16_t LVL2_DOWN = LVL2_UP - BATT_HYSTERESIS_MV; const uint16_t LVL1_DOWN = LVL1_UP - BATT_HYSTERESIS_MV; //先计算候选档位(原始阈值) uint8_t candidate; if(real_vbat >= LVL4_UP) candidate = 4; else if(real_vbat >= LVL3_UP) candidate = 3; else if(real_vbat >= LVL2_UP) candidate = 2; else if(real_vbat >= LVL1_UP) candidate = 1; else candidate = 0; uint8_t new_level = last_level; //迟滞回差状态机 switch(last_level) { case 4: //4格往下掉,必须小于LVL4_DOWN才允许降级 if(real_vbat < LVL4_DOWN) { new_level = candidate; } break; case 3: //可以升4格;或者电压足够低才降级 if(real_vbat >= LVL4_UP) { new_level = 4; } else if(real_vbat < LVL3_DOWN) { new_level = candidate; } break; case 2: if(real_vbat >= LVL3_UP) { new_level = 3; } else if(real_vbat < LVL2_DOWN) { new_level = candidate; } break; case 1: if(real_vbat >= LVL2_UP) { new_level = 2; } else if(real_vbat < LVL1_DOWN) { new_level = candidate; } break; case 0: if(real_vbat >= LVL1_UP) { new_level = 1; } break; default: new_level = candidate; break; } last_level = new_level; return last_level; }
http://www.jsqmd.com/news/1352330/

相关文章:

  • 奥系论战:终极捷德单挑六强联军的战力推演与设定分析
  • 千亿参数大模型Kimi-K3实测:从部署到性能的深度评测与工程实践
  • AI降重工具测评与学术论文优化指南
  • 筑宅安房屋修缮|日照防水补漏专业公司,解决雨季房屋渗水漏水 - 筑宅安
  • 2026宁波房屋漏水维修哪家靠谱 亲测三家正规公司避坑指南 - 吉林同城获客
  • 2026年广德迎春街正宗土菜炖锅店推荐 - 谁都没有我好看
  • 2026滁州/六安高考没过线?告别校外机构,正规高校复读班来了!怎么报名?联系方式多少? - 最新资讯
  • Python Selenium自动化登录实战:从环境配置到健壮脚本开发
  • 5分钟掌握Translumo:Windows终极实时屏幕翻译工具完全指南
  • AI智能体开发实战:平衡判断力与创造力的技术架构与实现
  • 游戏主题歌战略价值解析:从入野自由案例看二次元游戏宣发逻辑
  • Java字符串规范化实战:解决编码、全角与Unicode等价性问题
  • 3个步骤搞定Windows原生读写Btrfs文件系统:跨平台数据访问终极指南
  • Python构建API请求频率监控系统:从日志分析到异常告警
  • Vue3+SpringBoot全栈电商平台开发实战
  • JPEXS Free Flash Decompiler:拯救Flash数字资产的3步解决方案
  • 计算机毕业设计之房屋租赁系统的设计与实现
  • 从零配置Codex:连接DeepSeek API与Ollama本地模型的AI编程助手实战
  • 跨浏览器书签同步工具:本地化数据迁移与备份实践指南
  • NetX Duo的内部IP线程与定时器机制
  • 武威文武学校口碑参考:2026年全国连锁品牌合作校区招生推荐 - 圣龙武术朱老师
  • 2026嘉兴房屋漏水维修哪家靠谱 亲测三家正规公司避坑指南 - 吉林同城获客
  • 巴蒂木是防腐木吗?2026年特性与采购解析 - 万相科技
  • 在Yank Note中集成AI:打造高效Markdown写作工作流
  • 终极指南:如何用NucleusCoop实现单机分屏多人游戏体验
  • 嵌入式音频开发:I2S、PCM与TDM协议原理、配置与调试全解析
  • DeepSeek API调价应对指南:成本优化与架构解耦策略
  • 专业级AMD Ryzen处理器调试工具SMUDebugTool:3大实战技巧深度解析
  • WaveTools终极指南:3步解锁鸣潮120帧+画质优化的完整教程
  • 医药数据科学核心能力解析与学习路径