⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 charge.c

📁 Keil单片机软件开发平台下的一个51系列单片机工程
💻 C
📖 第 1 页 / 共 3 页
字号:
/*
* Filename     : charge.c
* Author       : Li Dawen
* Copyright (c): Coslight Group .co
* Create Date  : 2002.04.27
* Version      : 0.1.0
*/
#include "includes.h"
#include "charge.h"
#include "module.h"
#include "protocol.h"

/****************************************************************************/
/****************************************************************************/
/*
蓄电池工作可分为均充、稳流均充、浮充、放电、测试五个状态

所有充电状态充电电流都不可超过限流值,
如充电电流过大则由于系统限流作用,充电电压将低于设定值,保持充电电流恒定

均充        限流恒压充电,均充电压
稳流均充    恒压充电,均充电压
浮充        恒压充电,浮充电压
放电        充电电流为负数
测试        为测试电池,人为的放电

状态转换如下

均充 -> 稳流均充
1电流条件   充电电流小于限值
2时间条件   均充保护时间到
3容量条件   当前容量大于转换点

稳流均充 -> 浮充
1电流条件   充电电流大于转换点
2时间条件   该状态充电持续时间大于稳流均充时间

浮充 -> 转均充过渡均充
1电流条件   充电电流大于转均充电流
2时间条件   系统未定时均充充电持续时间大于定时均充时间
3容量条件   当前容量小于转均充容量

转均充过渡 -> 均充
1电流条件   充电电流大于转均充电流
2时间条件   过渡时间到

转均充过渡 -> 浮充
1电流条件   充电电流小于转均充电流


测试 -> 浮充
1电压条件   电池电压小于测试终止电压
2容量条件   电池容量小于测试终止容量
3时间条件   测试时间大于最大测试时间

->放电
1电流条件   非测试状态,充电电流为负数

->测试
1启动条件   手动启动

                   放电
                    |
                    v
均充 -> 稳流均充 -> 浮充 <-> 转均充过渡 ->均充
                    ^
                    |
                   测试

运行 电压 电流 时间
----------------------------------------------------
浮充
*/


/*
tm_cfg
0系统延时 fen
1屏幕保护 fen
2均充周期时间 hour
3均充保护时间 fen
4稳流均充时间 fen
5转均充延时   fen
6电池测试时间 fen
*/
int Charge_Step;
int minute_count;
CHARGE Cha;
DA I_Contrl;
/****************************************************************************/
void ChargeInit(void)
{
    Cha.i_buf[0] = 0;
    Cha.i_buf[1] = 0;
    Cha.i_buf[2] = 0;
    Cha.i_da = 0;

    I_Contrl.da_v = 0;
    I_Contrl.da_max = 0;
    I_Contrl.da_min = 0;
    I_Contrl.da_timer = 0;
    I_Contrl.da_stepsize = 0;

    Jkmk.temp[25] = 0;
    ChargeTimerInit();
#ifdef HARD_GP
    Jkmk.ao_cfg[0] = 2400;
    Jkmk.ao_cfg[1] = 1000;
    SetChargeStep(0);   //设置成浮充
#endif
#ifdef HARD_XK
    Jkmk.ao_cfg[0] = 2400;
    Jkmk.ao_cfg[1] = 0;
    SetChargeStep(6);   //设置成停止
#endif
}
void ChargeTimerInit(void)
{
    int i;
    minute_count = 0;
    for (i = 2; i < 6; i++)
    {
        Jkmk.tm_v[i] = Jkmk.tm_cfg[i];
    }
    for (i = 2; i < 6; i++)
    {
        if (Jkmk.tm_v[i] > Jkmk.tm_cfg[i])
        {
             Jkmk.tm_v[i] = Jkmk.tm_cfg[i];
        }
    }
    ChargeTimerStop(3);         //停止均充保护计时器
    ChargeTimerStop(5);         //停止转均充延时计时器

}
/* 每分钟调用一次用于运行计时器*/
void ChargeTimerTick(void)
{
    int i;
    if (++minute_count > 60)
    {
        minute_count = 0;
        Jkmk.tm_v[2]--;
    }
    //分钟计时
    for (i = 3; i < 7; i++)
    {
        if (Jkmk.tm_v[i] > 0)
        {
            Jkmk.tm_v[i]--;
        }
    }
}
void ChargeTimerPlay(int index)
{
    if (Jkmk.tm_v[index] < 0)
    {
        Jkmk.tm_v[index] = -Jkmk.tm_v[index];
    }
}
void ChargeTimerPause(int index)
{
    if (Jkmk.tm_v[index] > 0)
    {
        Jkmk.tm_v[index] = -Jkmk.tm_v[index];
    }
}
void ChargeTimerStart(int index)
{
    Jkmk.tm_v[index] = Jkmk.tm_cfg[index];
}
void ChargeTimerStop(int index)
{
    Jkmk.tm_v[index] = 0;
}
int ChargeTimerCount(int index)
{
    return Jkmk.tm_v[index];
}
/****************************************************************************/
void X_ChargeIdentifyt(void)
{
}
/****************************************************************************/
void ChargeIdentifyt(void)
{
    int step;
    int i_zero = 0;
    //根据电压电流判断电池充电状态 浮充 均充 放电 测试 故障
    //相控用的补丁,被动识别充电状态
    /*
    Jkmk.mk_cfg[10]     电池容量
    Jkmk.mk_cfg[32]     转均充电流比
    Jkmk.mk_cfg[31]     转浮充电流比
    Jkmk.mk_cfg[7]      均充电压
    Jkmk.ai_v[16]       电池电压
    Jkmk.ai_v[17]       电池电流
    Jkmk.temp[24]       自动 手动
    */
    Jkmk.temp[34] = Jkmk.mk_cfg[10]*Jkmk.mk_cfg[30]/10;    //100m充电限流值
    Jkmk.temp[35] = Jkmk.mk_cfg[10]*Jkmk.mk_cfg[32]/10;    //100m转均充电流
    Jkmk.temp[36] = Jkmk.mk_cfg[10]*Jkmk.mk_cfg[31]/10;    //100m转浮充电流
    step = GetChargeStep();
//检查均充电压安全性
    if (Jkmk.mk_cfg[7] < Jkmk.mk_cfg[6])
    {
         Jkmk.mk_cfg[7] = Jkmk.mk_cfg[6];
    }
    //电池测试 逆变 不判断
    if (6 == step || 5 == step)
    {
        return;
    }
//    if (Jkmk.temp[24] == 0)
//    {//自动运行 根据电池电压和电流判断电池是否在放电
     //加入电压条件防止无连接时状态抖动,但效果不好,去掉电压条件,只判断电流
//        if ((Jkmk.ai_v[16] > Jkmk.ai_cfg[16*3+2]/2) && (Jkmk.ai_v[17] < -5))

#ifdef HARD_GP
    if (Jkmk.ai_cfg[17*3] > 700)
    {
        i_zero = -2;
    }
    else
    {
        i_zero = -1;
    }

    if ((Jkmk.ai_v[17] < i_zero))
    {
        //放电
        SetChargeStep(4);
    }
    else
    {
        if (step == 4)
        {
            SetChargeStep(0);
        }
    }
#endif
}
/****************************************************************************/
//相控充电机控制函数
//DA1   电压控制  XX:控制 0:停止
//DA2   电流控制  XX:控制 0:停止
//JK1   DA开关    1:通    0:断
//JK2   脉冲封锁  1:封锁  0:打开
void X_Discharge(void)
{
    //DA输出控制值 接通DA 允许脉冲
    //DA1=X DA2=X JK1 =1 JK2=0
    Cha.i_ctltimer = CHARGE_SOFTSTART_TIME;
    Cha.v_da = Cha.v_set;
    Cha.i_da = Cha.i_sigzero;//启动时去除死区
    Cha.v_da = Cha.v_high;
//    HardOut(5, 1);
//    HardOut(6, 0);
    SetModuleData(MODULE_JKMK|DATA_DO, 4, 0, 1);
    SetModuleData(MODULE_JKMK|DATA_DO, 5, 0, 0);
    X_Voltaget();
    X_Current();
}
void X_Charge(void)
{
    //DA输出控制值 接通DA 允许脉冲
    //DA1=X DA2=X JK1 =1 JK2=0
    Cha.i_ctltimer = CHARGE_SOFTSTART_TIME;
    Cha.v_da = Cha.v_high;
    Cha.i_da = Cha.i_sigzero;//启动时去除死区
//    HardOut(5, 1);
//    HardOut(6, 0);
    SetModuleData(MODULE_JKMK|DATA_DO, 4, 0, 1);
    SetModuleData(MODULE_JKMK|DATA_DO, 5, 0, 0);
    X_Voltaget();
    X_Current();

}
void X_Stop(void)
{
    //DA输出0 封锁脉冲 断开DA
    //DA1=0 DA2=0 JK1 =0 JK2=0
    Cha.i_timer = CHARGE_SOFTSTOP_TIME;    //停止延时定时器启动30S
    SetModuleData(MODULE_JKMK|DATA_DO, 4, 0, 1);
    X_Voltaget();
    X_Current();
}
/****************************************************************************/
//da输出线性平滑函数
void X_IDaSet(int v)
{
    I_Contrl.da_target = v;
    if (I_Contrl.da_target == I_Contrl.da_v)
    {
        return;
    }
    I_Contrl.da_timer = 10;
    I_Contrl.da_stepsize = I_Contrl.da_v - I_Contrl.da_target;
    //判断变化方向,去掉死区
    if (I_Contrl.da_stepsize > 0)
    {
        I_Contrl.da_stepsize /= 8;
        if (I_Contrl.da_stepsize > 10)
            I_Contrl.da_stepsize = 10;
        if (0 == I_Contrl.da_stepsize)
            I_Contrl.da_stepsize = 1;
    }
    else
    {
        I_Contrl.da_stepsize /= 8;
        if (I_Contrl.da_stepsize < -10)
            I_Contrl.da_stepsize = -10;
        if (0 == I_Contrl.da_stepsize)
            I_Contrl.da_stepsize = -1;
    }
}
/****************************************************************************/
//平滑输出da值
void X_IDaUpdata(void)
{
    if (I_Contrl.da_timer > 0)
    {
        I_Contrl.da_timer--;
        //减小超调
        if (I_Contrl.da_stepsize > 0)
        {//输出变小
            if (I_Contrl.da_v <= I_Contrl.da_target )
            {
                I_Contrl.da_stepsize = 0;
                I_Contrl.da_v = I_Contrl.da_target;
            }
        }
        else
        {//输出变大
            if (I_Contrl.da_v >= I_Contrl.da_target )
            {
                I_Contrl.da_stepsize = 0;
                I_Contrl.da_v = I_Contrl.da_target;
            }
        }
        if ((Cha.v_e > (Cha.v_ezero+2)) && (I_Contrl.da_stepsize < 0))
        {//电压偏高 不调节
            //I_Contrl.da_v;
            I_Contrl.da_stepsize = 0;
        }
        else
        {
            I_Contrl.da_v -= I_Contrl.da_stepsize;
        }

        if (I_Contrl.da_v < 0)
        {
            I_Contrl.da_v = 0;
        }
        DaOutI(I_Contrl.da_v);
    }
}
/****************************************************************************/
//根据电压判断当前要改动的充电状态是否安全
int X_SafeState(int value)
{
    int step;
    if (0 == value)
    {
        return 1;
    }
    step = X_GetChargeState();
    if (0 == step)
    {
        if (0 == GetModuleData(MODULE_JKMK|DATA_DO, 5, 0))
        {//脉冲没有封锁 不能操作
             return 0;
        }

        if (1 == GetModuleData(MODULE_JKMK|DATA_DI, 13, 0))
        {//在停止档 不能操作
             return 0;
        }
        if (1 == value)
        {//希望充电 判断输出电压极性为正 可以充电
            if (Jkmk.ai_v[6] > -50)
                return 1;
            else
                return 0;
        }
        if (2 == value)
        {//希望放电 输出电压极性为负 可以放电
            if (Jkmk.ai_v[6] < -1000)
                return 1;
            else
                return 0;
        }
    }
    else
    {
        if(value == step)
            return 1;
    }
    return 0;
}
/****************************************************************************/
void X_Updata(void)
{
    Cha.v_out       = Jkmk.ai_v[6];         //输出电压
    Cha.i_out       = Jkmk.ai_v[7];         //输出电流
    //根据电池开关状态判断当前电池是 1组或2组
    if (Jkmk.di_v[15])
    {
        //        Cha.v_batt = Jkmk.ai_v[18];
        Cha.i_batt = Jkmk.ai_v[19];
    }
    if (Jkmk.di_v[14])
    {//1组
        //        Cha.v_batt = Jkmk.ai_v[16];
        Cha.i_batt = Jkmk.ai_v[17];
    }
    Cha.i_batt = ABS(Cha.i_batt);
#ifdef HARD_GP
    Cha.i_batt = Jkmk.ai_v[17];
#endif
    //只使用1组电池数据
    Cha.v_batt = Jkmk.ai_v[16];

    Cha.v_ezero     = Jkmk.mk_cfg[64];      //电压调节误差
    Cha.v_lowtohigh = 20; //Jkmk.mk_cfg[65];      //电压调节范围
    Cha.i_ezero     = Jkmk.mk_cfg[66];      //电流调节误差
    Cha.i_max       = Jkmk.mk_cfg[68];      //最大输出电流
    Cha.i_sigzero   = Jkmk.mk_cfg[67];      //SIG零点
    Cha.v_set = Jkmk.ao_cfg[0]; //浮充或均充电压

    if (Cha.i_ezero <= 2)

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -