MTKFuelGauge(电量计)算法分析

3.MT65MT6572/MT6582平台SWFG算法分析

4.误差和消除误差

MTK平台Battery软件架构基本如上图所示。

具体过程:

硬件ADC读取Battery的各路信息:包括温度,电压等。

MTK开发的电量算法分析得到的数据。

Kernel层将电量信息通过写文件节点的方式更新,并通过UEVENT通知上层。

点,获取电量信息。

根据不同的电量读取和计算的策略,第一步的读取和第二步的算法部分会有比较大的差

异,而后面的数据更新和事件通知部分一致性较高。

本篇重点分析MT65MT6572/MT6582平台SWFG算法实现,对比SW_FG和HW_FG在硬件及软件上的部分差异,分析电量误差形成的一些原因和MTK已经采取的消除误差的措施。对于Battery数据更新和充电流程则粗略分析。

充电状态机,battery充电的逻辑,就依赖于这张图,如果是用的externalchargeric,则应当参考该IC的充电逻辑。

linearcharging下cc转cv,是通过ADC读取电压后,软件切换。而使用chargeric则很可能是硬件直接切换。

alps/mediatek/kernel/drivers/power/linear_charging.c

alps/mediatek/kernel/drivers/power/switching_charging.c

除了10s一次的定时器更新,插拔充电器会触发中断,中断处理时同样会更新battery数据。

为了得到较为精确的电量数据,需要改善测量方式和计算方法,并针对已知误差采取优化手段。一下介绍MTK平台下采用的一些电量算法。

AUXADC算法:

事实上,所有算法都要依赖ADC读取电量信息,这边的AUXADC算法指只依赖ADC读值然后查表读取电量的算法。

这种算法只重构了ZCVtable,误差会很大。

库仑积分法:

通过开路电压查表得到初始电量D0,后续电量通过电流积分累积,通用性强,依赖初始电量的精确度。

混合型算法:

SWFG算法HWFG算法。事实上MTK平台项目通常采用的是混合型算法。

SWFG的参考电路:

HWFG的参考电路

相同点:NTC电阻用于测量温度ADC测量各路信号

不同点:HWFG有单独的ADC和20毫欧的电阻作电流的侦测。

HWFG和SWFG最大差异就是电流的获取方式。

混合算法的流程,HWFG通过FGADC读取FG电阻两端电压获得电流,而SWFG则结合库伦算法通过SW方式算得。这部分会详细介绍。

主要分析上图黄色部分

大部分项目都采用混合算法,下面从算法初始化开始介绍下SWFG的算法实现。

battery_meter.c

这个C文件主要负责电池电量算法的实现向上主要承接battery_common.c向下调用battery_meter_hal.c中的接口,以读取电池的各路信号。

=>battery_meter_initial

首先看下调用这个func的timing。

显然在开机初始化阶段,就会进入该函数,且只会运行一次。

针对AUXADCSW_FGHW_FG三种不同的电池算法方案分别初始化,因为MT6582平台采用的SW_FG,所以接下去先主要分析SW_FG的流程。

SW_FG的准备工作分为两步:table_initoam_init

先看table_init

首先要获取当前的温度信息

=>force_get_tbat

ADC读值

这边就是MTK为了结合实际温度获取较为精确的电池信息而采取的线性平均值法。原理是利用预先测得的分布在-1002550摄氏度下的ZCV表,结合真实温度,动态重构一张当前温度下的ZCV表格。

TEMPERATURE对应预留的空ZCV表格,如下

构造新表的函数如下

采用线性平均法填补了有效温度内所有的ZCV对应值但与真实曲线必然存在一定的误差。

=>oam_init

常见的指针函数传参比较有趣vol_bat这个参数下传给底下pmic做count,然后被重新赋值成读取的v_bat值之所以能这样做是因为这两块代码同处在kernel层并地址传参

battery_meter_hal.c虽然顶着hal的名头,其实是驱动程序,工作在内核层,主要实现上表各结构体针对MTK不同种的充电方案读取各项参数,包括v_battemperaturev_i_sense等

这边走pmic

vbat是channel5,要等到adc数据ready才能去读寄存器,看一下pmic的手册

精度15bit的ADC其中14bit用来存储数据1个bit做ready信号,似乎ADC3和我们之前的dwchannelnumber有点对不上?

可以看到dwchannel5最终访问的仍是ADC3,另外可以直接比较下寄存器地址。

和datasheet左上角的寄存器地址一致

最后还要做次数值转换,公式如下:

分辨率计算:测量电压范围/(2^AD位数-1)

另外,对于同为电压值的v_bat和v_i_sense,可能会出现adc量程不够的问题这时候需要通过电阻分压。所以case6和7的r_val_temp为分压比

和前面一样ADC读值但是6320的spec上对于PCHR没有说明从函数定义的名称上看是开路电压但是如何在一个闭路的环境中通过ADC读取ocv,有些不解。查了下读这个值的timing,只有在initsuspend和resume的时候才去获取.猜想一是可能利用linearcharging这种充9停1的方式,在第10s读取电压作为OCV也可能是因为刚开机时电流还不大读到的电压值可用作OCV总之这个值应该是真实的开路电压的一个近似值。

根据电压读表获取电量

可以看到用的是table_init时重构的新表

Ok这边再一次利用线性平均法这一次是针对ADC读到测到的电压线性平均后得到一个较精准的电量

首先判断是否插着充电器,读PMU寄存器实现

为什么需要判断有没有插着充电器呢?

我是这么理解的,之前通过ADC读取了两个电压值其中一个是V_BAT另一个是hw_ocv是在闭路环境下读取的开路电压近似值,如果此时插着充电器,会有充电电流通过这个hw_ocv的值和开路电压的误差会增大,因此需要做进一步的处理。

插入充电器时,电量误差不大于30满电误差不大于10否则hw_ocv无效

Dod是指用电深度,100-dod=电池剩余容量

看一下dod_init的实现

看下这个值是何时被写入的:

电池信息10supdate1次同样UI电量10s存入RTC寄存器一次。

用7个bit存储电量信息。

开机时直接显示关机时保存的电量,会增强用户体验性,但是如果是更换电池或其他情况造成关机电量和开机电量相差过大,显然应该采用开机电量,否则后续电池电量跳变反而会影响用户体验。

Normalboot下忽略||后面的条件主要就是要求没有插入充电器不处于低电量误差不超过40%

经过前面所有的判断最终得到了gFG_capacity这个电量,也就是开机电量因为开机电量在整个电量计算中相当重要并且又要结合用户体验所以之前会有很多的条件分支。

即25度用标准容量其他温度下需要乘上一个比例值。

oam_v_ocv_1和oam_v_ocv_2现在是根据dod_init的结果取得的大部分情况下就是关机电量查表得到的ocv电压值而注释掉的原方案直接采用hw_ocv的值

这边是算ocv1和ocv2对应的电池内阻r,通过查表的方式获取因为r和v的对应表也是开路条件下测得所以用hw_ocv查表获取的值比原先通过vbat取平均要精准些。

其他一些oam电量算法需要的参数初始化

oam_init后,oam_run这个func负责电量的计算,看一下调用的时机。

=>mt_battery_GetBatteryData

显然也是10s轮询一次,get_percentage这个func多个分支对应不同的电量算法

=>oam_run

先看下MTKSWFG算法的原理图

SWFG的核心在于通过两种方式更新电压,去逼近真实开路电压最终查表获取近似真实的电量值。

ocv1被假定为开路电压ocv2则是闭路电压,以下结合实际代码和上述流程图分析下SW_FG算法流程

D0D1D2D3D4D5代表不同的放电深度.

这个算法的思路是这样的:最终通过开路电压oam_v_ocv_1查ZCV表得到当前的电量值->开路电压需要通过闭路电压v_bat和闭路电流oam_i_2去回溯电池内阻逐次逼近–>oam_i_2通过另一种方式电量积分更新的电压oam_v_ocv_2

总的来说:电压通过两种方式更新电流积分求电量后查表/电池内阻回溯IRdrop求得电池内阻更新方式只有一种根据电压查表.

具体分析部分代码:

闭路电压的更新不需要算法支持直接通过读寄存器实现,注意vol_bat这个参数被复用,下传表平均次数返回时为最终的v_bat电压值

ocv_1和ocv_2分别是两种方式更新的电压这边通过内阻的IRdrop求电流.

上图R可以是电池内阻

关键是oam_i_2这边的I2有几个作用:

<1>因为电流是通过上图的内阻IRdrop得到的,而方式一内阻回溯逼近开路电压本质也是IRdrop,如果使用oam_i_1则没有意义,只能使用不同体系的I2.

<2>方式二电流积分求电量查表同样依赖oam_i_2这个体系是累积积分不需要引用其他体系的参数

<3>I2的方向作为充电还是放电的依据

而oam_i_1只有作用3

oam_car_1/oam_car_2是累积电量显然oam_car_2是算法的有效参数

gFG_BATT_CAPACITY_aging是电池总容量之前分析过了根据开机时读取的电池温度会有所不同

d2为积分法算出的电池当前容量d0为开机电量不会更新d1不重要

内阻回溯IRdrop逼近开路电压,具体分析下:

主要是这个for循环,首先通过v_bat去查表得到电池内阻r然后用另一种算法求得的电流I和内阻r算出内阻分去的电压v,推算ocv_1.

几次循环反复这个过程逼近真实的开路电压。

有几个注意点:

1.

这边的电压单位到底是v还是mv?实际上是0.1mv

2.gFG_resistance_bat和R_FG_VALUE分别是指代电池内阻和硬件FG使用的FG电阻(一般是20毫欧)这边是SW_FG所以后一项为0

3.

因为ret_compensate是int型变量做除法时取整处理会引入较大误差,加上这个值使结果四舍五入

实际做6次内阻回溯,这时的电压值已经和开路电压比较接近,查表得到D3,D3基本就能反映当前电量了。

MTK在D3的问题上针对电量跳变的情况又做了步优化得到D5,看下代码

这部分代码比较简单,1分钟内电量值不会改变,且每分钟电量的变化不会大于1%,这样用户体验会比较好。防止因为低电压时陡峭的电量曲线,以及比较耗电的应用,或突然的大电流引起的电量跳变。当然特殊应用下应该取消这个功能,否则会带来电量变化延时等问题。

这边的返回值将填充BMT_status.SOC,这个参数再经过优化得到BMT_status.UI_SOC就是菜单栏看到的电池电量了。

因为电量值本身不容易通过仪器直接测量,只能依赖开路电压与电量的关系即电量曲线或者电流积分公式演算,这样一个过程会有很多产生误差的点,MTK针对其中一些给出了优化方式。

另外由于电池特性有些时候真实的电量数据反而使得用户体验下降,这时候还要针对电量数据做一些特殊处理,以满足用户的预期。

以下是MT6582平台SWFG中部分电量误差产生的原因以及MTK用于消除/减小误差的方法。

库伦积分时的电流:

即使是cc状态,电流也是有波动的,而进入cv状态后,电流的变化会更大。因为这样一个电流变化并无规律,所以不可能导出电流公式用于电量积分。目前代码会把每10s算一次电流作为这10s的平均电流。

这样会形成一个电量累积误差。

电池内阻不稳定造成的误差:

电池的内阻会随温度变化,且幅度很大,而在SWFG的算法中依赖电池内阻计算电流大小,如果使用固定值的电池内阻会严重影响电流的计算。

MTK应对方案:

1.建立zcvtable

MTK的zcvtable,建立了几个特定温度(-10,0,25,50)下的内阻r和开路电压ocv的关系,这样可以根据可量测的电压信号查表推算内阻.

2.线性平均值

MTK在算法初始化时,读取温度信息,通过线性平均重构zcvtable,这样可以覆盖从-10到50的所有温度点。

MT6582平台MTK电量算法只会在初始化的时候去通过读取的温度重构zcvtable,但假设使用者周围的温度在手机使用过程中变化比较大,或者电池本身发热很厉害,电池内阻值有了较大改变,则测出的电量偏差也会比较大。

假设从高温环境到低温环境,根据电池特性,电池内阻会大幅增大,而电池可使用容量将会下降。实际耗流假设变化不大,由于还是用之前的zcv表格,用于计算的内阻比实际内阻小很多,则算出来的电流会偏大。这样显示电量会快速下降。

开机电压的误差:

由于开机过程中,外设逐渐进入工作状态,电流逐渐增大,这时候ADC读到的电压偏差比较大。

MTK方案:89的HWFG会在PMU未开放restb时获取电压取代MT6582的sw读开机ocv的方案

ADC精度问题

这是硬件设施的问题,有一点精度和分辨率是两码事。精度指转换后所得结果相对与实际值的准确度分辨率是指转换器所能分辨的模拟信号的最小变化值。

插拔和重新开机的显示误差

开机过程中有累积误差,开机读取ocv查表同样有误差,这样的结果是用户可能看到开关机的电量出现很大误差。

电池老化的误差

MTK方案:

HWFG可以通过充电到100%的过程重新算得电池最大容量,SWFG则并没有采取这种方案,可能是SWFG的库伦积分误差较大。

100%tracking&0%tracking

充满电和关机实际上有两个判断标准:

软件关机电压:system_off_voltage电量显示0%

截止电流:top_off_current电量显示100%

由于误差这两套标准在实际使用中肯定不一致,MTK通过UI_SOC这个变量对算法得到SOC进行处理。让电量显示follow电压和电流的判断。

UI_SOC如先到0%需要等待电压和电流的判断;

UI_SOC如后到,则需加快步伐每次-1

代码如下:

100%tracking原理和上面的差不多,不一一列举。

充满电后,还回去reset之前FG算法的一些参数比如DODCAR等,启到修正误差的作用。

THE END
1.2024年用C语言求和:1+2+3+……+100C语言2024年用C语言求和:1+2+3+……+100 摘要:#include<stdio.h>(图片来源网络,侵删)main(){int m,sum=0;for(m=1;m<=100;m++){sum+=m;(图片来源网络 #include<stdio.h> (图片来源网络,侵删) main(){ int m,sum=0; for(m=1;m<=100;m++)https://win7sp.com/post/32066.html
2.(完整版)100以内加减法大全打印版.pdf(完整版)100以内加减法大全_打印版.pdf 31页内容提供方:快乐传递FD 大小:794.13 KB 字数:约4.97万字 发布时间:2024-12-13发布于四川 浏览人气:3 下载次数:仅上传者可见 收藏次数:0 需要金币:*** 金币 (10金币=人民币1元)(完整版)100以内加减法大全_打印版.pdf 关闭预览 想预览更多内容,点击https://max.book118.com/html/2024/1212/8034074125007006.shtm
3.用python求出1100之间和的五种方法sum2=0 for i in range(1,101): sum2+=i print(sum2) #方法二 def fsum(n): s=0 for i in range(1,n+1): s+=i print(s) fsum(100def fsum2(n): if n==1: return 1 else: return n+fsum2(n-1) print(fsum2(100)) #方法五 一句代码搞定 print(sum(list(range(1,101)))发https://zhuanlan.zhihu.com/p/475286415
4.Python编程从小白到大牛第3章流程控制在线免费阅读我们再来看一下0~100累加之和的问题,这次用for循环来计算。 例3-7 for循环计算0到100之和 这里使用了range函数,此函数是Python内置的函数,用于生成一系列连续的整数,经常用于for循环中。图3-1解释了for循环的运行机制,可以看到使用for循环遍历range(101)数组的过程中,迭代变量i会先后被赋值为range(101)数组中的https://fanqienovel.com/reader/7110109863295847454
5.1.写出以下式子的算法过程,并画出流程图及相应的C从程序。1)1+1流程图示意图: 开始 | V 设置sum=0 循环: 计算1/i并将结果加到sum上 i++ 直到i=limit返回sum结束 相关问题 设计完整的算法,计算1+1/2+1/3++1/100的值,并画出流程图 设计一个简单的算法来计算1到100之间所有正倒数之和,可以使用累加法,同时利用循环结构避免手动逐项相加。以下是算法步骤: https://wenku.csdn.net/answer/nedxqp5tah
6.设计算法,并用传统流程图和N—S图表示。求1+2+3++100。刷刷题APP(shuashuati.com)是专业的大学生刷题搜题拍题答疑工具,刷刷题提供设计算法,并用传统流程图和N—S图表示。求1+2+3++100。的答案解析,刷刷题为用户提供专业的考试题库练习。一分钟将考试题Word文档/Excel文档/PDF文档转化为在线题库,制作自己的电子错题本,提高https://www.shuashuati.com/ti/d33af262b0c74efbba23134eba810853.html
7.三万字图文详解100多个计算机网络知识点(收藏)DNS 的解析过程如下图: DNS解析流程 假设你要查询www.baidu.com的 IP 地址: 首先会查找浏览器的缓存,看看是否能找到www.baidu.com对应的IP地址,找到就直接返回;否则进行下一步。 将请求发往给本地DNS服务器,如果查找到也直接返回,否则继续进行下一步; https://www.360doc.cn/article/61825250_1061175411.html
8.C语言入门2(02分12秒)程序1 学校将考试成绩分为3档,0-59分为不及格,60-89分为及格,90-100分为优秀。现在请编一程序,由老师输入一个学生成绩,计算机判断这个成绩在哪一档,并在屏幕上显示。 (03分02秒)讲解流程图 (05分28秒)讲解程序 switch语句和break语句 https://developer.aliyun.com/article/1260094
9.1+23+4+56+7+89+10+1112+13+1415+16+1718+19+2021···因此,整个序列可以简化为(1+2-3)+(4+5-6)+(7+8-9)+(10+11-12)+-96+(97+98-99),即3+6+9++96。这是一个等差数列,首项为3,末项为96,项数为32(因为从3到96每隔3递增)。根据等差数列求和公式,S=n(a1+an)/2,其中n为项数,a1为首项,an为末项。将n=32,a1https://zhidao.baidu.com/question/381296562385127284.html
10.基于自适应调整权重和搜索策略的鲸鱼优化算法座头鲸是一类群居动物,由于它们只能捕食成群的小型鱼虾,因此进化出一种独特的觅食方式,即泡泡网觅食方式.根据座头鲸这种独特的狩猎行为,Seyedali等[7]于2016年模拟其群体行为方式,提出了鲸鱼优化算法,该算法主要分为两部分,一部分为泡泡网觅食,另一部分为随机搜索. 1.1 泡泡网觅食 座头鲸觅食行为示意图如图1所https://xuebao.neu.edu.cn/natural/article/html/2020-1-35.htm
11.算法教学设计流程图 【设计思想】 新课标强调要“培养解决问题的能力,倡导运用信息技术进行创新实践”,以前教学中我一直从面到点,先讲算法的定义和特点,再举例,效果不是很好,学生印象不深,往往到学期结束的时候,对算法印象全无。 因此,这次在设计本节内容的时候,在选择实例的时候,我从两点考虑:一是生活化,选择的例子尽可能贴https://www.ruiwen.com/jiaoxuesheji/7729127.html
12.系统设计(八)遵守三个要素回答,包含数据表的设计、api 的设计、算法的设计,最好图文并茂,有数据表、接口定义,流程图等。 如:面试官问你怎样设计一个短网址系统? 1、问面试官:什么场景和条件下使用? 这个系统是在什么地方使用的?比如短网址系统提供给站内各种服务生成短网站 https://www.jianshu.com/p/5e6eea72b554
13.100个相见恨晚的Python库(建议收藏)腾讯云开发者社区caniusepython3:判断是哪个项目妨碍你你移植到 Python 3。 cookiecutter:从 cookiecutters(项目模板)创建moviepy:一个用来进行基于脚本的视频编辑模块,适用于多种格式,包括动图 GIFs。 scikit-video:SciPy 视频Optimus:在使用 PySpark 时,让敏捷数据科学工作流程变得简单。 Colour:大量色彩理论转换和算法的实现。 https://cloud.tencent.com/developer/article/1922636
14.一种基于Pt100的高纯锗探测器保护系统46.请参阅图1所示,本发明提供一种基于pt100的高纯锗探测器保护系统,在核谱科学实验中常用高纯锗探测器测量γ射线,高纯锗探测器1是由一块掺杂的锗晶体(n型或p型)及电子学部件构成。在使用中,锗晶体、前置放大器输入级的场效应管和电荷灵敏级的反馈元件必须放置在液态氮中,温度低于-163℃时才能施加高压,否则巨大http://mip.xjishu.com/zhuanli/27/202211235068.html
15.个人简历模板电子版可填写「精选8篇」5、内外部沟通能有效的发现问题.解决问题.反馈风险,推进工作和业务的流程.提高工作效率. 6、编写功能模块API.详细设计.版本任务及其他相关文档说明。 工作业绩: 1、带领小组成员完成AI直播课从0到1的开发,并荣获2020年度风云项目 时间:201X.6-201X.8 https://www.100chui.com/article/474298.html
16.1加到100java最快51CTO博客已为您找到关于1加到100 java 最快的相关内容,包含IT学习相关文档代码介绍、相关教程视频课程,以及1加到100 java 最快问答内容。更多1加到100 java 最快相关解答可以来51CTO博客参与分享和学习,帮助广大IT技术人实现成长和进步。https://blog.51cto.com/topic/dda9053463d6b26.html
17.高二信息技术《程序设计》教案分析(通用13篇)高二信息技术《程序设计》教案分析 篇1 【教学目标】 1.能力目标 求100以内偶数和的算法设计思想,并将算法的设计思想用流程图表示出来。 2.过程与方法 利用现实生活中不断重复做某件事的例子以及假设围棋挑战赛的过程来梳理学生的思路,让学生学会从此类生活实际中提炼出循环求值的思想方法,即算法思想。 https://www.oh100.com/kaoshi/jiaoan/446599.html
18.RGSM3hmac/README.mdatmaster·rg4sun/RGHMAC 算法流程图 HMAC 算法描述 在HMAC 的定义中用到一个密码散列函数和一个密钥 Key。本作品使用的 SM3 作 为对明文进行分组循环压缩的散列函数,明文分组长度为 64(byte),散列函 数的输出长度为 32(byte)。认证密钥 K 为随机生成。 再定义两个不同的固定字符串 iPad 和 oPad 如下(“i”和“o”表示内部https://github.com/RGNil/RG_SM3hmac/blob/master/README.md