为什么我在fg_rk817.c中添加以下函数,会导致rsoc清零,并且每次充电就会清零,如何避免这种情况?

为什么我在fg_rk817.c中添加以下函数,会导致rsoc清零,并且每次充电就会清零,如何避免这种情况,我只需要在判断条件成立的情况下,更新dsoc的值,因为我的dsoc偶尔会卡在90以下,导致我的电量充不满

/*电池测试*/
/*
static void rk817_bat_battery_check(struct rk817_battery_device *battery)
{
    int   vol, is_charge, pre_cap, now_cap;
    vol = rk817_bat_get_battery_voltage(battery);
    pre_cap = rk817_bat_get_prev_cap(battery);
    now_cap = rk817_bat_get_capacity_mah(battery);
    if (now_cap > pre_cap) {
        is_charge = 1;
    } else {
        is_charge = 0;
    }
    if(is_charge){
    if(battery->dsoc<90000 && vol >= 4100){
            int new_soc = rk817_bat_get_rsoc(battery);
            battery->dsoc = new_soc;
            rk817_bat_save_dsoc(battery, battery->dsoc);
           }
    //}
    }
}

初始化代码如下


static int rk817_fg_init(struct rk817_battery_device *battery)
{
    int value;

    value = rk817_bat_read(battery, GG_CON);
    rk817_bat_write(battery, GG_CON, value | VOL_OUPUT_INSTANT_MODE);
    if (battery->variant == RK817_ID) {
        value =  rk817_bat_read(battery, BAT_DISCHRG);
        rk817_bat_write(battery, BAT_DISCHRG, value & (~DIS_ILIM_EN));
    }
    rk817_bat_gas_gaugle_enable(battery);
    rk817_bat_init_voltage_kb(battery);
    rk817_bat_calibration(battery);
    rk817_bat_rsoc_init(battery);
    rk817_bat_battery_check(battery);
    rk817_bat_init_coulomb_cap(battery, battery->nac);
    rk817_bat_set_initialized_flag(battery);
    

    battery->voltage_avg = rk817_bat_get_battery_voltage(battery);
    battery->voltage_sys = rk817_bat_get_sys_voltage(battery);
    battery->voltage_usb = rk817_bat_get_USB_voltage(battery);
    battery->current_avg = rk817_bat_get_avg_current(battery);
    battery->current_pwron = rk817_bat_get_pwron_current(battery);
    battery->remain_cap = rk817_bat_get_capacity_uah(battery);
    battery->rsoc = rk817_bat_get_rsoc(battery);
    battery->sm_linek = rk817_bat_calc_linek(battery);
    battery->chrg_type = rk817_bat_get_charger_type(battery);
    battery->finish_chrg_base = get_timer(0);
    battery->term_sig_base = get_timer(0);

    battery->dbg_pwr_dsoc = battery->dsoc;
    battery->dbg_pwr_rsoc = battery->rsoc;
    battery->dbg_pwr_vol = battery->voltage_avg;

    if (battery->variant == RK817_ID)
        rk817_bat_charger_setting(battery, battery->chrg_type);

    DBG("voltage_k = %d, voltage_b = %d\n",
        battery->voltage_k, battery->voltage_b);
    DBG("voltage_sys = %d\n", battery->voltage_sys);
    DBG("voltage usb: %d\n", battery->voltage_avg);
    DBG("battery: %d\n", battery->voltage_avg);
    DBG("current_avg = %d\n", battery->current_avg);
    DBG("current_pwron = %d\n", battery->current_pwron);
    DBG("remain_cap = %d\n", battery->remain_cap);
    DBG("fcc = %d\n", battery->fcc);
    DBG("qmax = %d\n", battery->qmax);
    DBG("dsoc = %d\n", battery->dsoc);
    DBG("rsoc = %d\n", battery->rsoc);
    DBG("charge type: %d\n", battery->chrg_type);

    return 0;
}


【以下回答由 GPT 生成】

针对你的问题,我会做出以下回答和建议:

首先,通过对你给出的代码进行分析,我发现在rk817_fg_init函数中调用了rk817_bat_battery_check函数,而在rk817_bat_battery_check函数中更新了battery->dsoc的值。这就解释了为什么每次充电后rsoc都会被清零。

要解决这个问题,你可以尝试以下操作:

  1. rk817_bat_battery_check函数的调用从rk817_fg_init函数中移除。这样就不会在初始化时更新battery->dsoc的值。
  2. 在你希望更新dsoc值的特定条件下,手动调用rk817_bat_battery_check函数,而不是在初始化代码中调用。你可以根据你的需求将其放在合适的位置。

下面是代码示例:

static int rk817_fg_init(struct rk817_battery_device *battery)
{
    int value;

    value = rk817_bat_read(battery, GG_CON);
    rk817_bat_write(battery, GG_CON, value | VOL_OUPUT_INSTANT_MODE);
    if (battery->variant == RK817_ID) {
        value =  rk817_bat_read(battery, BAT_DISCHRG);
        rk817_bat_write(battery, BAT_DISCHRG, value & (~DIS_ILIM_EN));
    }
    rk817_bat_gas_gaugle_enable(battery);
    rk817_bat_init_voltage_kb(battery);
    rk817_bat_calibration(battery);
    rk817_bat_rsoc_init(battery);
    rk817_bat_init_coulomb_cap(battery, battery->nac);
    rk817_bat_set_initialized_flag(battery);


    battery->voltage_avg = rk817_bat_get_battery_voltage(battery);
    battery->voltage_sys = rk817_bat_get_sys_voltage(battery);
    battery->voltage_usb = rk817_bat_get_USB_voltage(battery);
    battery->current_avg = rk817_bat_get_avg_current(battery);
    battery->current_pwron = rk817_bat_get_pwron_current(battery);
    battery->remain_cap = rk817_bat_get_capacity_uah(battery);
    battery->rsoc = rk817_bat_get_rsoc(battery);
    battery->sm_linek = rk817_bat_calc_linek(battery);
    battery->chrg_type = rk817_bat_get_charger_type(battery);
    battery->finish_chrg_base = get_timer(0);
    battery->term_sig_base = get_timer(0);

    battery->dbg_pwr_dsoc = battery->dsoc;

    // 在需要更新dsoc值的条件下手动调用rk817_bat_battery_check函数
    if (condition) {
        rk817_bat_battery_check(battery);
    }

    // ...
}

你需要根据你的具体需求来确定在什么条件下调用rk817_bat_battery_check函数。这样,你就可以避免在每次充电后清零rsoc的问题。

希望这个解决方案能帮助到你。如果你有任何进一步的问题,请随时提问。


如果你已经解决了该问题, 非常希望你能够分享一下解决方案, 写成博客, 将相关链接放在评论区, 以帮助更多的人 ^-^

引用 皆我百晓生 小程序回复内容作答:
根据你提供的代码,可以看出在rk817_fg_init()函数中,每次初始化电池时都会执行rk817_bat_battery_check()函数。而在rk817_bat_battery_check()函数中,当电池处于充电状态且电量小于90000时会更新dsoc的值并保存到存储器中。

这导致了每次充电时都会更新dsoc值并保存到存储器中,即每次充电都会导致电量清零的情况。

要避免这种情况,你可以考虑将rk817_bat_battery_check()函数的调用放在需要更新dsoc值的地方,而不是在每次初始化电池时都调用。只有当判断条件成立时,才调用该函数更新dsoc值。这样就可以避免每次充电都会清零的问题。

以下是修改建议:

  1. 将rk817_bat_battery_check()函数的代码段移动到需要更新dsoc值的位置,并将其调用条件设置为充电状态和电量小于90000的情况。
  2. 移除rk817_bat_battery_check()函数在rk817_fg_init()函数中的调用。

修改代码示例:

/*电池测试*/
static void rk817_bat_battery_check(struct rk817_battery_device *battery)
{
    int vol, is_charge;
    vol = rk817_bat_get_battery_voltage(battery);
    if (is_charge) {
        if (battery->dsoc < 90000 && vol >= 4100) {
            int new_soc = rk817_bat_get_rsoc(battery);
            battery->dsoc = new_soc;
            rk817_bat_save_dsoc(battery, battery->dsoc);
        }
    }
}

static int rk817_fg_init(struct rk817_battery_device *battery)
{
    int value;
 
    value = rk817_bat_read(battery, GG_CON);
    rk817_bat_write(battery, GG_CON, value | VOL_OUPUT_INSTANT_MODE);
    if (battery->variant == RK817_ID) {
        value =  rk817_bat_read(battery, BAT_DISCHRG);
        rk817_bat_write(battery, BAT_DISCHRG, value & (~DIS_ILIM_EN));
    }
    rk817_bat_gas_gaugle_enable(battery);
    rk817_bat_init_voltage_kb(battery);
    rk817_bat_calibration(battery);
    rk817_bat_rsoc_init(battery);
    rk817_bat_init_coulomb_cap(battery, battery->nac);
    rk817_bat_set_initialized_flag(battery);
    
    battery->voltage_avg = rk817_bat_get_battery_voltage(battery);
    battery->voltage_sys = rk817_bat_get_sys_voltage(battery);
    battery->voltage_usb = rk817_bat_get_USB_voltage(battery);
    battery->current_avg = rk817_bat_get_avg_current(battery);
    battery->current_pwron = rk817_bat_get_pwron_current(battery);
    battery->remain_cap = rk817_bat_get_capacity_uah(battery);
    battery->rsoc = rk817_bat_get_rsoc(battery);
    battery->sm_linek = rk817_bat_calc_linek(battery);
    battery->chrg_type = rk817_bat_get_charger_type(battery);
    battery->finish_chrg_base = get_timer(0);
    battery->term_sig_base = get_timer(0);
 
    battery->dbg_pwr_dsoc = battery->dsoc;
    battery->dbg_pwr_rsoc = battery->rsoc;
    battery->dbg_pwr_vol = battery->voltage_avg;
 
    if (battery->variant == RK817_ID)
        rk817_bat_charger_setting(battery, battery->chrg_type);
 
    DBG("voltage_k = %d, voltage_b = %d\n",
        battery->voltage_k, battery->voltage_b);
    DBG("voltage_sys = %d\n", battery->voltage_sys);
    DBG("voltage usb: %d\n", battery->voltage_avg);
    DBG("battery: %d\n", battery->voltage_avg);
    DBG("current_avg = %d\n", battery->current_avg);
    DBG("current_pwron = %d\n", battery->current_pwron);
    DBG("remain_cap = %d\n", battery->remain_cap);
    DBG("fcc = %d\n", battery->fcc);
    DBG("qmax = %d\n", battery->qmax);
    DBG("dsoc = %d\n", battery->dsoc);
    DBG("rsoc = %d\n", battery->rsoc);
    DBG("charge type: %d\n", battery->chrg_type);
 
    // 调用rk817_bat_battery_check()函数并更新dsoc值
    int vol = rk817_bat_get_battery_voltage(battery);
    if (battery->dsoc < 90000 && vol >= 4100) {
        rk817_bat_battery_check(battery);
    }
 
    return 0;
}

通过以上修改,你可以在需要更新dsoc值的条件下调用rk817_bat_battery_check()函数,并避免每次充电都会清零的情况。请根据你的需求和代码逻辑进行相应的调整。