SOC计算部分代码解析

  • 格式:doc
  • 大小:30.50 KB
  • 文档页数:3

static void Soc_CheckRule3(U8 soc){///
#pragma section SOC_FLASH_section end
static U8 rule3Debounce = 3; // over 3 readings
#pragma define_section SOC_FLASH_section "SOC_FLASH" RWX
#pragma section SOC_FLASH_section begin
U16 rule3 = 0;
U16 rule3Threshold = RULE_3_THRESHOLD;
if(coulombSoc > soc){
rule3 = (U16)coulombSoc - soc;
rule3Threshold *= socValue;
rule3Threshold /= 255;
if(rule3 > rule3Threshold){
if(rule3Debounce)
rule3Debounce--;
else
socControl = (U8)(MODE_4 | (socControl & (BATTERY_EMPTY | CAPACITY_LEARNED)));
}
else
rule3Debounce = 3;
}
else
rule3Debounce = 3;
}
这个函数应该是说明rule3下的情况。

如果coulombSoc > (1/2)*soc 那么的话就会跳转到rule4去。

static U8 Soc_GetCoulombSoc(S16 temp){
U32 g1 = 0;
U32 g2 = 0;
U8 soc = 0;
g1 = Soc_LongMath((U32)Soc_GetCapacityTempAdj(temp), capacityValue, (U32)255);
g2 = g1;
if(g2 > ampMinutesDischarged)
g1 = g2 - ampMinutesDischarged;
else
g1 = 0;
g1 = Soc_LongMath(g1, (U32)256, g2);
if(g1){
if(g1 > 254)
g1 = 254; // don't let it be 100%
else
g1--;
}
soc = (U8)g1;
if((socControl & (MODE_2 | RULE_3)) && (soc < (U8)(0.1 * 255)))
soc = (U8)(0.1 * 255);
return soc;
}
计算库仑电荷量。

办法是通过温度获取当前的系统应该的总电量,然后和给定的温度的比值,这样就得到了电荷量的归一化,因为ampMinutesDischarged也是按照255的份额计算的。

然后计算出现在还剩下的电量,最后剩下电量与总电量比值乘以255即可。

coulomSoc = 255*(1 – (ampMinutesDischarged * 255)/f(temperature) * capacityValue)
Soc_UpdateSoc
if(socControl & (MODE_2 | RULE_3)){
if(socValue < 128){
i1 = (U16)(coulombSoc * 2);
if(c1 > i1) // Rule 4
c1 = (U8)i1;
i1 = (U16)(socValue * 2);
i1 *= coulombSoc;
i1 /= 255;
c2 = (U8)i1;
i1 = (U16)(socValue * 2);
i1 = 255 - i1;
i1 *= c1;
i1 /= 255;
c1 = (U8)(i1 + c2);
}
else
c1 = coulombSoc; // Mode 1
最后的C1 =
SocValue<128:
V oltprofileSoc + 2*SocValue*(CoulombSoc - VoltprofileSoc)/255
SocValue>128:
coulombSoc
意思应该是在<50%电量的时候,利用了一个库仑和电压、电流、温度计算的SOC之间的差值获得一个校正。

当>128的时候,则直接使用温度获取的库仑值作为SOC。

这些计算都只是知道了当前是在放电状态下,SOC的基本流向。

void Soc_CountmAh(S32 current){
#pragma section SOC_FLASH_section end
static S32 ampHalfSecondCounter = 0;
#pragma define_section SOC_FLASH_section "SOC_FLASH" RWX
#pragma section SOC_FLASH_section begin
S16 adjustment;
S32 present;
ampHalfSecondCounter += current;
present = (S32)ampMinutesDischarged;
if(ampHalfSecondCounter > (COULOMB_FREQ * 60)){///discharge
adjustment = (S16)(ampHalfSecondCounter / (COULOMB_FREQ * 60));
if((present + adjustment) < 0xffff) //INT_MAX
present += adjustment;
ampHalfSecondCounter %= (COULOMB_FREQ * 60);
}
else if(ampHalfSecondCounter <= -(COULOMB_FREQ * 60)){//charge
adjustment = (S16)(-(ampHalfSecondCounter) / (COULOMB_FREQ * 60));
if((present - adjustment) > 0)
present -= adjustment;
ampHalfSecondCounter %= (COULOMB_FREQ * 60); // bug? - reverify this works }
ampMinutesDischarged = (U32)present;
}
这个函数实现充电和放电的消耗电流SOC计算。

库仑法。