搜索
bottom↓
回复: 17

新版V1.2硬件的充电器程序(基于3.3固件的)0.09版本

[复制链接]

出0入0汤圆

发表于 2010-8-2 09:01:02 | 显示全部楼层 |阅读模式
新版V1.2硬件的充电器程序(基于3.3固件的)

0.09版本

那堆代码混乱到不得了,看不下去的都改了,界面全部英文化,去掉一大堆冗余和垃圾代码
菜单更新了,更符合实际操作,那些没实际用途的参数配置全部去掉

增加直接充电和充电后进入涓流充电
上位机软件源码兼容Delphi2010,串口通信改为文本显示,就算没工具都能人工看得明白

009 by LYSoftourdev_572371.rar(文件大小:6.12M) (原文件名:BAT CHG 009.rar)

出0入0汤圆

发表于 2010-8-2 10:22:49 | 显示全部楼层
其实感觉菜单的有一个功能还是有必要的。

就是设置电池容量。 最适合电池充电的电流是根据电池容量来定的。

1200mAH 和 2500mAH 的电池最适合的电池电流还是差别比较大的。

通常别的智能充电器的最法是分嘈的。 假如只插当中两节可以两倍电流充电的。

出0入0汤圆

发表于 2010-8-2 10:24:20 | 显示全部楼层
看楼主比较有兴趣折腾软件, 我放出一个半成品的代码 , 楼主可以看看 。

最近在抽时间弄 RTT 版本的。 所以这个先放了放。 楼主可以拿去看看。 比你修改之前版本的软件值得写很多很多倍了。

点击此处下载 ourdev_572377.rar(文件大小:6.14M) (原文件名:CodeChargerQP.rar)

出0入0汤圆

发表于 2010-8-2 10:30:15 | 显示全部楼层
参考资料, 上面这个版本发布了我移植了的最新版本的 QP。 基于 MDK,官方下载不到的哦。

http://www.state-machine.com/


(原文件名:1.JPG)

出0入0汤圆

 楼主| 发表于 2010-8-2 10:31:46 | 显示全部楼层
设置电池容量的功能没移除啊
呵呵

RTT版本的哪里有?
不过偶还是习惯uCOS这个模式,其实关键是充电算法和控制方式,而引入RTOS对界面控制较为灵活而已

出0入0汤圆

发表于 2010-8-2 10:33:38 | 显示全部楼层
RTT的仅仅半成品, 内部交流可以哦 , 打算利用业余时间这个月完工。

楼主有兴趣可以一起玩哦。

不过上面这个也是我极力推荐的, 相当不错的软件思路。

出0入0汤圆

发表于 2010-8-2 10:48:53 | 显示全部楼层
支持一下

出0入0汤圆

 楼主| 发表于 2010-8-2 10:49:38 | 显示全部楼层
简单看了一下,充电逻辑,还是没变化,而我修改了这些,你用用修改版就知道的

QP这个有什么特色之处呢?

出0入0汤圆

发表于 2010-8-2 10:58:42 | 显示全部楼层
^_^ 充电逻辑是需要好好改进的 我明白你的意思。 我一定回去用用你修改过的版本的。

QP 这个版本的逻辑部分没有做, 别的部分都做了。


QP 的特色是使用状态机来编程, 编程变的有趣味了。 C++ 的用 C 实现了来编程。

出0入0汤圆

 楼主| 发表于 2010-8-2 11:31:52 | 显示全部楼层
嗯,从名字上也可得知是状态机编程
不过我不太习惯状态机的方式,而比较习惯消息模式的编程,可能是写得Win32程序太多了的缘故吧

出0入4汤圆

发表于 2010-8-2 11:42:19 | 显示全部楼层
我用IAR C++来写,所有的库都改用自己写的C++库,整个流程也是采用“状态机+伪线程”的方式,没有采用任何RTOS。

出0入0汤圆

 楼主| 发表于 2010-8-2 11:57:26 | 显示全部楼层
我不用C++的,都是C的

这个版本的菜单我都改了处理的,可以循环浏览的

偶是不喜欢IAR,而比较喜欢MDK

另外,电池修复方法还没想好咋弄的好,不知道你们有什么看法没有呢?

出0入0汤圆

发表于 2010-8-2 13:22:27 | 显示全部楼层
嗯,从名字上也可得知是状态机编程
不过我不太习惯状态机的方式,而比较习惯消息模式的编程

===================================

这个是 MDK 版本的。 不是 C++ , 就是 C。

你看下代码就明白, 这个就是消息机制的状态机。 和 ucos 的消息是一样的意思。

C++ 的编程模式的好处是继承, 比如一个快捷键, 在子类菜单中都是同一个子程序, 不必要写很多遍。

出0入0汤圆

 楼主| 发表于 2010-8-2 19:41:16 | 显示全部楼层
接口封装得好,不用C++都可以做好的,而且MDK的C++远没达到C++Builder的OOP程度呢

修复电池的过程有这个:

1C放电至1.00V,转0.2C放电至0.6V
搁置30分钟,
0.2C充6.5小时,
搁置30分钟,
1C放电至1.00V,转0.2C放电至0.8V
搁置30分钟,
0.2C充7小时,
搁置30分钟,
1C放电至1.00V,转0.2C放电至0.9V

未知是否靠谱?

出0入0汤圆

 楼主| 发表于 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;
}

出0入0汤圆

发表于 2010-8-6 21:12:05 | 显示全部楼层
13楼的方法还是靠谱的。

其实简单点的办法就是 0.1C 充电 16 小时, 再0.1放电放完。 过程循环 3 次。

出0入0汤圆

发表于 2010-8-6 21:35:01 | 显示全部楼层
原来的0.08代码的确看得人头痛,菜单和执行部分感觉耦合太强,我加了磷酸铁锂支持很费劲,改得很乱,铁锂要求恒压恒流充电,因此原来的电流调整实时性也差些。感觉目前没法把这些代码完美并入。同时还要修改运放分压电阻,为避免分裂,一直也就没发布,这些天先充自己的AA铁锂电池测试。有时间看看哪个分支更容易添加新功能吧。

出0入0汤圆

发表于 2010-8-6 21:40:57 | 显示全部楼层
既然加入的人多了, 就需要整理了。 ^_^

我一定抽时间和大家一起交流, 把完整的分支做出来。
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-4-20 13:53

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

快速回复 返回顶部 返回列表