ZDBMS/code_drv/Balance.c

254 lines
7.3 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/********************************************************************************
Copyright (C), Sinowealth Electronic. Ltd.
Author: Sino
Version: V0.0
Date: 2020/04/26
History:
V2.0 2020/04/26 Preliminary
********************************************************************************/
#include "Main.h"
BOOL bBalanceFlg;
BOOL bBalancingFlg;
BOOL bBalanceOddFlg;
BOOL bCTOValidFlg; //当电芯压差超过1200mV时才认为存在断线主要解决电芯电压低于2V情况下
BOOL bCellOpenDecFlag;
U16 xdata uiBalanceChannel;
U8 xdata ucBalanceTimeCnt;
U8 xdata ucBalanceStep;
U8 xdata ucCellOpenDecCnt;
U8 xdata ucCtoCnt;
/*************************************************************************************************
* 函数名: BalTurnOnCheck
* 参 数: 无
* 返回值: 无
* 描 述:
1. 平衡开启条件是电压、压差及电流 同时满足
2. 平衡过程中,不再进行平衡检测
3. 断线检测借用平衡
*************************************************************************************************/
void BalTurnOnCheck(void)
{
U8 i;
if(!bBalancingFlg && !bCellOpenDecFlag) //在一个平衡周期中或开启断线检测时不判定是否进行平衡
{
if(bBAL_EN)
{
uiBalanceChannel = 0;
if(((uiCellVmax>E2uiOVvol)&&(!bOV)) //发生温度保护时不进行平衡,判定进入过压、过压恢复、进入充电截止时暂停平衡
||((uiCellVmax < E2uiOVRvol)&&(bOV))
|| bOTC || bUTC || bOTD || bUTD)
{
bBalanceFlg = 0;
ucBalanceTimeCnt = 0;
}
else
{
if(((uiCellVmax>E2uiBalanceVol) && (uiCellVmax-uiCellVmin)>=E2uiBalanceVolDiff) && (Info.slCurr>=E2siBalCurrent))
{
if(!bBalanceFlg)
{
ucBalanceTimeCnt++;
}
if(ucBalanceTimeCnt >= BAL_DELAY_CNT)
{
for(i=ucCellNumOffset; i<ucCellNumOffset+ucCellNum; i++)
{
if(((Info.uiVCell[i]-uiCellVmin)>=E2uiBalanceVolDiff)&&(Info.uiVCell[i]>=E2uiBalanceVol)) //电芯电压大于平衡电压,且压差大于阈值,开启该电芯平衡
{
uiBalanceChannel |= (1<<i);
}
}
bBalanceFlg = 1;
}
}
else
{
bBalanceFlg = 0;
ucBalanceTimeCnt = 0;
}
}
}
}
}
/*******************************************************************************
Function: CTOCheckVol(void)
Description:
Input:
Output:
Others:
*******************************************************************************/
BOOL CTOCheckVol(void)
{
BOOL bResult=0;
if(bCTO_EN) //判断是否支持断线检测
{
if(!bCTO) //如果已经检测到断线,则不再检测
{
if(bCTOValidFlg) //判断电压压差是否超过1.2V
{
if(uiVadcVmin < VOL_CELL_CUT_180MV) //180mV
{
bResult = 1;
if(++ucCtoCnt >= TIME_50MS_500MS) //断线 500mS
{
bCTO = 1;
}
}
else
{
bCTOValidFlg = 0;
ucCtoCnt = 0;
}
}
}
#ifdef SP_CTO_RECOVER
else //断线恢复功能每250mS一个周期判断最小电压
{
if(uiVadcVmin >= VOL_CELL_CUT_180MV) //180mV
{
if(++ucCtoRCnt >= TIME_250MS_1S)
{
bCTO = 0;
}
}
else
{
ucCtoRCnt = 0;
}
}
#endif
}
return bResult;
}
/*************************************************************************************************
* 函数名: BalProcess
* 参 数: 无
* 返回值: 无
* 描 述:
1. 平衡周期分为5个STEP合计250mS
2. 平衡效率<100/(250mS*2)(采用奇偶平衡)
3. 如果检测到断线,则持续开启平衡进行断线检测
4. 平衡开启后正常的电压保护判断延时可能会多延时250mS(一个平衡周期)
*************************************************************************************************/
void BalProcess(void)
{
U16 BalChTemp;
//判断电芯电压压差是否超过1.2V,如果超过则允许判断断线,主要解决电芯电压<2V情况下平衡会触发断线判断条件
//判断电芯最大电压是否小于1.38V,如果小于则允许判断断线,主要解决未有效检测电芯电压的情况下压差不满足断线判断条件
if((uiCellVmax-uiCellVmin>=VOL_CELL_CUT_1200MV) || (uiCellVmax<=VOL_CELL_CUT_1380MV))
{
bCTOValidFlg = 1;
}
switch(ucBalanceStep)
{
case BALANCE_ENABLE: //VADC采集的数据用于正常电压判断
if(bCellOpenDecFlag || bBalanceFlg)
{
if(bBalanceOddFlg) //odd balance
{
BalChTemp = uiBalanceChannel&0x5555;
}
else //even balance
{
BalChTemp = uiBalanceChannel&0xAAAA;
}
AfeBalCtl(BalChTemp); //开启平衡
ucBalanceStep = BALANCE_START;
bBalancingFlg = 1;
}
break;
case BALANCE_START: //VADC采集的电压数据丢掉
ucBalanceStep = BALANCING;
break;
case BALANCING: //VADC采集的电压数据判断断线
if(!CTOCheckVol()) //如果发现有断线则连续检测断线
{
AfeBalCtl(0); //关闭平衡
ucBalanceStep = BALANCE_DISABLE;
bBalanceOddFlg = ~bBalanceOddFlg;
}
break;
case BALANCE_DISABLE: //VADC采集的电压数据丢掉
if(!CTOCheckVol()) //如果发现有断线则连续检测断线
{
ucBalanceStep = BALANCE_NULL;
}
else
{
ucBalanceStep = BALANCE_ENABLE;
bBalanceOddFlg = ~bBalanceOddFlg;
}
break;
case BALANCE_NULL: //VADC采集的数据用于正常电压判断
ucBalanceStep = BALANCE_ENABLE;
bCellOpenDecFlag = 0;
bBalanceFlg = 0;
bBalancingFlg = 0;
break;
}
}
/*************************************************************************************************
* 函数名: CellOpenProcess
* 参 数: 无
* 返回值: 无
* 描 述: 每2S开启一次断线检测
*************************************************************************************************/
void CTOTurnOnCheck(void)
{
#ifdef SP_CTO_RECOVER
if(bCTO_EN) //支持断线恢复
#else
if(bCTO_EN && !bCTO) //如果已发生断线则不检测
#endif
{
if(++ucCellOpenDecCnt >= TIME_50MS_2250MS) //2S
{
ucCellOpenDecCnt = TIME_50MS_2250MS; //避免该检测周期是平衡的偶数倍关系
if(!bBalancingFlg) //如果正在平衡,则等一个平衡周期结束后再开启断线检测
{
ucCellOpenDecCnt = 0;
bCellOpenDecFlag = 1;
uiBalanceChannel = 0x03ff;
}
}
}
}
/*************************************************************************************************
* 函数名: BalanceProcess
* 参 数: 无
* 返回值: 无
* 描 述: 平衡与断线检测处理
*************************************************************************************************/
void BalanceProcess(void)
{
BalTurnOnCheck(); //检测是否满足平衡开启条件
CTOTurnOnCheck(); //定时开启断线检测
BalProcess(); //处理平衡和断线时序
}