|
楼主 |
发表于 2010-8-5 16:36:07
|
显示全部楼层
最新改的充电逻辑
volatile INT32U Bat0_Charge_Discharge_Time_Count; // 电池 0 充电时间计数器
volatile INT32U Bat1_Charge_Discharge_Time_Count; // 电池 1 充电时间计数器
FP32 Bat0_Charge_Discharge_Capacity ; // 电池 0 充电或放电容量
FP32 Bat1_Charge_Discharge_Capacity ; // 电池 1 充电或放电容量
INT32U BAT_STD_CHARGE_MAX_TIME;
/*****************************************************************************
电池0 充电状态机 先检测电池是否插入 然后检测电池是否是可充电电池
然后等待用户选择充电模式 或者直接使用默认充电方式进行充电
*****************************************************************************/
void Bat0_State_Machine(INT8U mode)
{
INT8U TempStatus;
static INT8U timecount = 0;
switch(Bat0_StateMachine)
{
case Battery_Wait_For_Remove:
//每隔3S钟才检测一次
if( timecount <30 )
{
timecount++;
break;
}
else timecount = 0;
TempStatus = Bat0_Insert_Test();
if( 0 == TempStatus )
{
Bat0_Status= Battery_No_Battery;
Bat0_StateMachine = Battery_Insert_Test;
DbgPrint(" Battery 0 has been take off ...\r\n");
}
break;
case Battery_Init:
lcd_printf(0,2," Detecting... ");
Bat0_StateMachine = Battery_Insert_Test;
break;
case Battery_Insert_Test:
Led0ChargeStat = AllOff;
//每隔3S钟才检测一次
if( timecount <30 )
{
timecount++;
break;
}
else timecount = 0;
// 检测是否有电池插入状态 返回1 代表有电池被插入
TempStatus = Bat0_Insert_Test();
if( 1 == TempStatus )
{
Bat0_Status= Battery_Ready;
Bat0_StateMachine = Battery_Chargeable_Test;
DbgPrint(" Battery 0 has been inserted ...\r\n");
}
else lcd_printf(0,2," No battery ");
break;
case Battery_Chargeable_Test:
// 检测电池是否是可充电电池, 返回1 代表可充电电池
TempStatus = Bat0_Recharge_Test();
if( 1 == TempStatus )
{
Bat0_Status = Battery_Chargeable;
Bat0_StateMachine = Battery_Charge_Discharge;
DbgPrint(" Battery 0 is rechargeable ...\r\n");
}
else
{
Bat0_Status = Battery_Not_Chargeable;
//返回0 该电池不是可充电电池 拒冲
Bat0_StateMachine = Battery_Wait_For_Remove;
DbgPrint(" Battery 0 refuse charge, wait take off ...\r\n");
}
break;
// 电池处于充电状态 等待用户选择充电方式(有一个默认设置)
case Battery_Charge_Discharge:
Bat0_Charge_Discharge_Choise = mode;
if( Battery_Standard_Charge_Mode == Bat0_Charge_Discharge_Choise )
{
// 标准充电前先放电
DbgPrint(" Battery 0 Standard Discharging ...\r\n");
Bat0_Status = Battery_DisCharge;
Bat0_StateMachine = Battery_Discharging;
Batt_Vol_Accumulate(1);
}
else if( Battery_Fast_Charge_Mode == Bat0_Charge_Discharge_Choise )
{
// 置快速充电为预冲状态
DbgPrint(" Battery 0 Fast Charging ...\r\n");
Bat0_Status = Battery_Fast_Charge;
Bat0_Fast_Charge_StateMachine = Battery_Precharge_Mode;
Bat0_StateMachine = Battery_Fast_Charging;
Batt_Vol_Accumulate(1);
}
else if( Battery_Direct_Charge_Mode == Bat0_Charge_Discharge_Choise)
{
// 直接充电,不对电池放电
DbgPrint(" Battery 0 Direct Charging ...\r\n");
Bat0_Status = Battery_Standard_Charge;
Bat0_StateMachine = Battery_Standard_Charging;
}
Bat0_Charge_Discharge_Time_Count = 0;
Bat0_Charge_Discharge_Capacity = 0;
break;
case Battery_Standard_Charging:
// 标准充电模式
TempStatus = Bat0_StandardCharge();
if(1 == TempStatus)
{
Bat0_Status = Battery_Charge_Over;
Bat0_StateMachine = Battery_Wait_For_Remove;
DbgPrint(" Battery 0 charge full, wait take off ...\r\n");
}
break;
case Battery_Fast_Charging:
//快速充电模式
TempStatus = Bat0_FastCharge();
if(1 == TempStatus)
{
Bat0_Status = Battery_Charge_Over;
Bat0_StateMachine = Battery_Wait_For_Remove;
DbgPrint(" Battery 0 charge full, wait take off ...\r\n");
}
break;
case Battery_Discharging:
TempStatus = Bat0_DisCharge();
if(1 == TempStatus)
{
// 放电结束转到标准充电
Bat0_Status = Battery_Standard_Charge;
Bat0_StateMachine = Battery_Standard_Charging;
Bat0_Charge_Discharge_Capacity = 0;
DbgPrint(" Battery 0 Discharge over, change to standard charging ...\r\n");
}
break;
default:
Led0ChargeStat = AllOff;
break;
}
}
/*****************************************************************************
电池1 充电状态机 先检测电池是否插入 然后检测电池是否是可充电电池
然后等待用户选择充电模式 或者直接使用默认充电方式进行充电
*****************************************************************************/
void Bat1_State_Machine(INT8U mode)
{
INT8U TempStatus;
static INT8U timecount = 0;
switch(Bat1_StateMachine)
{
case Battery_Wait_For_Remove:
//每隔3S钟才检测一次
if( timecount <30 )
{
timecount++;
break;
}
else timecount = 0;
TempStatus = Bat1_Insert_Test();
if( 0 == TempStatus )
{
Bat1_Status= Battery_No_Battery;
Bat1_StateMachine = Battery_Insert_Test;
Bat1_Charge_Discharge_Capacity = 0;
Bat1_Charge_Discharge_Time_Count = 0;
DbgPrint(" Battery 1 has been take off ...\r\n");
}
break;
case Battery_Init:
lcd_printf(0,4," Detecting... ");
Bat1_StateMachine = Battery_Insert_Test;
break;
case Battery_Insert_Test:
Led1ChargeStat = AllOff;
//每隔3S钟才检测一次
if( timecount <30 )
{
timecount++;
break;
}
else timecount = 0;
// 检测是否有电池插入状态 返回1 代表有电池被插入
TempStatus = Bat1_Insert_Test();
if( 1 == TempStatus )
{
Bat1_Status= Battery_Ready;
Bat1_StateMachine = Battery_Chargeable_Test;
DbgPrint(" Battery 1 has been inserted ...\r\n");
}
else lcd_printf(0,4," No battery ");
break;
case Battery_Chargeable_Test:
// 检测电池是否是可充电电池, 返回1 代表可充电电池
TempStatus = Bat1_Recharge_Test();
if( 1 == TempStatus )
{
Bat1_Status = Battery_Chargeable;
Bat1_StateMachine = Battery_Charge_Discharge;
DbgPrint(" Battery 1 is rechargeable ...\r\n");
}
else
{
Bat1_Status = Battery_Not_Chargeable;
//返回0 该电池不是可充电电池 拒冲
Bat1_StateMachine = Battery_Wait_For_Remove;
DbgPrint(" Battery 1 refuse charge, wait take off ...\r\n");
}
break;
// 电池处于充电状态 等待用户选择充电方式(有一个默认设置)
case Battery_Charge_Discharge:
Bat1_Charge_Discharge_Choise = mode;
if( Battery_Standard_Charge_Mode == Bat1_Charge_Discharge_Choise )
{
// 标准充电前先放电
DbgPrint(" Battery 1 Standard Discharging ...\r\n");
Bat1_Status = Battery_DisCharge;
Bat1_StateMachine = Battery_Discharging;
Batt_Vol_Accumulate(1);
}
else if( Battery_Fast_Charge_Mode == Bat1_Charge_Discharge_Choise )
{
// 置快速充电为预冲状态
DbgPrint(" Battery 1 Fast Charging ...\r\n");
Bat1_Status = Battery_Fast_Charge;
Bat1_Fast_Charge_StateMachine = Battery_Precharge_Mode;
Bat1_StateMachine = Battery_Fast_Charging;
Batt_Vol_Accumulate(1);
}
else if( Battery_Direct_Charge_Mode == Bat1_Charge_Discharge_Choise )
{
// 直接充电,不对电池放电
DbgPrint(" Battery 1 Direct Charging ...\r\n");
Bat1_Status = Battery_Standard_Charge;
Bat1_StateMachine = Battery_Standard_Charging;
}
Bat1_Charge_Discharge_Capacity = 0;
Bat1_Charge_Discharge_Time_Count = 0;
break;
case Battery_Standard_Charging:
// 标准充电模式
TempStatus = Bat1_StandardCharge();
if(1 == TempStatus)
{
Bat1_Status = Battery_Charge_Over;
Bat1_StateMachine = Battery_Wait_For_Remove;
DbgPrint(" Battery 1 charge full, wait take off ...\r\n");
}
break;
case Battery_Fast_Charging:
//快速充电模式
TempStatus = Bat1_FastCharge();
if(1 == TempStatus)
{
Bat1_Status = Battery_Charge_Over;
Bat1_StateMachine = Battery_Wait_For_Remove;
DbgPrint(" Battery 1 charge full, wait take off ...\r\n");
}
break;
case Battery_Discharging:
TempStatus = Bat1_DisCharge();
if(1 == TempStatus)
{
// 放电结束转到标准充电
Bat1_Status = Battery_Standard_Charge;
Bat1_StateMachine = Battery_Standard_Charging;
Bat1_Charge_Discharge_Capacity = 0;
DbgPrint(" Battery 1 Discharge over, change to standard charging ...\r\n");
}
break;
default:
Led1ChargeStat = AllOff;
break;
}
}
void InitChargeParam(void)
{
// 2路电池共同参数设置
BAT_MAX_RESISTANCE = 300; // 可充电电池最大内阻值
BAT_MAX_TEMPERATURE = 500; // 电池充电时最高截止温度
BAT_INSERT_TEST_CCR = 300; // 检测电池是否插入pwm占空比
BAT_RECHARGE_TEST_CCR = 360; // 检测是否是可充电电池使用pwm占空比 900mA左右
BAT_VOL_STOP_DISCHARGE = 1000; // 停止放电电压
BAT_VOL_STD_CHARGE_MAX = 1650; // 标准充电时最高截止电压
BAT_VOL_PRE_CHARGE_OVER = 800; // 预充结束电压
BAT_VOL_FAST_CHARGE_MAX = 1800;// 快冲最高电压
//数值=时间(H)*3600*2000,每500us自增一次
//每小时数值是0x6DDD00
//标准0.1C充电需要时间0x6DDD000(16小时)
//标准0.2C充电需要时间0x36EE800(8小时)
BAT_STD_CHARGE_MAX_TIME = 0x6DDD000;
ReinitChargeParam(0);
ReinitChargeParam(1);
}
void ReinitChargeParam( INT8U param_ptr)
{
INT8U sta;
if ( 0 == param_ptr )
{
// 从eeprom读取电池0的容量
sta = EE_ReadVariable(E2PVarTab[NumbOfSys + 0], &Bat0_Capacity);
if( 1 == sta || Bat0_Capacity == 0) Bat0_Capacity = Battery_Def_Capacity;
if(Bat0_Capacity > Battery_Max_Capacity) Bat0_Capacity = Battery_Max_Capacity;
// 第 0 路电池参数设置
Bat0_Cur_DisCharge = Bat0_Capacity * 0.1; // 放电电流
Bat0_Cur_Pre_CHARGE = Bat0_Capacity * 0.2; // 预冲电流
Bat0_Cur_Fast_CHARGE = Bat0_Capacity * 0.4; // 快冲电流
Bat0_Cur_Standard_CHARGE = Bat0_Capacity * 0.1; // 标准充电电流
Bat0_Cur_Trickle_CHARGE = Bat0_Capacity * 0.005; // 涓流充电电流 0.005C
if (Bat0_Cur_Trickle_CHARGE < 1) Bat0_Cur_Trickle_CHARGE = 1;
Bat0_Cur_Repair_CHARGE = Bat0_Capacity * 0.2; // 修复充电电流
Bat0_StateMachine = Battery_Init; //复位充电状态机
Bat0_Fast_Charge_StateMachine = Battery_Precharge_Mode; //预冲状态
Bat0_Charge_Discharge_Choise = Battery_Standard_Charge_Mode; //默认的充电模式
Bat0_DischargeMachine = Battery_Init; //复位放电状态机
// 电池0 状态标志位
Bat0_Status = Battery_No_Battery;
}
else if ( 1 == param_ptr )
{
// 从eeprom读取电池1的容量
sta = EE_ReadVariable(E2PVarTab[NumbOfSys + 1], &Bat1_Capacity);
if( 1 == sta || Bat1_Capacity == 0) Bat1_Capacity = Battery_Def_Capacity;
if(Bat1_Capacity > Battery_Max_Capacity) Bat1_Capacity = Battery_Max_Capacity;
// 第 1 路电池参数设置
Bat1_Cur_DisCharge = Bat1_Capacity * 0.1; // 放电电流
Bat1_Cur_Pre_CHARGE = Bat1_Capacity * 0.2; // 预冲电流
Bat1_Cur_Fast_CHARGE = Bat1_Capacity * 0.4; // 快冲电流
Bat1_Cur_Standard_CHARGE = Bat1_Capacity * 0.1; // 标准充电电流
Bat1_Cur_Trickle_CHARGE = Bat1_Capacity * 0.005; // 涓流充电电流
if (Bat1_Cur_Trickle_CHARGE < 1) Bat1_Cur_Trickle_CHARGE = 1;
Bat1_Cur_Repair_CHARGE = Bat1_Capacity * 0.2; // 修复充电电流
Bat1_StateMachine = Battery_Init; //复位充电状态机
Bat1_Charge_Discharge_Choise = Battery_Standard_Charge_Mode; //默认的充电模式
Bat1_DischargeMachine = Battery_Init; //复位放电状态机
// 电池1 状态标志位
Bat1_Status = Battery_No_Battery;
}
}
/*入口参数flag=1 输出校正后的数据
入口参数flag=0 输出没校正的数据
*/
void GetChargeMeasure(void)
{
ADC_Covert_Value();
Bat0_Temperature = ADC_ConvertedValue[0]*3300/4096;
Bat1_Temperature = ADC_ConvertedValue[1]*3300/4096;
//电流调零
Bat0_Cur = Zero_current_bat0(ADC_ConvertedValue[2]*3300/4096);
Bat1_Cur = Zero_current_bat1(ADC_ConvertedValue[3]*3300/4096);
if( Battery_Discharging == Bat0_DischargeMachine || Bat0_Status == Battery_DisCharge )
{
// 软件调整电流零点误差
if( Bat0_Cur < 8 ) Bat0_Cur = 0xffff;
Bat0_Cur = 0xffff - Bat0_Cur;
}
else if( Bat0_Cur > 32768 ) Bat0_Cur = 0;
if( Battery_Discharging == Bat1_DischargeMachine || Bat1_Status == Battery_DisCharge )
{
// 软件调整电流零点误差
if( Bat1_Cur < 8 ) Bat1_Cur = 0xffff;
Bat1_Cur = 0xffff - Bat1_Cur;
}
else if( Bat1_Cur > 32768 ) Bat1_Cur = 0;
//电压调零
Bat0_Vol = Zero_voltage_bat0( ADC_ConvertedValue[4]*3300/4096 );
Bat1_Vol = Zero_voltage_bat1( ADC_ConvertedValue[5]*3300/4096 );
Temperature_0 = ((1.42 - ADC_ConvertedValue[6]*3.3/4096)*1000/4.35 + 25)*10;
Vref = ADC_ConvertedValue[7]*3300/4096;
}
/**************************************************************
检测是否有电池放插入充电器 输出一个短时间的pwm
如果没有插入电池 那么检测到的电压应该是3300mv
如果低于3300mv 那么就是有电池插入
这里设置的是低于 BAT_Vol_CHARGE_MAX
**************************************************************/
INT8U Bat0_Insert_Test(void)
{
INT16U Bat0_Vol_temp;
// 输出pwm
TIM2->CCR1 = BAT_INSERT_TEST_CCR;
// 延迟10ms的时间,完整一次采样需要的时间是448us,这里一轮采样16次
SysDelay(30);
// 获取当前的检测数据
GetChargeMeasure();
Bat0_Vol_temp = Bat0_Vol ;
// 关闭pwm
TIM2->CCR1 = 0;
SysDelay(20);
// 如果检测电压等于3300mv 证明没有电池插入
// 否则 则认为有电池插入 BAT_Vol_CHARGE_MAX 标准充电时最高截止电压
if( Bat0_Vol_temp < BAT_VOL_STD_CHARGE_MAX )
{
return 1;
}
return 0;
}
INT8U Bat1_Insert_Test(void)
{
INT16U Bat1_Vol_temp;
// 输出pwm
TIM2->CCR2 = BAT_INSERT_TEST_CCR;
// 延迟10ms的时间
SysDelay(30);
// 获取当前的检测数据
GetChargeMeasure();
Bat1_Vol_temp = Bat1_Vol ;
// 关闭pwm
TIM2->CCR2 = 0;
SysDelay(20);
// 如果检测电压等于3300mv 证明没有电池插入
// 否则 则认为有电池插入 BAT0_Vol_Standard_CHARGE_MAX 标准充电时最高截止电压
if( Bat1_Vol_temp < BAT_VOL_STD_CHARGE_MAX )
{
return 1;
}
return 0;
}
/**************************************************************
电池放进来后 检测电池是否可冲
检测不充电时的电池电压 v0
检测充电时的电池电压 vc
检测充电电流 i
则电池内阻 r = (vc - v0)/i
**************************************************************/
INT8U Bat0_Recharge_Test(void)
{
INT8U i;
INT16U Resistance_tmp=0;
INT16U charge_current_tmp;
for(i=0;i<8;i++)
{
// 输出pwm
TIM2->CCR1 = BAT_RECHARGE_TEST_CCR + 10*i;
//延迟8ms的时间
SysDelay(100);
// 获取充电时电池电压和电流参数
GetChargeMeasure();
Bat0_ReChargeable_Vol = Bat0_Vol;
charge_current_tmp = Bat0_Cur;
TIM2->CCR1 = BAT_RECHARGE_TEST_CCR + 10*i + 50;
SysDelay(100);
// 获取充电时电池电压和电流参数
GetChargeMeasure();
// 关闭pwm
TIM2->CCR1 = 0;
Resistance_tmp += ( Bat0_ReChargeable_Vol - Bat0_Vol )*1000 /(charge_current_tmp-Bat0_Cur); // 内阻放大1000倍
//DbgPrint(" vol0 %4d cur0 %4d vol1 %4d cur1 %4d\r\n", Bat0_ReChargeable_Vol,charge_current_tmp,Bat0_Vol,Bat0_Cur);
}
Bat0_Resistance = Resistance_tmp/8;
Bat0_Resistance-=99; //减去采样电阻99毫欧
DbgPrint(" Bat0_Resistance: %4d mOmh \r\n", Bat0_Resistance);
// 如果电池内阻在 BAT_MAX_RESISTANCE 最大可充电电池内阻以内 则是可充电电池
if( Bat0_Resistance < BAT_MAX_RESISTANCE )
{
return 1;
}
return 0;
}
/**************************************************************
电池放进来后 检测电池是否可冲
检测不充电时的电池电压 v0
检测充电时的电池电压 vc
检测充电电流 i
则电池内阻 r = (vc - v0)/i
**************************************************************/
INT8U Bat1_Recharge_Test(void)
{
INT8U i;
INT16U Resistance_tmp=0;
INT16U charge_current_tmp;
// 输出pwm
for(i=0;i<8;i++)
{
// 输出pwm
TIM2->CCR2 = BAT_RECHARGE_TEST_CCR + 10*i;
SysDelay(100);
// 获取充电时电池电压和电流参数
GetChargeMeasure();
Bat1_ReChargeable_Vol = Bat1_Vol;
charge_current_tmp = Bat1_Cur;
TIM2->CCR2 = BAT_RECHARGE_TEST_CCR + 10*i + 50;
SysDelay(100);
// 获取充电时电池电压和电流参数
GetChargeMeasure();
// 关闭pwm
TIM2->CCR2 = 0;
Resistance_tmp += ( Bat1_ReChargeable_Vol - Bat1_Vol )*1000 /(charge_current_tmp-Bat1_Cur); // 内阻放大1000倍
}
// 计算电池内阻/////////////////////////////////////////////
Bat1_Resistance = Resistance_tmp/8;
Bat1_Resistance-=99; //减去采样电阻99毫欧
DbgPrint(" Bat1_Resistance: %4d mOmh \r\n", Bat1_Resistance);
// 如果电池内阻在 BAT_MAX_RESISTANCE 最大可充电电池内阻以内 则是可充电电池
if( Bat1_Resistance < BAT_MAX_RESISTANCE )
{
return 1;
}
return 0;
}
// battery 0 PID control process
void Bat0_StandardControl(void)
{
INT16U Charge_CCR;
// 这里设置的电流是标准充电电流
Charge_CCR = pid_Controller(Bat0_Cur_Standard_CHARGE, Bat0_Cur, &pidData0);
if (Charge_CCR > 900) Charge_CCR = 900;
TIM2->CCR1 = Charge_CCR;
}
void Bat0_TrickleControl(void)
{
INT16U Charge_CCR;
// 这里设置的电流是涓流充电电流
Charge_CCR = pid_Controller(Bat0_Cur_Trickle_CHARGE, Bat0_Cur, &pidData0);
if (Charge_CCR > 900) Charge_CCR = 900;
TIM2->CCR1 = Charge_CCR;
Led0ChargeStat = RedFlash2HZ;
}
void Bat0_PreControl(void)
{
INT16U Charge_CCR;
// 这里设置的电流是预充电电流
Charge_CCR = pid_Controller(Bat0_Cur_Pre_CHARGE, Bat0_Cur, &pidData0);
if (Charge_CCR > 900) Charge_CCR = 900;
TIM2->CCR1 = Charge_CCR;
}
void Bat0_FastControl(void)
{
INT16U Charge_CCR;
// 这里设置的电流是快充充电电流
Charge_CCR = pid_Controller(Bat0_Cur_Fast_CHARGE, Bat0_Cur, &pidData0);
if (Charge_CCR > 900) Charge_CCR = 900;
TIM2->CCR1 = Charge_CCR;
}
// battery 1 PID control process
void Bat1_StandardControl(void)
{
INT16U Charge_CCR;
// 这里设置的电流是标准充电电流
Charge_CCR = pid_Controller(Bat1_Cur_Standard_CHARGE, Bat1_Cur, &pidData1);
if (Charge_CCR > 900) Charge_CCR = 900;
TIM2->CCR2 = Charge_CCR;
}
void Bat1_TrickleControl(void)
{
INT16U Charge_CCR;
// 这里设置的电流是涓流充电电流
Charge_CCR = pid_Controller(Bat1_Cur_Trickle_CHARGE, Bat1_Cur, &pidData1);
if (Charge_CCR > 900) Charge_CCR = 900;
TIM2->CCR2 = Charge_CCR;
Led1ChargeStat = RedFlash2HZ;
}
void Bat1_PreControl(void)
{
INT16U Charge_CCR;
// 这里设置的电流是预充充电电流
Charge_CCR = pid_Controller(Bat1_Cur_Pre_CHARGE, Bat1_Cur, &pidData1);
if (Charge_CCR > 900) Charge_CCR = 900;
TIM2->CCR2 = Charge_CCR;
}
void Bat1_FastControl(void)
{
INT16U Charge_CCR;
// 这里设置的电流是快充充电电流
Charge_CCR = pid_Controller(Bat1_Cur_Fast_CHARGE, Bat1_Cur, &pidData1);
if (Charge_CCR > 900) Charge_CCR = 900;
TIM2->CCR2 = Charge_CCR;
}
/**************************************************************
标准充电方式 使用0.1C的电流充电 充电时间15h
**************************************************************/
INT8U Bat0_StandardCharge(void)
{
// 确认电池处于充电状态
if( Bat0_Status == Battery_Standard_Charge )
{
// 获取实时检测结果
GetChargeMeasure();
// 如果电池电压过高 则停止
if( Bat0_Vol_Seconds > BAT_VOL_STD_CHARGE_MAX )
{
Bat0_TrickleControl(); //涓流充电
DbgPrint(" Battery 0 chargeing over by volt ...\r\n");
return 1;
}
// 如果充电时间到达 则停止
if( Bat0_Charge_Discharge_Time_Count > BAT_STD_CHARGE_MAX_TIME )
{
Bat0_TrickleControl(); //涓流充电
DbgPrint(" Battery 0 chargeing over by time ...\r\n");
return 1;
}
// 如果充电容量到达 则停止
if( Bat0_Charge_Discharge_Capacity > Bat0_Capacity * 1.2 )
{
Bat0_TrickleControl(); //涓流充电
DbgPrint("Battery 0 chargeing over by capacity ...\r\n");
return 1;
}
// 如果电池温度过高 则停止
//if( Bat0_Temperature > BAT_MAX_TEMPERATURE )
//{
// Bat0_TrickleControl(); //涓流充电
// DbgPrint(" Battery 0 chargeing over by temp ...\r\n");
// return 1;
//}
Bat0_StandardControl(); //标准充电
}
Led0ChargeStat = RedOn;
return 0;
}
/**************************************************************
标准充电方式 使用0.1C的电流充电 充电时间15h
**************************************************************/
INT8U Bat1_StandardCharge(void)
{
// 确认电池处于充电状态
if( Bat1_Status == Battery_Standard_Charge )
{
// 获取实时检测结果
GetChargeMeasure();
// 如果电池电压过高 则停止
if( Bat1_Vol_Seconds > BAT_VOL_STD_CHARGE_MAX )
{
Bat1_TrickleControl(); //涓流充电
DbgPrint("Battery 1 chargeing over by volt ...\r\n");
return 1;
}
// 如果充电时间到达 则停止
if( Bat1_Charge_Discharge_Time_Count > BAT_STD_CHARGE_MAX_TIME )
{
Bat1_TrickleControl(); //涓流充电
DbgPrint("Battery 1 chargeing over by time ...\r\n");
return 1;
}
// 如果充电容量到达 则停止
if( Bat1_Charge_Discharge_Capacity > Bat1_Capacity * 1.2 )
{
Bat1_TrickleControl(); //涓流充电
DbgPrint("Battery 1 chargeing over by capacity ...\r\n");
return 1;
}
// 如果电池温度过高 则停止
//if( Bat1_Temperature > BAT_MAX_TEMPERATURE )
//{
// Bat1_TrickleControl(); //涓流充电
// DbgPrint(" Battery 1 chargeing over by temp ...\r\n");
// return 1;
//}
Bat1_StandardControl(); //标准充电
}
Led1ChargeStat = RedOn;
return 0;
}
/**************************************************************
标准放电
**************************************************************/
INT8U Bat0_DisCharge(void)
{
INT16U DisCharge0_CCR;
// 获取实时检测结果
GetChargeMeasure();
// 这里设置的电流是标准充电电流
DisCharge0_CCR = pid_Controller(Bat0_Cur_DisCharge, Bat0_Cur, &pidData0);
if (DisCharge0_CCR > 900) DisCharge0_CCR = 900;
TIM3->CCR1 = DisCharge0_CCR;
// 如果电池电压到达截止充电电压 则停止
if( Bat0_Vol_Seconds < BAT_VOL_STOP_DISCHARGE )
{
TIM3->CCR1 = 0; // 停止放电
DbgPrint(" Battery 0 discharge over by volt ...\r\n");
return 1;
}
// 如果电压大于阀值,则表示电池被取出
else if( Bat0_Vol_Seconds > BAT_VOL_STD_CHARGE_MAX )
{
TIM3->CCR1 = 0; // 停止放电
DbgPrint(" Battery 0 has been take off ...\r\n");
return 1;
}
Led0ChargeStat = GreenFlash20HZ;
return 0;
}
void Bat0_Discharge_Machine(void)
{
INT8U TempStatus;
static INT8U timecount = 0;
switch(Bat0_DischargeMachine)
{
case Battery_Init:
lcd_printf(0,2," Detecting... ");
Bat0_DischargeMachine = Battery_Insert_Test;
break;
// 检测是否有电池插入状态 返回1 代表有电池被插入
case Battery_Insert_Test :
//每隔1S钟才检测一次
if( timecount <30 )
{
timecount++;
break;
}
else timecount = 0;
TempStatus = Bat0_Insert_Test();
if( 1 == TempStatus )
{
Bat0_DischargeMachine = Battery_Discharging;
Bat0_Status= Battery_DisCharge;
Bat0_Charge_Discharge_Capacity = 0;
Bat0_Charge_Discharge_Time_Count = 0;
DbgPrint(" Battery 0 has been inserted ...\r\n");
DbgPrint(" Battery 0 start to discharge ...\r\n");
Batt_Vol_Accumulate(1);
}
else
lcd_printf(0,2," No battery ");
break;
case Battery_Discharging:
Led0ChargeStat = GreenFlash20HZ;
TempStatus = Bat0_DisCharge();
if( 1 == TempStatus )
{
Bat0_DischargeMachine = Battery_Wait_For_Remove;
Bat0_Status= Battery_Discharge_Over;
DbgPrint(" Battery 0 discharge over, wait take off ...\r\n");
}
break;
case Battery_Wait_For_Remove:
Led0ChargeStat = GreenOn;
//每隔3S钟才检测一次
if( timecount <30 )
{
timecount++;
break;
}
else timecount = 0;
TempStatus = Bat0_Insert_Test();
if( 0 == TempStatus )
{
Led0ChargeStat = AllOff;
Bat0_DischargeMachine = Battery_Insert_Test;
Bat0_Charge_Discharge_Capacity = 0;
Bat0_Charge_Discharge_Time_Count = 0;
DbgPrint(" Battery 0 has been take off ...\r\n");
}
break;
default:
break;
}
}
/**************************************************************
标准放电
**************************************************************/
INT8U Bat1_DisCharge(void)
{
INT16U DisCharge1_CCR;
// 获取实时检测结果
GetChargeMeasure();
// 这里设置的电流是标准充电电流
DisCharge1_CCR = pid_Controller(Bat1_Cur_DisCharge, Bat1_Cur, &pidData1);
if (DisCharge1_CCR > 900) DisCharge1_CCR = 900;
TIM3->CCR2 = DisCharge1_CCR;
// 如果电池电压到达截止充电电压 则停止
if( Bat1_Vol_Seconds < BAT_VOL_STOP_DISCHARGE )
{
DbgPrint(" Battery 1 discharge over by volt ...\r\n");
TIM3->CCR2 = 0; // 停止放电
return 1;
}
// 如果电压大于阀值,则表示电池被取出
else if( Bat1_Vol_Seconds > BAT_VOL_STD_CHARGE_MAX )
{
DbgPrint(" Battery 1 has been take off ...\r\n");
TIM3->CCR1 = 0; // 停止放电
return 1;
}
Led1ChargeStat = GreenFlash20HZ;
return 0;
}
void Bat1_Discharge_Machine(void)
{
INT8U TempStatus;
static INT8U timecount = 0;
switch(Bat1_DischargeMachine)
{
case Battery_Init:
lcd_printf(0,4," Detecting... ");
Bat1_DischargeMachine = Battery_Insert_Test;
break;
// 检测是否有电池插入状态 返回1 代表有电池被插入
case Battery_Insert_Test :
//每隔1S钟才检测一次
if( timecount <30 )
{
timecount++;
break;
}
else timecount = 0;
TempStatus = Bat1_Insert_Test();
if( 1 == TempStatus )
{
Bat1_DischargeMachine = Battery_Discharging;
Bat1_Status= Battery_DisCharge;
Bat1_Charge_Discharge_Capacity = 0;
Bat1_Charge_Discharge_Time_Count = 0;
DbgPrint(" Battery 1 has been inserted ...\r\n");
DbgPrint(" Battery 1 start to discharge ...\r\n");
Batt_Vol_Accumulate(1);
}
else
lcd_printf(0,4," No battery ");
break;
case Battery_Discharging:
Led1ChargeStat = GreenFlash20HZ;
TempStatus = Bat1_DisCharge();
if( 1 == TempStatus )
{
Bat1_DischargeMachine = Battery_Wait_For_Remove;
Bat1_Status= Battery_Discharge_Over;
DbgPrint(" Battery 1 discharge over, wait take off ...\r\n");
}
break;
case Battery_Wait_For_Remove:
Led1ChargeStat = GreenOn;
//每隔3S钟才检测一次
if( timecount <30 )
{
timecount++;
break;
}
else timecount = 0;
TempStatus = Bat1_Insert_Test();
if( 0 == TempStatus )
{
Bat1_DischargeMachine = Battery_Insert_Test;
Bat1_Charge_Discharge_Capacity = 0;
Bat1_Charge_Discharge_Time_Count = 0;
DbgPrint(" Battery 1 has been take off ...\r\n");
}
break;
default:
break;
}
}
/*********************************************************************************************************
** 函数名称: Bat0_FastCharge
** 功能描述: 快速充电函数
**
** 预充电流0.2C,预充最长时间60min,到达最长时间如果电压
** 还没有达到预充截止电压,则停止充电
**
** 快速充电电流0.4C,开始快充时设置5min时间为不检测负
** 压阶段,快充最长时间210min,达到最长时间如果没有出
** 现负压,则停止充电
**
** 总的快充最长时间为270min,到达时间则停止充电
********************************************************************************************************/
INT8U Bat0_FastCharge(void) //快速充电模式
{
static INT32U timecount,timeold;
static INT16U bat_vol_top = 0;
static INT8S delt_v[delt_v_counts]; // 负压检测数组
INT8U i;
INT8S sum = 0;
// 获取实时检测结果
GetChargeMeasure();
switch(Bat0_Fast_Charge_StateMachine)
{
case Battery_Init:
{
timecount = timeold = SoftTimer ; // 清零计数器
}
break;
case Battery_Precharge_Mode:
{
Led0ChargeStat = RedFlash10HZ;
// 这里设置的预冲电流
Bat0_PreControl();
Bat0_Status = Battery_Fast_Charge ;
timeold = SoftTimer;
if( timeold - timecount > 0x6DDD00 ) // 16 minutes
{
// 到达预充最长时间60min,还没到达预充截止电压,则停止充电
if( Bat0_Vol_Seconds < BAT_VOL_PRE_CHARGE_OVER )
{
TIM2->CCR1 = 0;
Bat0_Fast_Charge_StateMachine = Battery_Charge_Over_Mode;
DbgPrint(" Battery 0 pre - charge over by volt ...\r\n");
return 1;
}
}
// 如果电池电压到达预冲截止电压则跳转
if( Bat0_Vol_Seconds > BAT_VOL_PRE_CHARGE_OVER )
{
// 跳转到不监控负压的快充模式
Bat0_Fast_Charge_StateMachine = Battery_Not_Monitor_Mode;
timecount = timeold = SoftTimer ; // 清零计数器
DbgPrint(" Battery 0 pre - charge over ...\r\n");
DbgPrint(" Battery 0 jump to not monitor charge ...\r\n");
}
}
break;
case Battery_Not_Monitor_Mode:
{
Led0ChargeStat = RedFlash20HZ;
// 快充电流
Bat0_FastControl();
// 如果电池电压过高 则停止充电
if( Bat0_Vol_Seconds > BAT_VOL_FAST_CHARGE_MAX )
{
Bat0_TrickleControl(); //涓流充电
Bat0_Fast_Charge_StateMachine = Battery_Charge_Over_Mode;
DbgPrint(" Battery 0 fast charge over by volt ...\r\n");
return 1;
}
// 这里延迟5分钟后开始检测负压,其实还有更好的一个
// 办法是等待电压上升到一个阀门值,再去开始检测负压
timeold = SoftTimer;
if( timeold - timecount > 0x927C0 ) // 5 minutes
{
Bat0_Fast_Charge_StateMachine = Battery_Monitor_Charge_Mode;
// 初始化负压检测数组
for( i=0; i<delt_v_counts; i++)
{
delt_v = -1;
}
timecount = timeold = SoftTimer ; // 清零计数器
DbgPrint(" Battery 0 not monitor charge over ...\r\n");
DbgPrint(" Battery 0 jump to monitor charge ...\r\n");
}
}
break;
case Battery_Monitor_Charge_Mode:
{
Led0ChargeStat = RedFlash20HZ;
// 这里设置的快充电流
Bat0_FastControl();
// 如果电池电压过高 则停止充电
if( Bat0_Vol_Seconds > BAT_VOL_FAST_CHARGE_MAX )
{
Bat0_TrickleControl(); //涓流充电
Bat0_Fast_Charge_StateMachine = Battery_Charge_Over_Mode;
DbgPrint(" Battery 0 fast - charge over by volt ...\r\n");
return 1;
}
timeold = SoftTimer;
if( timeold - timecount > 0x1808580 ) // 210 minutes
{
// 到达快充最长时间90min,还没出现负压,则停止充电
Bat0_TrickleControl(); //涓流充电
Bat0_Fast_Charge_StateMachine = Battery_Charge_Over_Mode;
DbgPrint(" Battery 0 fast - charge over by time ...\r\n");
return 1;
}
// 检测负压/////////////////////////////////////////////////////
// 获得最高电压值,采用秒值运算
if( Bat0_Vol_Seconds > bat_vol_top )
{
bat_vol_top = Bat0_Vol_Seconds;
}
//向左 移动数组的数值
for( i=0; i<delt_v_counts -1; i++)
{
delt_v = delt_v[i+1];
}
// 出现负压,填充1,否则填充-1
if( bat_vol_top - Bat0_Vol_Seconds > delt_v_value )
delt_v[delt_v_counts-1] = 1;
else
delt_v[delt_v_counts-1] = -1;
// 计算斜率总和
for( i=0; i<delt_v_counts; i++)
{
sum += delt_v ;
}
if( sum > delt_v_counts/2 )
{
// 跳转到充电结束
Bat0_Fast_Charge_StateMachine = Battery_Charge_Over_Mode;
Bat0_TrickleControl(); //涓流充电
timecount = 0;
DbgPrint(" Battery 0 fast - charge over by delt-V ...\r\n");
return 1;
}
}
break;
case Battery_Charge_Over_Mode:
return 1;
default:
break;
}
// 总的快速充电时间
if( Bat0_Charge_Discharge_Time_Count > 0x1EE6280) // 270 minutes
{
Bat0_TrickleControl(); //涓流充电
Bat0_Fast_Charge_StateMachine = Battery_Charge_Over_Mode;
DbgPrint(" Battery 0 fast - charge over by total time ...\r\n");
return 1;
}
return 0;
}
/*********************************************************************************************************
** 函数名称: Bat1_FastCharge
** 功能描述: 快速充电函数
**
** 预充电流0.2C,预充最长时间60min,到达最长时间如果电压
** 还没有达到预充截止电压,则停止充电
**
** 快速充电电流0.4C,开始快充时设置5min时间为不检测负
** 压阶段,快充最长时间210min,达到最长时间如果没有出
** 现负压,则停止充电
**
** 总的快充最长时间为150min,到达时间则停止充电
********************************************************************************************************/
INT8U Bat1_FastCharge(void) //快速充电模式
{
static INT32U timecount ,timeold;
static INT16U bat_vol_top = 0;
static INT8S delt_v[delt_v_counts]; // 负压检测数组
INT8U i;
INT8S sum = 0;
// 获取实时检测结果
GetChargeMeasure();
switch(Bat1_Fast_Charge_StateMachine)
{
case Battery_Init:
{
timecount = timeold = SoftTimer ; // 清零计数器
}
break;
case Battery_Precharge_Mode:
{
Led1ChargeStat = RedFlash10HZ;
// 这里设置的预冲电流
Bat1_PreControl();
Bat1_Status = Battery_Fast_Charge ;
timeold = SoftTimer;
if( timeold - timecount > 0x6DDD00 ) // 16 minutes
{
// 到达预充最长时间60min,还没到达预充截止电压,则停止充电
if( Bat1_Vol_Seconds < BAT_VOL_PRE_CHARGE_OVER )
{
Bat1_TrickleControl(); //涓流充电
Bat1_Fast_Charge_StateMachine = Battery_Charge_Over_Mode;
DbgPrint(" Battery 1 pre - charge over by volt ...\r\n");
return 1;
}
}
// 如果电池电压到达预冲截止电压则跳转
if( Bat1_Vol_Seconds > BAT_VOL_PRE_CHARGE_OVER )
{
// 跳转到不监控负压的快充模式
Bat1_Fast_Charge_StateMachine = Battery_Not_Monitor_Mode;
timecount = timeold = SoftTimer ; // 清零计数器
DbgPrint(" Battery 1 pre - charge over ...\r\n");
DbgPrint(" Battery 1 jump to not monitor charge ...\r\n");
}
}
break;
case Battery_Not_Monitor_Mode:
{
Led1ChargeStat = RedFlash20HZ;
// 快充电流
Bat1_FastControl();
// 如果电池电压过高 则停止充电
if( Bat1_Vol_Seconds > BAT_VOL_FAST_CHARGE_MAX )
{
Bat1_TrickleControl(); //涓流充电
Bat1_Fast_Charge_StateMachine = Battery_Charge_Over_Mode;
DbgPrint(" Battery 1 fast - charge over by volt ...\r\n");
return 1;
}
// 这里延迟5分钟后开始检测负压,其实还有更好的一个
// 办法是等待电压上升到一个阀门值,再去开始检测负压
timeold = SoftTimer;
if( timeold - timecount > 0x927C0 ) // 5 minutes
{
Bat1_Fast_Charge_StateMachine = Battery_Monitor_Charge_Mode;
// 初始化负压检测数组
for( i=0; i<delt_v_counts; i++)
{
delt_v = -1;
}
timecount = timeold = SoftTimer ; // 清零计数器
DbgPrint(" Battery 1 not monitor charge over ...\r\n");
DbgPrint(" Battery 1 jump to monitor charge ...\r\n");
}
}
break;
case Battery_Monitor_Charge_Mode:
{
Led1ChargeStat = RedFlash20HZ;
// 这里设置的快充电流
Bat1_FastControl(); //涓流充电
// 如果电池电压过高 则停止充电
if( Bat1_Vol_Seconds > BAT_VOL_FAST_CHARGE_MAX )
{
Bat1_Fast_Charge_StateMachine = Battery_Charge_Over_Mode;
TIM2->CCR2 = 0;
DbgPrint(" Battery 1 fast - charge over by volt ...\r\n");
return 1;
}
timeold = SoftTimer;
if( timeold - timecount > 0x1808580 ) // 210 minutes
{
// 到达快充最长时间90min,还没出现负压,则停止充电
TIM2->CCR2 = 0;
Bat1_Fast_Charge_StateMachine = Battery_Charge_Over_Mode;
DbgPrint(" Battery 1 fast - charge over by time ...\r\n");
return 1;
}
// 检测负压/////////////////////////////////////////////////////
// 获得最高电压值,采用秒值运算
if( Bat1_Vol_Seconds > bat_vol_top )
{
bat_vol_top = Bat1_Vol_Seconds;
}
//向左 移动数组的数值
for( i=0; i<delt_v_counts -1; i++)
{
delt_v = delt_v[i+1];
}
// 出现负压,填充1,否则填充-1
if( bat_vol_top - Bat1_Vol_Seconds > delt_v_value )
delt_v[delt_v_counts-1] = 1;
else
delt_v[delt_v_counts-1] = -1;
// 计算斜率总和
for( i=0; i<delt_v_counts; i++)
{
sum += delt_v ;
}
if( sum > delt_v_counts/2 )
{
// 跳转到充电结束
Bat1_TrickleControl(); //涓流充电
Bat1_Fast_Charge_StateMachine = Battery_Charge_Over_Mode;
timecount = 0;
DbgPrint(" Battery 1 fast - charge over by delt-V ...\r\n");
return 1;
}
}
break;
case Battery_Charge_Over_Mode:
return 1;
default:
break;
}
// 总的快速充电时间
if( Bat1_Charge_Discharge_Time_Count > 0x1EE6280) // 270 minutes
{
Bat1_TrickleControl(); //涓流充电;
Bat1_Fast_Charge_StateMachine = Battery_Charge_Over_Mode;
DbgPrint(" Battery 1 fast - charge over by total time ...\r\n");
return 1;
}
return 0;
} |
|