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.

[参考译文] BQ27421-G1:遵循 TRM 进行配置更新:SoC 和全容量读数为零

Guru**** 2562840 points
Other Parts Discussed in Thread: BQ27426

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

https://e2e.ti.com/support/power-management-group/power-management/f/power-management-forum/1019603/bq27421-g1-following-trm-for-config-update-soc-and-full-capacity-is-reading-zero

器件型号:BQ27421-G1
主题中讨论的其他器件:BQ27426

A

更新完配置部分的满容量后、SOC 和满容量值读数为零。

而电压、电流值是正确的。

配置更新后、读回配置块会正确修改"满容量"字段。

我们非常感谢您在这一问题上提供的任何帮助、请从1周开始尝试。 需要一些线索来进行调试。

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

    葡萄园

    请提供一个日志文件和用于编程的.gm.fs 文件、以帮助进一步调试此问题

    谢谢、

    Eric Vos

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

    e2e.ti.com/.../6014.Fuel_2D00_Guage_5F00_log.log

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

    我不确定为什么标头文件和 c 代码文件无法上传... 这个平台的新功能。。。  

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

    #include "bq27421.h"
    #include "fuel_guage.h"
    #include "i2c.h"
    static uint8_t txdata[16];
    static uint8_t rxdata[16];
    #define I2C_MASTER	    MXC_I2C0_BUS0
    
    #define I2C_SLAVE	    MXC_I2C1_BUS0
    
    #define I2C_SLAVE_ADDR	(0xAB)
    
    #define  HAL_Delay(X)   local_task_sleep_ms(X)
    
    #define HAL_StatusTypeDef int
    int error = 0;
    bool bq27421_i2c_command_write( uint8_t command, uint16_t data )
    {
        HAL_StatusTypeDef ret;
        uint8_t i2c_data[3];
    
        i2c_data[0] = command;
        i2c_data[1] = ( uint8_t )( data & 0x00FF );
        i2c_data[2] = ( uint8_t )( ( data >> 8 ) & 0x00FF );
    
     	if((error = I2C_MasterWrite(I2C_MASTER, I2C_SLAVE_ADDR, i2c_data, 3, 0)) != 3) {
        		printf( "%s:%d Error writing: %d\n", __func__, __LINE__, error);
        }
    
        HAL_Delay( BQ27421_DELAY );
    
        return true;
    
    }
    
    bool bq27421_i2c_command_read( uint8_t command, uint16_t *data )
    {
        HAL_StatusTypeDef ret;
        uint8_t i2c_data[2];
    
     	if((error = I2C_MasterWrite(I2C_MASTER, I2C_SLAVE_ADDR, command, 1, 0)) != 1) {
        		printf( "%s:%d Error writing: %d\n", __func__, __LINE__, error);
        }
        HAL_Delay( BQ27421_DELAY );
    
    	if((error = I2C_MasterRead(I2C_MASTER, I2C_SLAVE_ADDR, i2c_data, 2, 0)) != 2) {
    		printf("%s:%d Error writing: %d\n", __func__, __LINE__, error);
    	}
    
        HAL_Delay( BQ27421_DELAY );
        //printf("%s:%d readVal: 0x%x%x \n", __func__, __LINE__,i2c_data[1], i2c_data[0]);
        *data = ( i2c_data[1] << 8 ) | i2c_data[0];
    
        return true;
    }
    
    bool bq27421_i2c_control_write( uint16_t subcommand )
    {
        HAL_StatusTypeDef ret;
        uint8_t i2c_data[2];
    
        i2c_data[0] = BQ27421_CONTROL_LOW;
        i2c_data[1] = (uint8_t)( ( subcommand ) & 0x00FF );
    
     	if((error = I2C_MasterWrite(I2C_MASTER, I2C_SLAVE_ADDR, i2c_data, 2, 0)) != 2) {
        		printf( "%s:%d Error writing: %d\n", __func__, __LINE__, error);
        }
        //HAL_Delay( BQ27421_DELAY );
    
        i2c_data[0] = BQ27421_CONTROL_HIGH;
        i2c_data[1] = (uint8_t)( ( subcommand >> 8 ) & 0x00FF );
    
     	if((error = I2C_MasterWrite(I2C_MASTER, I2C_SLAVE_ADDR, i2c_data, 2, 0)) != 2) {
        		printf( "%s:%d Error writing: %d\n", __func__, __LINE__, error);
        }
        //HAL_Delay( BQ27421_DELAY );
    
        return true;
    }
    
    bool bq27421_i2c_control_read( uint16_t subcommand, uint16_t *data )
    {
        HAL_StatusTypeDef ret;
        uint8_t i2c_data[2];
    
        i2c_data[0] = BQ27421_CONTROL_LOW;
        i2c_data[1] = (uint8_t)( ( subcommand ) & 0x00FF );
    
     	if((error = I2C_MasterWrite(I2C_MASTER, I2C_SLAVE_ADDR, i2c_data, 2, 0)) != 2) {
        		printf( "%s:%d Error writing: %d\n", __func__, __LINE__, error);
        }
    
        HAL_Delay( BQ27421_DELAY );
    
        i2c_data[0] = BQ27421_CONTROL_HIGH;
        i2c_data[1] = (uint8_t)( ( subcommand >> 8 ) & 0x00FF );
    
     	if((error = I2C_MasterWrite(I2C_MASTER, I2C_SLAVE_ADDR, i2c_data, 2, 0)) != 2) {
        		printf( "%s:%d Error writing: %d\n", __func__, __LINE__, error);
        }
    
        HAL_Delay( BQ27421_DELAY );
    
    	if((error = I2C_MasterRead(I2C_MASTER, I2C_SLAVE_ADDR, i2c_data, 2, 0)) != 2) {
    		printf("%s:%d Error writing: %d\n", __func__, __LINE__, error);
    	}
    
    
        HAL_Delay( BQ27421_DELAY );
    
        *data = ( i2c_data[1] << 8 ) | i2c_data[0];
        printf("%s:%d readVal: 0x%x%x \n", __func__, __LINE__,i2c_data[1], i2c_data[0]);
        return true;
    }
    
    bool bq27421_i2c_write_data_block( uint8_t offset, uint8_t *data, uint8_t bytes )
    {
        HAL_StatusTypeDef ret;
        uint8_t i2c_data[2], i;
    
        for( i = 0; i < bytes; i++ )
        {
            i2c_data[0] = BQ27421_BLOCK_DATA_START + offset + i;
            i2c_data[1] = data[i];
    
         	if((error = I2C_MasterWrite(I2C_MASTER, I2C_SLAVE_ADDR, i2c_data, 2, 0)) != 2) {
            		printf( "%s:%d Error writing: %d\n", __func__, __LINE__, error);
            }
            HAL_Delay( BQ27421_DELAY );
        }
    
        return true;
    }
    
    bool bq27421_i2c_read_data_block( uint8_t offset, uint8_t *data, uint8_t bytes )
    {
        HAL_StatusTypeDef ret;
    
        uint8_t i2c_data;
    
        i2c_data = BQ27421_BLOCK_DATA_START + offset;
    
     	if((error = I2C_MasterWrite(I2C_MASTER, I2C_SLAVE_ADDR, &i2c_data, 1, 0)) != 1) {
        		printf( "%s:%d Error writing: %d\n", __func__, __LINE__, error);
        }
    
        HAL_Delay( 5 );
    
    	if((error = I2C_MasterRead(I2C_MASTER, I2C_SLAVE_ADDR, data, bytes, 0)) != bytes) {
    		printf("%s:%d Error writing: %d\n", __func__, __LINE__, error);
    	}
    
        HAL_Delay( BQ27421_DELAY );
    
        return true;
    }
    
    
    
    bool bq27421_init( uint16_t designCapacity_mAh, uint16_t terminateVoltage_mV, uint16_t taperCurrent_mA )
    {
    
        uint16_t designEnergy_mWh, taperRate, flags, checksumOld, checksumRead;
        uint8_t checksumNew;
    	int ret = 0;
    	uint8_t block[32];
    
        designEnergy_mWh = 3.7 * designCapacity_mAh;
        taperRate = designCapacity_mAh / ( 0.1 * taperCurrent_mA );
        HAL_Delay( 1000 );
        // Unseal gauge
        bq27421_i2c_control_write( BQ27421_CONTROL_UNSEAL );
        bq27421_i2c_control_write( BQ27421_CONTROL_UNSEAL );
        HAL_Delay( 50 );
        // Send CFG_UPDATE
        bq27421_i2c_control_write( BQ27421_CONTROL_SET_CFGUPDATE );
    
        printf("%s:%d Checking  config flag\n", __func__, __LINE__);
        // Poll flags
        int counter = 0;
        do
        {	flags = 0;
            bq27421_i2c_command_read( BQ27421_FLAGS_LOW, &flags );
            if( !(flags & 0x0010) )
            {
                HAL_Delay( 50 );
            }
            counter ++;
            if(counter >= 50){
            	break;
            }
        }
        while( !(flags & 0x0010) );
        printf("%s:%d Flags: 0x%x \n", __func__, __LINE__, flags);
        // Enable Block Data Memory Control
        bq27421_i2c_command_write( BQ27421_BLOCK_DATA_CONTROL, 0x0000 );
    
        HAL_Delay( BQ27421_DELAY );
        printf("%s:%d \n", __func__, __LINE__);
        // Access State subclass
        bq27421_i2c_command_write( BQ27421_DATA_CLASS, 0x0052 );
        printf("%s:%d \n", __func__, __LINE__);
        // Write the block offset
        bq27421_i2c_command_write( BQ27421_DATA_BLOCK, 0x0000 );
    
        // Read block checksum
        bq27421_i2c_command_read( BQ27421_BLOCK_DATA_CHECKSUM, &checksumOld );
        printf("%s:%d CheckSumOld:0x%x\n", __func__, __LINE__, checksumOld);
        // Read 32-byte block of data
    
        for(uint8_t i = 0; i < 32; i++ )
        {
            block[i] = 0x00;
        }
        printf("%s:%d \n", __func__, __LINE__);
        bq27421_i2c_read_data_block( 0x00, block, 32 );
    
        // Calculate checksum
        uint8_t checksumCalc = 0x00;
    
        for(uint8_t i = 0; i < 32; i++ )
        {
            checksumCalc += block[i];
            printf("Block[%d]:%d %x\n", i, block[i], block[i]);
        }
        printf("\n");
        printf("%s:%d Calculated CheckSum: 0x%x \n", __func__, __LINE__, checksumCalc);
        checksumCalc = 0xFF - checksumCalc;
        printf("%s:%d Calculated CheckSum: 0x%x \n", __func__, __LINE__, checksumCalc);
        // Update design capacity
        block[10] = (uint8_t)( designCapacity_mAh >> 8 );
        block[11] = (uint8_t)( designCapacity_mAh & 0x00FF );
        // Update design energy
        block[12] = (uint8_t)( designEnergy_mWh >> 8 );
        block[13] = (uint8_t)( designEnergy_mWh & 0x00FF );
        // Update terminate voltage
    //    block[16] = (uint8_t)( terminateVoltage_mV >> 8 );
    //    block[17] = (uint8_t)( terminateVoltage_mV & 0x00FF );
        // Update taper rate
    //    block[27] = (uint8_t)( taperRate >> 8 );
    //    block[28] = (uint8_t)( taperRate & 0x00FF );
    
        // Calculate new checksum
        checksumNew = 0x00;
        for(int i = 0; i < 32; i++ )
        {
            checksumNew += block[i];
        }
        printf("%s:%d New CheckSum: 0x%x \n", __func__, __LINE__, checksumNew);
        checksumNew = 0xFF - checksumNew;
        printf("%s:%d New CheckSum: 0x%x \n", __func__, __LINE__, checksumNew);
        // Enable Block Data Memory Control
        bq27421_i2c_command_write( BQ27421_BLOCK_DATA_CONTROL, 0x0000 );
    
        HAL_Delay( BQ27421_DELAY );
    
         // Write 32-byte block of updated data
        bq27421_i2c_write_data_block( 0x00, block, 32 );
    
        bq27421_i2c_command_write( BQ27421_BLOCK_DATA_CHECKSUM, checksumNew );
    
    
    
    #if 0
        // Access State subclass
        bq27421_i2c_command_write( BQ27421_DATA_CLASS, 0x0052 );
    
        // Write the block offset
        bq27421_i2c_command_write( BQ27421_DATA_BLOCK, 0x0000 );
    
    
    
    
        // Access State subclass
        bq27421_i2c_command_write( BQ27421_DATA_CLASS, 0x0052 );
    
        // Write the block offset
        bq27421_i2c_command_write( BQ27421_DATA_BLOCK, 0x0000 );
    #endif
        // Read block checksum
        bq27421_i2c_command_read( BQ27421_BLOCK_DATA_CHECKSUM, &checksumRead );
    
        printf("%s:%d checksumRead:0x%x \n", __func__, __LINE__, checksumRead);
        // Verify
        if( checksumRead != (uint8_t)checksumNew )
        {
        	printf("%s:%d CheckSum not matched: checksumRead:0x%x,  wrote:0x%x \n", __func__, __LINE__, checksumRead, checksumNew);
        }
    #if 0
        // Enable Block Data Memory Control
        bq27421_i2c_command_write( BQ27421_BLOCK_DATA_CONTROL, 0x0000 );
    
        HAL_Delay( BQ27421_DELAY );
    
        // Access Registers subclass
        bq27421_i2c_command_write( BQ27421_DATA_CLASS, 0x0040 );
    
        // Write the block offset
        bq27421_i2c_command_write( BQ27421_DATA_BLOCK, 0x0000 );
    
        // Read block checksum
        bq27421_i2c_command_read( BQ27421_BLOCK_DATA_CHECKSUM, &checksumOld );
    
        // Read 32-byte block of data
        for(uint8_t i = 0; i < 32; i++ )
        {
            block[i] = 0x00;
        }
    
        bq27421_i2c_read_data_block( 0x00, block, 32 );
    
        // Calculate checksum
        checksumCalc = 0x00;
    
        for(uint8_t i = 0; i < 32; i++ )
        {
            checksumCalc += block[i];
        }
        checksumCalc = 0xFF - checksumCalc;
        printf("%s:%d calculated CheckSum: 0x%x , checksumRead:0x%x \n", __func__, __LINE__, checksumCalc, checksumRead);
        // Update OpConfig
        block[0] = 0x05;
    
        // Calculate new checksum
        checksumNew = 0x00;
        for(int i = 0; i < 32; i++ )
        {
            checksumNew += block[i];
        }
        checksumNew = 0xFF - checksumNew;
    
        // Enable Block Data Memory Control
        bq27421_i2c_command_write( BQ27421_BLOCK_DATA_CONTROL, 0x0000 );
    
        HAL_Delay( BQ27421_DELAY );
    
        // Access Registers subclass
        bq27421_i2c_command_write( BQ27421_DATA_CLASS, 0x0040 );
    
        // Write the block offset
        bq27421_i2c_command_write( BQ27421_DATA_BLOCK, 0x0000 );
    
        // Write 32-byte block of updated data
        bq27421_i2c_write_data_block( 0x00, block, 32 );
    
        // Write new checksum
        bq27421_i2c_command_write( BQ27421_BLOCK_DATA_CHECKSUM, checksumNew );
    
        // Access Registers subclass
        bq27421_i2c_command_write( BQ27421_DATA_CLASS, 0x0040 );
    
        // Write the block offset
        bq27421_i2c_command_write( BQ27421_DATA_BLOCK, 0x0000 );
    
        // Read block checksum
        bq27421_i2c_command_read( BQ27421_BLOCK_DATA_CHECKSUM, &checksumRead );
    
        // Verify
        if( checksumRead != (uint8_t)checksumNew )
        {
            //return false;
        }
    #endif
        // Configure BAT_DET
        bq27421_i2c_control_write( BQ27421_CONTROL_BAT_INSERT );
    
        // Send Soft Reset
        bq27421_i2c_control_write( BQ27421_CONTROL_SOFT_RESET );
    printf("FG Soft Reset \n");
        // Poll flags
        do
        {
            bq27421_i2c_command_read( BQ27421_FLAGS_LOW, &flags );
            if( !(flags & 0x0010) )
            {
                HAL_Delay( 50 );
            }
        }
        while( (flags & 0x0010) );
        printf("FG Seal Gauge: flag:%x \n", flags);
        // Seal gauge
        bq27421_i2c_control_write( BQ27421_CONTROL_SEALED );
    
        HAL_Delay( 1000 );
        bq27421_i2c_control_write( BQ27421_CONTROL_SOFT_RESET );
        HAL_Delay( 1000 );
    #if 1
    	bq27421_readDeviceFWver(&ret);
    	printf("DEVICE FIRMWARE: %x \n", ret);
    	bq27421_readDeviceType(&ret);
    	printf("DEVICE TYPE: %x \n", ret);
    	checksumOld = 0;
        bq27421_i2c_command_read( BQ27421_BLOCK_DATA_CHECKSUM, &checksumOld );
        printf("%s:%d CheckSumOld:0x%x\n", __func__, __LINE__, checksumOld);
    
        for(uint8_t i = 0; i < 32; i++ )
        {
            block[i] = 0x00;
        }
        bq27421_i2c_read_data_block( 0x00, block, 32 );
        for(uint8_t i = 0; i < 32; i++ )
        {
            printf("Block[%d]:%d - %x\n", i, block[i], block[i]);
        }
        printf("\n");
       // printf("Design Capacity: %x , %d \n", ret, ret);
    
    #endif
    
    
        return true;
    }
    
    bool bq27421_update( bq27421_info *battery )
    {
        uint16_t temp;
    
        if( !bq27421_readVoltage_mV( &(battery->voltage_mV) ) )
        {
            return false;
        }
        if( !bq27421_readAvgCurrent_mA( &(battery->current_mA) ) )
        {
            return false;
        }
        if( !bq27421_readTemp_degK( &temp ) )
        {
            return false;
        }
        battery->temp_degC = ( (double)temp / 10 ) - 273.15;
    
        if( !bq27421_readStateofCharge_percent( &(battery->soc_percent) ) )
        {
            return false;
        }
        if( !bq27421_readStateofHealth_percent( &(battery->soh_percent) ) )
        {
            return false;
        }
        if( !bq27421_readDesignCapacity_mAh( &(battery->designCapacity_mAh) ) )
        {
            return false;
        }
        if( !bq27421_readRemainingCapacity_mAh( &(battery->remainingCapacity_mAh) ) )
        {
            return false;
        }
        if( !bq27421_readFullChargeCapacity_mAh( &(battery->fullChargeCapacity_mAh) ) )
        {
            return false;
        }
        if( !bq27421_readFlagsReg( &temp ) )
        {
            return false;
        }
        battery->isCritical = temp & 0x0002;
        battery->isLow = temp & 0x0004;
        battery->isFull = temp & 0x0200;
        if( battery->current_mA <= 0 )
        {
            battery->isDischarging = 1;
            battery->isCharging = 0;
        }
        else
        {
            battery->isDischarging = 0;
            battery->isCharging = 1;
        }
    
        return true;
    }
    
    bool bq27421_readDeviceType( uint16_t *deviceType )
    {
        if( !bq27421_i2c_control_write( BQ27421_CONTROL_DEVICE_TYPE ) )
        {
            return false;
        }
        if( !bq27421_i2c_command_read( BQ27421_CONTROL_LOW, deviceType ) )
        {
            return false;
        }
    
        return true;
    }
    
    bool bq27421_readDeviceFWver( uint16_t *deviceFWver )
    {
        if( !bq27421_i2c_control_write( BQ27421_CONTROL_FW_VERSION ) )
        {
            return false;
        }
        if( !bq27421_i2c_command_read( BQ27421_CONTROL_LOW, deviceFWver ) )
        {
            return false;
        }
    
        return true;
    }
    
    bool bq27421_readDesignCapacity_mAh( uint16_t *capacity_mAh )
    {
        if( !bq27421_i2c_command_read( BQ27421_DESIGN_CAP_LOW, capacity_mAh ) )
        {
            return false;
        }
    
        return true;
    }
    
    bool bq27421_readVoltage_mV( uint16_t *voltage_mV )
    {
        if( !bq27421_i2c_command_read( BQ27421_VOLTAGE_LOW, voltage_mV ) )
        {
            return false;
        }
    
        return true;
    }
    
    bool bq27421_readTemp_degK( uint16_t *temp_degKbyTen )
    {
        if( !bq27421_i2c_command_read( BQ27421_TEMP_LOW, temp_degKbyTen ) )
        {
            return false;
        }
    
        return true;
    }
    
    bool bq27421_readAvgCurrent_mA( int16_t *avgCurrent_mA )
    {
        if( !bq27421_i2c_command_read( BQ27421_AVG_CURRENT_LOW, (uint16_t *)avgCurrent_mA ) )
        {
            return false;
        }
    
        return true;
    }
    
    bool bq27421_readStateofCharge_percent( uint16_t *soc_percent )
    {
        if( !bq27421_i2c_command_read( BQ27421_STATE_OF_CHARGE_LOW, soc_percent ) )
        {
            return false;
        }
    
        return true;
    }
    
    bool bq27421_readControlReg( uint16_t *control )
    {
        if( !bq27421_i2c_control_write( BQ27421_CONTROL_STATUS ) )
        {
            return false;
        }
        if( !bq27421_i2c_command_read( BQ27421_CONTROL_LOW, control ) )
        {
            return false;
        }
    
        return true;
    }
    
    bool bq27421_readFlagsReg( uint16_t *flags )
    {
        if( !bq27421_i2c_command_read( BQ27421_FLAGS_LOW, flags ) )
        {
            return false;
        }
    
        return true;
    }
    
    bool bq27421_readopConfig( uint16_t *opConfig )
    {
        if( !bq27421_i2c_command_read( BQ27421_OPCONFIG_LOW, opConfig ) )
        {
            return false;
        }
    
        return true;
    }
    
    bool bq27421_readRemainingCapacity_mAh( uint16_t *capacity_mAh )
    {
        if( !bq27421_i2c_command_read( BQ27421_REMAINING_CAP_LOW, capacity_mAh ) )
        {
            return false;
        }
    
        return true;
    }
    
    bool bq27421_readFullChargeCapacity_mAh( uint16_t *capacity_mAh )
    {
        if( !bq27421_i2c_command_read( BQ27421_FULL_CHARGE_CAP_LOW, capacity_mAh ) )
        {
            return false;
        }
    
        return true;
    }
    
    bool bq27421_readStateofHealth_percent( uint16_t *soh_percent )
    {
        if( !bq27421_i2c_command_read( BQ27421_STATE_OF_HEALTH_LOW, soh_percent ) )
        {
            return false;
        }
    
        *soh_percent = *soh_percent & 0x00FF;
    
        return true;
    }
    
    static int16_t fg_currentmA(){
    
    	txdata[0] = COMMAND_CURRENT_MA; //cmd
    	if((error = I2C_MasterWrite(I2C_MASTER, I2C_SLAVE_ADDR, txdata, 1, 0)) != 1) {
    		printf_log(LOG_ERROR, "%s:%d Error writing: %d\n", __func__, __LINE__, error);
    	}
    
    	memset(rxdata, 0, sizeof(rxdata));
    	if((error = I2C_MasterRead(I2C_MASTER, I2C_SLAVE_ADDR, rxdata, 2, 0)) != 2) {
    		printf_log(LOG_ERROR, "%s:%d Error writing: %d\n", __func__, __LINE__, error);
    	}
    	return ((rxdata[0] & 0xFF) | (rxdata[1] << 8));
    }
    
    static int16_t getVoltage(){
    	txdata[0] = COMMAND_VOLTAGE; //cmd
    	if((error = I2C_MasterWrite(I2C_MASTER, I2C_SLAVE_ADDR, txdata, 1, 0)) != 1) {
    		printf_log(LOG_ERROR, "%s:%d Error writing: %d\n", __func__, __LINE__, error);
    	}
    
    	memset(rxdata, 0, sizeof(rxdata));
    	if((error = I2C_MasterRead(I2C_MASTER, I2C_SLAVE_ADDR, rxdata, 2, 0)) != 2) {
    		printf_log(LOG_ERROR, "%s:%d Error writing: %d\n", __func__, __LINE__, error);
    	}
    	return ((rxdata[0] & 0xFF) | (rxdata[1] << 8));
    }
    
    static uint16_t fg_remainingChargingCapacity()
    {
    	txdata[0] = COMMAND_REMAINING_CHARGING_CAPACITY; //cmd
    	if((error = I2C_MasterWrite(I2C_MASTER, I2C_SLAVE_ADDR, txdata, 1, 0)) != 1) {
    		printf_log(LOG_ERROR, "%s:%d Error writing: %d\n", __func__, __LINE__, error);
    	}
    
    	memset(rxdata, 0, sizeof(rxdata));
    	if((error = I2C_MasterRead(I2C_MASTER, I2C_SLAVE_ADDR, rxdata, 2, 0)) != 2) {
    		printf_log(LOG_ERROR, "%s:%d Error writing: %d\n", __func__, __LINE__, error);
    	}
    	//printf("REMAINING CAPCITY mA : %d %d \n", rxdata[0], rxdata[1]);
    	return ((rxdata[0] & 0xFF) | (rxdata[1] << 8));
    }
    static uint16_t fg_fullChargeCapacity(){
    
    	txdata[0] = COMMAND_FULL_CHARGE_CAPACITY; //cmd
    	if((error = I2C_MasterWrite(I2C_MASTER, I2C_SLAVE_ADDR, txdata, 1, 0)) != 1) {
    		printf_log(LOG_ERROR, "%s:%d Error writing: %d\n", __func__, __LINE__, error);
    	}
    
    	memset(rxdata, 0, sizeof(rxdata));
    	if((error = I2C_MasterRead(I2C_MASTER, I2C_SLAVE_ADDR, rxdata, 2, 0)) != 2) {
    		printf_log(LOG_ERROR, "%s:%d Error writing: %d\n", __func__, __LINE__, error);
    	}
    	printf_log(LOG_DEBUG, "FULL CHARGE CAPCITY mA: %d %d \n", rxdata[0], rxdata[1]);
    	return ((rxdata[0] & 0xFF) | (rxdata[1] << 8));
    }
    
    static uint16_t fg_soc(){
    
    	txdata[0] = 0x1C; //cmd
    	if((error = I2C_MasterWrite(I2C_MASTER, I2C_SLAVE_ADDR, txdata, 1, 0)) != 1) {
    		printf_log(LOG_ERROR, "%s:%d Error writing: %d\n", __func__, __LINE__, error);
    	}
    
    	memset(rxdata, 0, sizeof(rxdata));
    	if((error = I2C_MasterRead(I2C_MASTER, I2C_SLAVE_ADDR, rxdata, 2, 0)) != 2) {
    		printf_log(LOG_ERROR, "%s:%d Error writing: %d\n", __func__, __LINE__, error);
    	}
    	printf_log(LOG_DEBUG, "FULL CHARGE CAPCITY mA: %d %d \n", rxdata[0], rxdata[1]);
    	return ((rxdata[0] & 0xFF) | (rxdata[1] << 8));
    }
    
    void fg_print_data(){
    	printf("\nCapacity->FULL:%d\tRemaining:%d\n",fg_fullChargeCapacity(), fg_remainingChargingCapacity());
    	printf("Voltage:%d\tCurrent:%d\tSOC:%d\n", getVoltage(), fg_currentmA(), fg_soc());
    	printf("Percentage:%d \n", getBatteryPercentage());
    }
    
    
    void new_fg_init()
    {
    	printf("SLAVE Address : %x \n", BQ27421_I2C_ADDRESS);
    	bq27421_init(200, 3000, 80);
    	printf("fg_init done \n");
    }
    
    #ifndef CODE_CORE0_SOURCE_DRIVER_FUEL_GUAGE_BQ27421_H_
    #define CODE_CORE0_SOURCE_DRIVER_FUEL_GUAGE_BQ27421_H_
    #include <stdbool.h>
    #include <stdint.h>
    #define HAL_BQ27421_TIMEOUT                 5
    #define BQ27421_DELAY                       1
    
    #define BQ27421_I2C_ADDRESS                 0xAA
    
    #define BQ27421_CONTROL_LOW                 0x00
    #define BQ27421_CONTROL_HIGH                0x01
    #define BQ27421_TEMP_LOW                    0x02
    #define BQ27421_TEMP_HIGH                   0x03
    #define BQ27421_VOLTAGE_LOW                 0x04
    #define BQ27421_VOLTAGE_HIGH                0x05
    #define BQ27421_FLAGS_LOW                   0x06
    #define BQ27421_FLAGS_HIGH                  0x07
    #define BQ27421_NOM_AVAILABLE_CAP_LOW       0x08
    #define BQ27421_NOM_AVAILABLE_CAP_HIGH      0x09
    #define BQ27421_FULL_AVAILABLE_CAP_LOW      0x0A
    #define BQ27421_FULL_AVAILABLE_CAP_HIGH     0x0B
    #define BQ27421_REMAINING_CAP_LOW           0x0C
    #define BQ27421_REMAINING_CAP_HIGH          0x0D
    #define BQ27421_FULL_CHARGE_CAP_LOW         0x0E
    #define BQ27421_FULL_CHARGE_CAP_HIGH        0x0F
    #define BQ27421_AVG_CURRENT_LOW             0x10
    #define BQ27421_AVG_CURRENT_HIGH            0x11
    #define BQ27421_STANDBY_CURRENT_LOW         0x12
    #define BQ27421_STANDBY_CURRENT_HIGH        0x13
    #define BQ27421_MAX_LOAD_CURRENT_LOW        0x14
    #define BQ27421_MAX_LOAD_CURRENT_HIGH       0x15
    #define BQ27421_AVG_POWER_LOW               0x18
    #define BQ27421_AVG_POWER_HIGH              0x19
    #define BQ27421_STATE_OF_CHARGE_LOW         0x1C
    #define BQ27421_STATE_OF_CHARGE_HIGH        0x1D
    #define BQ27421_INT_TEMP_LOW                0x1E
    #define BQ27421_INT_TEMP_HIGH               0x1F
    #define BQ27421_STATE_OF_HEALTH_LOW         0x20
    #define BQ27421_STATE_OF_HEALTH_HIGH        0x21
    #define BQ27421_REMAINING_CAP_UNFILT_LOW    0x28
    #define BQ27421_REMAINING_CAP_UNFILT_HIGH   0x29
    #define BQ27421_REMAINING_CAP_FILT_LOW      0x2A
    #define BQ27421_REMAINING_CAP_FILT_HIGH     0x2B
    #define BQ27421_FULL_CHARGE_UNFILT_CAP_LOW  0x2C
    #define BQ27421_FULL_CHARGE_UNFILT_CAP_HIGH 0x2D
    #define BQ27421_FULL_CHARGE_FILT_CAP_LOW    0x2E
    #define BQ27421_FULL_CHARGE_FILT_CAP_HIGH   0x2F
    #define BQ27421_STATE_OF_CHARGE_UNFILT_LOW  0x30
    #define BQ27421_STATE_OF_CHARGE_UNFILT_HIGH 0x31
    #define BQ27421_OPCONFIG_LOW                0x3A
    #define BQ27421_OPCONFIG_HIGH               0x3B
    #define BQ27421_DESIGN_CAP_LOW              0x3C
    #define BQ27421_DESIGN_CAP_HIGH             0x3D
    #define BQ27421_DATA_CLASS                  0x3E
    #define BQ27421_DATA_BLOCK                  0x3F
    #define BQ27421_BLOCK_DATA_START            0x40
    #define BQ27421_BLOCK_DATA_END              0x5F
    #define BQ27421_BLOCK_DATA_CHECKSUM         0x60
    #define BQ27421_BLOCK_DATA_CONTROL          0x61
    
    #define BQ27421_CONTROL_STATUS              0x0000
    #define BQ27421_CONTROL_DEVICE_TYPE         0x0001
    #define BQ27421_CONTROL_FW_VERSION          0x0002
    #define BQ27421_CONTROL_DM_CODE             0x0004
    #define BQ27421_CONTROL_PREV_MACWRITE       0x0007
    #define BQ27421_CONTROL_CHEM_ID             0x0008
    #define BQ27421_CONTROL_BAT_INSERT          0x000C
    #define BQ27421_CONTROL_BAT_REMOVE          0x000D
    #define BQ27421_CONTROL_SET_HIBERNATE       0x0011
    #define BQ27421_CONTROL_CLEAR_HIBERNATE     0x0012
    #define BQ27421_CONTROL_SET_CFGUPDATE       0x0013
    #define BQ27421_CONTROL_SHUTDOWN_ENABLE     0x001B
    #define BQ27421_CONTROL_SHUTDOWN            0x001C
    #define BQ27421_CONTROL_SEALED              0x0020
    #define BQ27421_CONTROL_TOGGLE_GPOUT        0x0023
    #define BQ27421_CONTROL_RESET               0x0041
    #define BQ27421_CONTROL_SOFT_RESET          0x0042
    #define BQ27421_CONTROL_EXIT_CFGUPDATE      0x0043
    #define BQ27421_CONTROL_EXIT_RESIM          0x0044
    #define BQ27421_CONTROL_UNSEAL              0x8000
    
    #define 	FUEL_GUAGE_TIMER_MS				3000
    
    #define FG_BATTERY_CHARGER_CUT_VOLTAGE			4195
    #define FG_BATTERY_CHARGER_PLUG_VOLTAGE			4000
    #define FG_BATTERY_SHUTDOWN_VOLTAGE				3000
    
    enum{
    	CHARGER_NOT_CONNECTED = 0,
    	CHARGER_CONNECTED
    };
    
    #define COMMAND_DESIGN_CAPACITY						0x3C
    
    #define COMMAND_REMAINING_CAPACITY_UNFILTERED		0x28
    #define COMMAND_REMAINING_CAPACITY_FILTERED			0x2A
    
    #define	COMMAND_FULL_CAPACITY_FILTERED				0x2E
    #define	COMMAND_FULL_CAPACITY_UNFILTERED			0x2C
    
    #define COMMAND_REMAINING_CHARGING_CAPACITY			0x0C
    #define COMMAND_CURRENT_MA							0x10
    #define COMMAND_FULL_CHARGE_CAPACITY				0x0E
    #define COMMAND_VOLTAGE								0x04
    
    
    typedef struct
    {
        uint16_t    voltage_mV;
        int16_t     current_mA;
        double      temp_degC;
        uint16_t    soc_percent;
        uint16_t    soh_percent;
        uint16_t    designCapacity_mAh;
        uint16_t    remainingCapacity_mAh;
        uint16_t    fullChargeCapacity_mAh;
    
        bool        isCritical;
        bool        isLow;
        bool        isFull;
        bool        isCharging;
        bool        isDischarging;
    } bq27421_info;
    
    bool bq27421_init( uint16_t designCapacity_mAh, uint16_t terminateVoltage_mV, uint16_t taperCurrent_mA );
    bool bq27421_update( bq27421_info *battery );
    bool bq27421_readDeviceType( uint16_t *deviceType );
    bool bq27421_readDeviceFWver( uint16_t *deviceFWver );
    bool bq27421_readDesignCapacity_mAh( uint16_t *capacity_mAh );
    
    bool bq27421_readVoltage_mV( uint16_t *voltage_mV );
    bool bq27421_readTemp_degK( uint16_t *temp_degKbyTen );
    bool bq27421_readAvgCurrent_mA( int16_t *avgCurrent_mA );
    bool bq27421_readStateofCharge_percent( uint16_t *soc_percent );
    
    bool bq27421_readControlReg( uint16_t *control );
    bool bq27421_readFlagsReg( uint16_t *flags );
    bool bq27421_readopConfig( uint16_t *opConfig );
    bool bq27421_readRemainingCapacity_mAh( uint16_t *capacity_mAh );
    bool bq27421_readFullChargeCapacity_mAh( uint16_t *capacity_mAh );
    bool bq27421_readStateofHealth_percent( uint16_t *soh_percent );
    
    bool bq27421_i2c_command_write( uint8_t command, uint16_t data );
    bool bq27421_i2c_command_read( uint8_t command, uint16_t *data );
    
    bool bq27421_i2c_control_write( uint16_t subcommand );
    bool bq27421_i2c_control_read( uint16_t subcommand, uint16_t *data );
    bool bq27421_i2c_write_data_block( uint8_t offset, uint8_t *data, uint8_t bytes );
    bool bq27421_i2c_read_data_block( uint8_t offset, uint8_t *data, uint8_t bytes );
    
    #endif /* CODE_CORE0_SOURCE_DRIVER_FUEL_GUAGE_BQ27421_H_ */
    

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

    我们没有用于研究和调试代码的带宽、但我们可以回答有关监测计配置的问题。 该监测计的快速入门指南介绍了需要配置哪些参数才能获得准确的结果。 请访问: https://www.ti.com/lit/ug/sluubn3/sluubn3.pdf

    简而言之:您必须配置一些参数、以告诉监测计您的系统和电池的基本特性:

    *充电终止设置(通过锥率)、以便监测计了解100%相对充电的条件
    *放电终止设置(终止电压)-定义相对充电状态何时为0%
    *设计容量和能源-以便电量监测计了解该特定电池可以存储的电量
    *选择适当的化学成分

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

    谢谢、Dominik、我将介绍 pdf 和建议、
    本用户指南适用于 bq27426 、我使用的是 bq27421电量监测计、希望与编程方面毫无区别

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

    bq27421和 bq27426非常接近。 我们提供了 bq27421的快速入门指南: www.ti.com/.../sluuah7b.pdf