This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

[参考译文] BQ27427:读取剩余容量

Guru**** 2387080 points
Other Parts Discussed in Thread: BQSTUDIO, BQ27427
请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

https://e2e.ti.com/support/power-management-group/power-management/f/power-management-forum/1338831/bq27427-reading-the-remaining-capacity

器件型号:BQ27427
主题中讨论的其他器件:BQSTUDIO

大家好!

我们已选择此器件用于我们的一个应用。

我们将在 https://thinkrobotics.com/products/16340-battery-3-7v-1300mah?variant=39334535266390上使用这种可充电电池、

我已经使用以下配置初始化电量监测计。

1、化学识别号: 0x1202 (4.2V)

2.设计能力(700mA)

3.设计能耗(2.59 Wh )

我每十秒就会持续读取剩余电量。

问题:

1. 即使施加了一些负载、也能获得恒定的剩余容量值。 但在上电复位后、容量值将减小。

例如: 即使我施加了一些负载、我也能持续获得615 mA 值。  但在上电复位后、剩余容量值减少为600 mA 十六进制

 

2.充电时,剩余容量值会降低。  但在上电复位之后、 剩余的容量值增加。

例如:为 该电池充电时、剩余容量值将从615 mA 十六进制降低  但在上电复位后、 剩余容量值增加到630 mA 十六进制

请提供建议。

此致、

阿斯拉姆

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好、Aslam:  

    您能否为我提供 bqStudio 为此行为获取的日志文件和 gg 文件? 此外、您是否完成了学习循环?  

    此致、  

    Jonny.  

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好、Jhonny:

    我不使用 bqStudio 来配置这些值。 我是直接从控制器发出 I2C 命令。 请在下面找到代码片段:

    void change_chemistry_profile(uint16_t chem_id )
    {
    //unseal the fuel gauge
    gauge_cmd_write(CTRL, UNSEAL_KEY);
    gauge_cmd_write(CTRL, UNSEAL_KEY);
    
    gauge_cfg_update();
    gauge_cmd_write(CTRL,chem_id);
    gauge_exit();
    
    gauge_cmd_write(CTRL, SEAL_KEY);
    
    }
    
    int change_battery_parameters(void)
    {
    uint8_t pData[DC_STATE_LENGTH]; //DC_STATE_LENGTH = 32
    int ret=1;
    //unseal the fuel gauge
    gauge_cmd_write(CTRL, UNSEAL_KEY);
    gauge_cmd_write(CTRL, UNSEAL_KEY);
    
    ret = gauge_read_data_class(DC_STATE, pData, DC_STATE_LENGTH);
    
    pData[6] = (DESIGN_CAPACITY & 0xFF00) >>8;
    pData[7] = DESIGN_CAPACITY & 0xFF;
    pData[8] = (DESIGN_ENERGY & 0xFF00) >>8;
    pData[9] = DESIGN_ENERGY & 0xFF;
    
    gauge_cfg_update(); // required for ROM gauge
    ret = gauge_write_data_class(DC_STATE, pData, DC_STATE_LENGTH);
    gauge_exit(); // required for ROM gauge
    
    // gauge_read_data_class(DC_STATE, pData, DC_STATE_LENGTH);
    
    //seal the fuel gauge
    gauge_cmd_write(CTRL, SEAL_KEY);
    
    return ret;
    }
    
    int gauge_read_data_class(uint8_t nDataClass, uint8_t *pData, uint8_t nLength)
    {
        uint8_t nRemainder = nLength;
        uint16_t nOffset = 0;
        uint8_t nDataBlock = 0x00;
        uint16_t nData;
    
        if (nLength < 1)
            return -1;
    
        do
        {
            nLength = nRemainder;
            if (nLength > 32)
            {
                nRemainder = nLength - 32;
                nLength = 32;
            }
            else nRemainder = 0;
    
            nData = (nDataBlock << 8) | nDataClass;
            gauge_cmd_write(CMD_DATA_CLASS, nData);
    
            //if (hal_i2c_gauge_read(CMD_BLOCK_DATA, pData, nLength) != nLength) return -1;
            hal_i2c_gauge_read(CMD_BLOCK_DATA, pData, nLength);
            pData += nLength;
            nDataBlock++;
        } while (nRemainder > 0);
    
        return 0;
    }
    
    //check_sum: calculate check sum for block transfer
    //pData: pointer to data block
    //nLength: length of data block
    uint8_t check_sum(uint8_t *pData, uint8_t nLength)
    {
        uint8_t nSum = 0x00;
        uint8_t n;
        for (n = 0; n < nLength; n++)
            nSum += pData[n];
        nSum = 0xFF - nSum;
        return nSum;
    }
    
    //gauge_write_data_class: write a data class
    //pHandle: handle to communications adapter
    //nDataClass: data class number
    //pData: buffer holding the whole data class (all blocks)
    //nLength: length of data class (all blocks)
    //return value: 0 = success
    int gauge_write_data_class(uint8_t nDataClass, uint8_t *pData,uint8_t nLength)
    {
        uint8_t nRemainder = nLength;
        uint16_t nOffset = 0;
        uint8_t pCheckSum[2] = {0x00, 0x00};
        uint16_t nData;
        uint8_t nDataBlock = 0x00;
        uint8_t temp_buff[8] = {0};
    
        if (nLength < 1)
            return 0;
    
        do
        {
            nLength = nRemainder;
            if (nLength < 32)
            {
                nRemainder = nLength - 32;
                nLength = 32;
            }
            else nRemainder = 0;
    
           // gauge_cmd_write(0x61, 0x00);  //enable block data memory
            temp_buff[0] = 0x00;
            hal_i2c_gauge_write(0x61,temp_buff,1);
    
           // nData = (nDataBlock << 8) | nDataClass;
            //gauge_cmd_write(CMD_DATA_CLASS, nData); //DataBlockClass() command
            temp_buff[0] = 0x52;
            hal_i2c_gauge_write(CMD_DATA_CLASS,temp_buff,1);
    
            //gauge_cmd_write(0x3F, 0x00);  //block offset location
            temp_buff[0] = 0x00;
            hal_i2c_gauge_write(0x3F,temp_buff,1);
    
           // if (gauge_write(pHandle, CMD_BLOCK_DATA, pData, nLength) != nLength)
             //   return -1;
    
            hal_i2c_gauge_write(CMD_BLOCK_DATA, pData, nLength);
    
            pCheckSum[0] = check_sum(pData, nLength);
            hal_i2c_gauge_write(CMD_CHECK_SUM, pCheckSum, 1);
            usleep(10000);
    
           // gauge_cmd_write(CMD_DATA_CLASS, nData);
            temp_buff[0] = 0x52;
            hal_i2c_gauge_write(CMD_DATA_CLASS,temp_buff,1);
    
            hal_i2c_gauge_read(CMD_CHECK_SUM, pCheckSum + 1, 1);
    
            if (pCheckSum[0] != pCheckSum[1])
                return -2;
            pData += nLength;
            nDataBlock++;
        } while (nRemainder > 0);
    
        return 0;
    }
    
    #define MAX_ATTEMPTS 5
    bool gauge_cfg_update(void)
    {
        uint16_t nFlags;
        int nAttempts = 0;
        gauge_control(SET_CFGUPDATE);
    
        do
        {
            nFlags = gauge_cmd_read(CMD_FLAGS);
            if (!(nFlags & CFGUPD)) usleep(500000);
        } while (!(nFlags & CFGUPD) && (nAttempts++ < MAX_ATTEMPTS));
    
        return (nAttempts < MAX_ATTEMPTS);
    }
    
    //gauge_exit: exit configuration update mode for rom gauges
    //pHandle: handle to communications adapter
    //nSubCmd: sub command to exit configuration update mode
    //return value: true = success, false = failure
    bool gauge_exit(void)
    {
        uint16_t nFlags;
        int nAttempts = 0;
    
        gauge_control(SOFT_RESET);
        do
        {
            nFlags = gauge_cmd_read(CMD_FLAGS);
            if (nFlags & CFGUPD) usleep(500000);
        } while ((nFlags & CFGUPD) && (nAttempts++ <MAX_ATTEMPTS));
    
        return (nAttempts < MAX_ATTEMPTS);
    }

    如果我在每次读取之前重新初始化电量监测计、那么该值会符合预期。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好、Aslam:  

    我怀疑配置有问题。 当电量监测计为 POR 时、电量监测计默认为其默认参数、而不是您编程到电量监测计中的参数。 为了能够进一步调试该情况、我将需要您的配置。  

    此致、  

    Jonny.  

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好、Jhonny:

    在 POR 期间、 电量监测计默认为其默认参数。 这种情况发生正确。 并且我的配置值也会正确更新。 以下是我的配置值:

    1、化学识别号: 0x1202 (4.2V)

    2.设计能力(700mA)

    3.设计能耗(2.59 Wh )

    问题是、在进行任何读取之前必须向电量监测计提供 SOFT_RESET 命令(例如 SOC、剩余容量等)、然后仅能获得正确的值。  

    如果我 在读取之前没有向电量监测计发出 SOFT_RESET 命令、则无法获取正确的值。

    该电量监测计的这种预期行为。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好!  

    配置电量监测计后、使用 SOFT_RESET 子命令退出 CONFIG UPDATE 模式、以恢复正常电量监测。 为了能够对其进行全面调试、我需要使用完整电量监测计配置、与 gg 文件中的配置类似。 此外、chemID 是如何匹配的? 通常、我们建议使用 GPCCHEM 工具、以确保您使用的电池与 bq27427中可选择的三种化学 ID 之一良好匹配。  

    此致、  

    Jonny.  

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    Jonny、您好!

    我仅更改了电量监测计的三个配置值、其他值与默认配置参数相同。  我们根据电池数据表选择了该化学 ID。

     以下是更改后的配置值:

    1、化学识别号: 0x1202 (4.2V)

    2.设计能力(700mA)

    3.设计能耗(2.59 Wh )

    还有任何其他关键电池参数吗?

    我只需要读取电池的 SOC。 我们目前不需要其他功能。

    而且、我们用于该任务的时间也很少。  

    目前、 我需要在进行任何读取之前向电量监测计发出 SOFT_RESET 命令(例如 SOC、剩余容量等)、然后仅获取正确的值。  

    此致、

    阿斯拉姆

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好、Aslam:  

    您需要设置的第一个参数至少列出如下:  

    • 设计容量
    • 充电项收尾电流
    • DSG 电流阈值
    • CHG 电流阈值
    • 停止电流  
    • 术语电压

    此外、您需要成功执行学习周期、请参阅 "成功实现学习周期"文档以了解执行该操作的步骤。 您需要这样做、并确保 ChemID 匹配良好、然后才能参考电量监测计的精度。   

    此致、  

    Jonny.