BQ27441-G1: 匹配化学id失败

Part Number: BQ27441-G1
Other Parts Discussed in Thread: GPCCHEM, BQSTUDIO,

通过检测电池充放电数据,匹配化学id,没有结果,MiscInfo.txt 信息为”ProcessingType= 2“,请问如何获取到化学id。

以及id获取到后,芯片中Ra配置的值与电池有什么关系?如何获取?

6204.config.txt
ProcessingType = 2
NumCellSeries = 1
ElapsedTimeColumn = 0
VoltageColumn = 1
CurrentColumn = 2
TemperatureColumn = 3
4555.roomtemp_rel_dis_rel.csv
MiscInfo.txt
ProcessingType= 2

  • 您好

    您可以通过GPCCHEM工具匹配化学ID,方法在下方链接26页2.2.3 电池化学 ID 匹配方法。

    您说的Ra应该指的是阻抗,重点看一下下方链接34页的Ra Flag章节

    www.ti.com.cn/.../zhcaaf7.pdf

  • 您好 化学id匹配完成后,怎么设置?

    bqStudio 没找到 Chemistry菜单

  • 您好

    如果您目前使用的是BQ27441-G1,您可以看一下它的TRM和数据手册。

    TRM第6页有写:

    Unlike some other Impedance TrackTm fuel gauges, the bq27441-G1 cannot be programmed with specific battery chemistry profiles

    www.ti.com.cn/.../sluuac9a.pdf

    数据手册也有写

    www.ti.com.cn/.../bq27441-g1.pdf

    因为CHEM_ID是固定的,所以bqStudio没有Chemistry菜单。

  • 您好

    感谢解惑,目前我遇到的问题是,产品用的电池容量是5000mAh,电压范围是2.75V(放电截止),4.2V(满电)。

    但是将参数配置完成后,电池电量结果不对。在电池电压3.6V的时候电量就是0了。

    按《TI 电量计应用指导》是先匹配化学id,再学习阻抗表。是否可以通过学习阻抗表就可以优化电池电量准确度?

    配置参数如下:

    unsigned short const Designcapacity={5000};     //Design capacity=2500mAh   这个值随着电池的使用会变化

    unsigned short const DesignEnergy={18500};       //Design Energy=2500*3.8mWh; Design Energy=Design capacity*3.7 for 4.2V battery,Design Energy=Design capacity*3.8 for 4.35V battery,
    #define   FCC_SIZE   5000      //满电容量

    //220   充电
    //5000*10/220=227
    const uint16_t Taperrate ={500};              //Taper rate=500,taper rate=Design Capacity*10/taper current mA;(500*10/220 = 125) a little higher than charger taper current(~>20mA)  
    //Taperrate  是一个充电截止判定的量

    //subclass 81
    //放电电流 大于62mA  5000*10 / 62.5ma = 800
    const uint16_t Dsgcurrentthreshold ={800};    // ?50000/167=299mA,  Dsg current threshold(num)=500, Dsg current threshold(mAh)=Design capacity*10/Dsg current threshold(num)=80mA



    //充电电流一定大于这个电流 100mA 5000*10/100 = 500
    const uint16_t Chgcurrentthreshold ={500};    //?Chg current threshold(num)=500, Chg current threshold(mAh)=Design capacity*10/Chg current threshold(num)=80mA,must smaller than charger taper current



    //进入低功耗电流 5000 * 10 / 50ma = 1000
    const uint16_t Quitcurrent ={1000};  //{0x03E8}; ?    //Quit current threshold(num)=1000,Quit current threshold(mAh)=Design capacity*10/Quit current threshold(num)=40mA

    #endif
    程序如下:
    bq27441_driver.c
    #include "bq27441_driver.h"
    #include "common.h"
    #include "menter_i2c.h"
    #include "dev_info.h"
    #include "menter_ctrl.h"
    
    
    
    
    void HAL_UART_Transmit(int *temp1,unsigned char*data,char data_len,int temp2)
    {
      for (size_t i = 0; i < data_len; i++)
      {
        printf("%02x ",data[i]);
      }
      printf("\n");
    }
    void HAL_Delay(unsigned int data)
    {
      vTaskDelay(data);
    
    };
    const uint16_t terminatevoltage ={0x012C};       //terminate voltage=3000mV,system shutdown voltage  ,      系统的正常工作电压
    //
    const uint16_t loadselect ={0x81};               //load select/load loadselectmode; 0x81 power-mode 0x01 current mode, normally use 0x81 ,if design capacity > 8500mAh change to 0x01
    #define BATTERY_5000MAH
    uint32_t Frack_Num;
    // #define BATTERY_3200MAH
    /**************************************************************************************
    **************************************************************************************/
    
    
    #ifdef BATTERY_5000MAH
    //3200mAH    
    unsigned short const Designcapacity={5000};     //Design capacity=2500mAh   这个值随着电池的使用会变化
    unsigned short const DesignEnergy={18500};       //Design Energy=2500*3.8mWh; Design Energy=Design capacity*3.7 for 4.2V battery,Design Energy=Design capacity*3.8 for 4.35V battery,
    #define   FCC_SIZE   5000      //满电容量
    
    //220   充电
    //5000*10/220=227
    const uint16_t Taperrate ={500};              //Taper rate=500,taper rate=Design Capacity*10/taper current mA;(500*10/220 = 125) a little higher than charger taper current(~>20mA)  
    //Taperrate  是一个充电截止判定的量
    
    //subclass 81
    //放电电流 大于62mA  5000*10 / 62.5ma = 800
    const uint16_t Dsgcurrentthreshold ={800};    // ?50000/167=299mA,  Dsg current threshold(num)=500, Dsg current threshold(mAh)=Design capacity*10/Dsg current threshold(num)=80mA
    
    
    //充电电流一定大于这个电流 100mA 5000*10/100 = 500
    const uint16_t Chgcurrentthreshold ={500};    //?Chg current threshold(num)=500, Chg current threshold(mAh)=Design capacity*10/Chg current threshold(num)=80mA,must smaller than charger taper current
    
    
    //进入低功耗电流 5000 * 10 / 50ma = 1000
    const uint16_t Quitcurrent ={1000};  //{0x03E8}; ?    //Quit current threshold(num)=1000,Quit current threshold(mAh)=Design capacity*10/Quit current threshold(num)=40mA
    
    #endif
    
    
    
    
    
    
    
    
    
    /**************************************************************************************
    **************************************************************************************/
    
    
    #ifdef BATTERY_5000MAH
    const uint16_t  Qmax ={5000};   //
    #define RA_AVE  3
    // 阻值*5000/3000               
    // const uint16_t  Ra[] ={102, 102, 99, 107, 72, 59, 62, 63, 53, 47, 60, 70, 140, 369, 588};
    // //源程序值3200mAh
    // const uint16_t  Ra[] ={52, 52, 50, 54, 45, 50, 71, 82, 80, 75, 87, 82, 114, 264, 420};//                     
    // const uint16_t  Ra[] ={0x66, 0x66, 0x63, 0x6b, 0x48, 0x3b, 0x3e, 0x3f, 0x35, 0x2f, 0x3c, 0x46, 0x8c, 0x171, 0x24c};   //?
    // const uint16_t  Ra[] ={0x34, 0x34, 0x32, 0x36, 0x2d, 0x32, 0x47, 0x52, 0x50, 0x4b, 0x57, 0x52, 0x72, 0x108, 0x1a4}; 
    
    const uint16_t  Ra[] ={33,33,32,35,29,32,45,52,51,48,56,52,73,169,269};
    
    #endif
    uint16_t bettery_volt,bettery_soc,bettery_fcc,bettery_temper,bettery_intemper;
    int16_t bettery_avgCur;
    /**************************************************************************************
    **************************************************************************************/
    
    static uint32_t bq_cmdWrite(uint8_t subaddr, uint8_t cmd);
    static uint32_t bq_read(uint8_t *pBuf,  uint8_t addr, uint8_t len);
    static uint32_t bq_MemoryWrite(uint8_t subaddr, uint16_t data );
    static uint8_t GetCheckSum(uint8_t  addr);
    static void  bq_Read_Ta_and_Qmax(void);
    static void bq_fullReset(void);
    static void bq_CONFIG_subclass52(void);
    static void bq_CONFIG_subclass51(void);
    static void bq_CONFIG_subclass59(void);
    static uint32_t bq_ConfigRead(void);
    static uint32_t bq_Rdarg(uint16_t *volt, int16_t *avgCur, uint16_t *soc, uint16_t *fcc, uint16_t *temper, uint16_t *intemper);
    uint16_t bq_ITPOR(void);
    /**************************************************************************************
    **************************************************************************************/
    
    /**************************************************************************************
    **************************************************************************************/
    
    
    /********************************************************
    向subaddr 这个地址写入cmd这个指令(写单个指令)
     ********************************************************/
    uint32_t bq_cmdWrite(uint8_t subaddr, uint8_t cmd) 
    {
      return I2C_MAST_WRITE(BQ2744_ADDRESS,subaddr,&cmd,1,1);
        // return I2C_WriteData(BQ2744_ADDRESS,subaddr,&cmd,1);
        // return HAL_I2C_Mem_Write(&hi2c1,BQ2744_ADDRESS,subaddr,I2C_MEMADD_SIZE_8BIT,&cmd,1,0xff);
    }
    /*************************************  
      *************************************/
    uint32_t bq_read(uint8_t *pBuf,  uint8_t addr, uint8_t len) 
    { 
      return I2C_MAST_READ(BQ2744_ADDRESS, addr, pBuf, len,1);
      // return I2C_ReadData(BQ2744_ADDRESS, addr, pBuf, len);
      //return HAL_I2C_Mem_Read(&hi2c1, BQ2744_ADDRESS, addr, len, pBuf, len, 0xfff);   
        
    }
    /********************************************************
    *********************************************************/
    uint32_t bq_MemoryWrite(uint8_t subaddr, uint16_t data )
    {
        uint8_t Mdata=(data>>8);
        uint8_t Ldata=(data&0xFF); 
        // I2C_WriteData(BQ2744_ADDRESS,subaddr,&Mdata,1);  
        // HAL_I2C_Mem_Write(&hi2c1,BQ2744_ADDRESS,subaddr,I2C_MEMADD_SIZE_8BIT,&Mdata,1,0xff);
        // return I2C_WriteData(BQ2744_ADDRESS,subaddr+1,&Ldata,1);
        //return HAL_I2C_Mem_Write(&hi2c1,BQ2744_ADDRESS,subaddr+1,I2C_MEMADD_SIZE_8BIT,&Ldata,1,0xff);    
        I2C_MAST_WRITE(BQ2744_ADDRESS,subaddr,&Mdata,1,1);  
         return I2C_MAST_WRITE(BQ2744_ADDRESS,subaddr+1,&Ldata,1,1);
    }
    /********************************************************
    *********************************************************/
    uint8_t GetCheckSum(uint8_t  addr) 
    {
        uint8_t checksum = 0, i;
        uint8_t rtBuf[2];
        
        for (i = 0; i < 32; i++) 
        {
            rtBuf[0] = 0;
            bq_read(rtBuf, addr, 1);
            checksum = checksum + rtBuf[0];
            addr++;
        }
        
        checksum = 0xFF - checksum;
        return checksum;
    }
    /********************************************************
    *********************************************************/
    void  bq_Read_Ta_and_Qmax(void)
    {
      int huart2;
    	unsigned short  qmax=0x00;
    	uint8_t  Ra_table[32]= {0x0A};
    	unsigned short  cap=0x00;
    	
    	uint8_t buf[1];
     	uint8_t tbuf[2];   
            
    	uint8_t i;
            tbuf[0]=0;
            tbuf[1]=0;       
            Ra_table[31]='\r';
            Ra_table[30]='\n';
    	bq_cmdWrite(0x00,0x00);   //Places the device in UNSEALED access mode.
    	bq_cmdWrite(0x01,0x80);
    
    	bq_cmdWrite(0x00,0x00);
    	bq_cmdWrite(0x01,0x80);
    
    
    	bq_cmdWrite(0x61,0x00);       // enables BlockData() to access to RAM.
    
    	bq_cmdWrite(0x3e,0x52);     //选择0x52区域      //access the state subclass (decimal 82, 0x52 hex)
    
    	bq_cmdWrite(0x3f,0x00);         //use offset 0x00 for offsets 0 to 31
    
    
    	bq_read(buf, 0x40, 2);
    	qmax = (buf[0] << 8) | buf[1];  //高低位交换
    
    	bq_read(buf, 0x4A, 2);
    	cap = (buf[0] << 8) | buf[1]; //高低位交换
    
    
    	bq_cmdWrite(0x3e,0x59);//选择0x59区域
    	bq_cmdWrite(0x3f,0x00);
    
    	for(i=0; i<30; i++)
    	{
    		bq_read(buf, 0x40+i, 1);
    		Ra_table[i] = buf[0]; //高低位交换
    	}
            HAL_UART_Transmit(&huart2,Ra_table,32,0xff); 
            
            
            Frack_Num++;
            tbuf[0]=Frack_Num>>24;
            HAL_UART_Transmit(&huart2,tbuf,1,0xff);
            tbuf[0]=((Frack_Num>>16)&0xFF);
            HAL_UART_Transmit(&huart2,tbuf,1,0xff);
            tbuf[0]=((Frack_Num>>8)&0xFF);
            HAL_UART_Transmit(&huart2,tbuf,1,0xff);       
            tbuf[0]=(Frack_Num&0xFF);
            HAL_UART_Transmit(&huart2,tbuf,1,0xff);         
    //	bq_cmdWrite(0x3e,0x40);//选择0x59区域
    //	bq_cmdWrite(0x3f,0x00);
    //
    //
    //        bq_read(buf, 0x40, 1);
    //        HAL_UART_Transmit(&huart2,buf,1,0xff);         
    //        bq_read(tbuf, 0x41, 1);
    //        HAL_UART_Transmit(&huart2,tbuf,1,0xff);  
            	
    }
    
    /********************************************************
    *********************************************************/
    void bq_fullReset(void)
    {
    	if (bq_cmdWrite(0x00,0x00) || bq_cmdWrite(0x01,0x80))   //Places the device in UNSEALED access mode.
    	{
    	    return ;
    	}
    
    	if (bq_cmdWrite(0x00,0x00) || bq_cmdWrite(0x01,0x80))
    	{
    	    return ;
    	}
    	
    	if (bq_cmdWrite(0x00,0x41) || bq_cmdWrite(0x01,0x00)) //Performs a full device reset.
    	{
    	    return;
    	}
    }
    
    /********************************************************
    *********************************************************/
    
    void bq_CONFIG_subclass52(void) 
    {
        uint8_t checksum = 0;
        bq_cmdWrite(0x3e, 0x52); //选择0x52区域      //access the state subclass (decimal 82, 0x52 hex)
        bq_cmdWrite(0x3f, 0x00); //use offset 0x00 for offsets 0 to 31
    
        
        bq_MemoryWrite(0x40, Qmax);
    
        bq_MemoryWrite(0x50, terminatevoltage); //terminatevoltage 截止电压(系统能够正常运行的最低电压) 
    
        bq_cmdWrite(0x45, loadselect);
    
        bq_MemoryWrite(0x4A, Designcapacity); //电池容量  mAh
    
        bq_MemoryWrite(0x4C, DesignEnergy); //mWh
    
        bq_MemoryWrite(0x5B, Taperrate);
    
        checksum = GetCheckSum(0x40);
    
        bq_cmdWrite(0x60, checksum); //0xba  checksum
    
    }
    void bq_CONFIG_subclass51(void) //充放电阈值设置
    {
        uint8_t checksum = 0;
        bq_cmdWrite(0x3e, 0x51); //选择0x51区域
        bq_cmdWrite(0x3f, 0x00);
        bq_MemoryWrite(0x40, Dsgcurrentthreshold); //放电电流
        bq_MemoryWrite(0x42, Chgcurrentthreshold); //充电电流,充电电流的判断标准
        bq_MemoryWrite(0x44, Quitcurrent); //静态电源  
        checksum = GetCheckSum(0x40);
        bq_cmdWrite(0x60, checksum); //0x5e
    }
    
    void bq_CONFIG_subclass59(void)//内阻表设置
    {
        uint8_t checksum = 0, i = 0;
        bq_cmdWrite(0x3e, 0x59); //选择0x59区域
        bq_cmdWrite(0x3f, 0x00);
        for (i = 0; i < 15; i++) {
            bq_MemoryWrite(0x40 + i * 2, (int)(Ra[i]*RA_AVE));
        }
        checksum = GetCheckSum(0x40);
        bq_cmdWrite(0x60, checksum);
    }
    
    /********************************************************
    返回0,  进入配置模式并退出成功, 返回1, 进入配置失败, 返回0xFE, 超时
    *********************************************************/
    uint32_t bq_Config(void) 
    {  
    	uint8_t  rtBuf[2];
    	uint16_t value;
    	uint32_t result;
    	
    	static uint32_t m_tryCnt = 0;
    
      	if (m_tryCnt++ > 10)
    	{	   
    	    m_tryCnt = 0;
    	    return 0xFE;
    	}
    
        if (bq_cmdWrite(0x00, 0x00) || bq_cmdWrite(0x01, 0x80)) //Places the device in UNSEALED access mode.
        {
            cmsLog_error("entry unsealed err\n");
            
            return 1;
        }
        
        if (bq_cmdWrite(0x00, 0x00) || bq_cmdWrite(0x01, 0x80))
        {
            cmsLog_error("entry unsealed err1\n");
            return 1;
        }
        
        if (bq_cmdWrite(0x00, 0x13) || bq_cmdWrite(0x01, 0x00))
        {
            cmsLog_error("entry config mode err\n");
            return 1;
        }
        
        HAL_Delay(1);
    
        result = bq_read(rtBuf, bq27421CMD_FLAG_LSB, 2);
        if (result == 0)
        {
        	value = (rtBuf[1] << 8) | rtBuf[0];
    
        	if (!(value & 0x10))
        	{    		
        		
                cmsLog_error("upmode=0\n");         
        	     bq_cmdWrite(0x61,0x00);       // enables BlockData() to access to RAM.
    
               bq_CONFIG_subclass52();
                        
               bq_CONFIG_subclass51();
    
               bq_CONFIG_subclass59();
            
                bq_cmdWrite(0x00,0x42); //软复位 退出配置模式            
                bq_cmdWrite(0x01,0x00);
    
                bq_cmdWrite(0x00,0x00);
                bq_cmdWrite(0x01,0x00);
               
                m_tryCnt = 0;            
        	}
        	else
        	{
              
               cmsLog_error("upmode=1\n");
        	     bq_cmdWrite(0x61,0x00);       // enables BlockData() to access to RAM.
    
               bq_CONFIG_subclass52();
                        
               bq_CONFIG_subclass51();
    
               bq_CONFIG_subclass59();
            
                bq_cmdWrite(0x00,0x42); //软复位 退出配置模式            
                bq_cmdWrite(0x01,0x00);
    
                bq_cmdWrite(0x00,0x00);
                bq_cmdWrite(0x01,0x00);          
        	    result = 1;  
        	    cmsLog_error("value=0x%x\n", value);
        	}
        }  
    
        cmsLog_debug(" %s\n", result == 0 ? "Ok" : "Fail");
        return result;
    }
    /********************************************************
    返回0, 配置成功, 返回1, 配置失败  返回其他, 配置超时
    *********************************************************/
    uint32_t bq_ConfigRead(void)
    {
        uint8_t  rtBuf[2] = {0};
    	uint16_t value;
    	uint32_t result;
    
        result = bq_read(rtBuf, bq27421CMD_FLAG_LSB, 2);
    
        if (result != 0)
        {
            return 0xFF;
        }
    
        if (result == 0) 
        {
            value = (rtBuf[1] << 8) | rtBuf[0];
            
            if (value & 0x10) 
            {   
                result = 1;
            }
            else
            {
                bq_cmdWrite(0x00,0x20);
                bq_cmdWrite(0x01,0x00);
            }
        }
    
        return result;
    }
    
    /********************************************************
     读参数
    ********************************************************/
    uint32_t bq_Rdarg(uint16_t *volt, int16_t *avgCur, uint16_t *soc, uint16_t *fcc,uint16_t *temper,uint16_t *intemper)
    {
      uint8_t  lrtBuf[1];
      uint8_t  mrtBuf[1];
                  
      uint16_t  value;	
      uint16_t ret1;
      uint16_t ret2;
    
    // int I2C_ReadData(uint8_t slaveAddr, uint8_t regAddr, uint8_t *pData, uint16_t dataLen);
      ret1=I2C_MAST_READ(BQ2744_ADDRESS, bq27421CMD_VOLT_LSB,lrtBuf, 1,1);
      ret2=I2C_MAST_READ(BQ2744_ADDRESS, bq27421CMD_VOLT_MSB,mrtBuf, 1,1);
      //ret1=HAL_I2C_Mem_Read(&hi2c1, BQ2744_ADDRESS, bq27421CMD_VOLT_LSB, 1, lrtBuf, 1, 0xfff);   //volt  为电压  
      //ret2=HAL_I2C_Mem_Read(&hi2c1, BQ2744_ADDRESS, bq27421CMD_VOLT_MSB, 1, mrtBuf, 1, 0xfff); 
      if(0 == ret1 && ret2 == 0)   
      {
        value = (mrtBuf[0] << 8) |lrtBuf[0];
        
        *volt = value;
           
      }
      else
      {
        return 0xF1;
      }
      ret1=I2C_MAST_READ(BQ2744_ADDRESS, bq27421CMD_AI_LSB,lrtBuf, 1,1);
      ret2=I2C_MAST_READ(BQ2744_ADDRESS, bq27421CMD_AI_MSB,mrtBuf, 1,1);
      //ret1=HAL_I2C_Mem_Read(&hi2c1, BQ2744_ADDRESS, bq27421CMD_AI_LSB, 1, lrtBuf, 1, 0xfff);     //avgCur 为平均电流
      //ret2=HAL_I2C_Mem_Read(&hi2c1, BQ2744_ADDRESS, bq27421CMD_AI_MSB, 1, mrtBuf, 1, 0xfff); 
      if(0 == ret1 && ret2 == 0)   
      {
        value = (mrtBuf[0] << 8) |lrtBuf[0];
        
        *avgCur = value;    
      }
      else
      {
        return 0xF1;
      } 
      ret1=I2C_MAST_READ(BQ2744_ADDRESS, bq27421CMD_SOC_LSB,lrtBuf,1,1);
      ret2=I2C_MAST_READ(BQ2744_ADDRESS, bq27421CMD_SOC_MSB,mrtBuf,1,1);  
      //ret1=HAL_I2C_Mem_Read(&hi2c1, BQ2744_ADDRESS, bq27421CMD_SOC_LSB, 1, lrtBuf, 1, 0xfff);    //soc 为电量百份比   
      //ret2=HAL_I2C_Mem_Read(&hi2c1, BQ2744_ADDRESS, bq27421CMD_SOC_MSB, 1, mrtBuf, 1, 0xfff); 
      if(0 == ret1 && ret2 == 0)   
      {
        value = (mrtBuf[0] << 8) |lrtBuf[0];
        
        *soc = value;  
      }
      else
      {
        return 0xF1;
      }
      ret1=I2C_MAST_READ(BQ2744_ADDRESS, bq27421CMD_FCC_LSB,lrtBuf, 1,1);
      ret2=I2C_MAST_READ(BQ2744_ADDRESS, bq27421CMD_FCC_MSB,mrtBuf, 1,1); 
      //ret1=HAL_I2C_Mem_Read(&hi2c1, BQ2744_ADDRESS, bq27421CMD_FCC_LSB, 1, lrtBuf, 1, 0xfff);   //FCC为充电电量
      //ret2=HAL_I2C_Mem_Read(&hi2c1, BQ2744_ADDRESS, bq27421CMD_FCC_MSB, 1, mrtBuf, 1, 0xfff); 
      if(0 == ret1 && ret2 == 0)   
      {
        value = (mrtBuf[0] << 8) |lrtBuf[0];
        
        *fcc = value;
      }
      else
      {
        return 0xF1;
      }   
      ret1=I2C_MAST_READ(BQ2744_ADDRESS, bq27421CMD_TEMP_LSB,lrtBuf, 1,1);
      ret2=I2C_MAST_READ(BQ2744_ADDRESS, bq27421CMD_TEMP_MSB,mrtBuf, 1,1); 
      //ret1=HAL_I2C_Mem_Read(&hi2c1, BQ2744_ADDRESS, bq27421CMD_FCC_LSB, 1, lrtBuf, 1, 0xfff);   //FCC为充电电量
      //ret2=HAL_I2C_Mem_Read(&hi2c1, BQ2744_ADDRESS, bq27421CMD_FCC_MSB, 1, mrtBuf, 1, 0xfff); 
      if(0 == ret1 && ret2 == 0)   
      {
        value = (mrtBuf[0] << 8) |lrtBuf[0];
        
        *temper = value;
      }
      else
      {
        return 0xF1;
      } 
    
    
      ret1=I2C_MAST_READ(BQ2744_ADDRESS, bq27421CMD_ITEMP_LSB,lrtBuf, 1,1);
      ret2=I2C_MAST_READ(BQ2744_ADDRESS, bq27421CMD_ITEMP_MSB,mrtBuf, 1,1); 
      //ret1=HAL_I2C_Mem_Read(&hi2c1, BQ2744_ADDRESS, bq27421CMD_FCC_LSB, 1, lrtBuf, 1, 0xfff);   //FCC为充电电量
      //ret2=HAL_I2C_Mem_Read(&hi2c1, BQ2744_ADDRESS, bq27421CMD_FCC_MSB, 1, mrtBuf, 1, 0xfff); 
      if(0 == ret1 && ret2 == 0)   
      {
        value = (mrtBuf[0] << 8) |lrtBuf[0];
        
        *intemper = value;
      }
      else
      {
        return 0xF1;
      } 
    
    
    
        return ret1;
    }
    /********************************************************
    返回1 需要配置 返回0 已配置过 返回其他值出错
    ********************************************************/
    uint16_t bq_ITPOR(void)
    {
    	uint8_t  rtBuf[2] = {0};
    
    	uint32_t ret;
    
    	ret  = bq_read(rtBuf, bq27421CMD_FLAG_LSB, 1);
    
    	if (ret != 0)
    	{
    	    return 0xFF;
    	}	
    
        if (rtBuf[0] & 0x20)
        {
            return 1;
        }
    
        return 0xAA;    
    }
    
    extern char power_energy;
    
    #include <time.h>
    uint8_t BQ25895_STATE(){
    
      static time_t now;
      static time_t last=0;
      static uint32_t num=0;
      char strftime_buf[64];
      struct tm timeinfo; 
      static int low_time=0;
      time(&now);
      bq_Rdarg(&bettery_volt, &bettery_avgCur, &bettery_soc, &bettery_fcc,&bettery_temper,&bettery_intemper);
      printf("%d,%ld,%d,%d,%d,%d,%0.2f,%0.2f\n",num,now,bettery_volt, bettery_avgCur, bettery_soc, bettery_fcc,(float)bettery_temper/10.0-273.15,(float)bettery_intemper/10.0-273.15);
      if (bettery_volt<2750)
      {
        low_time++;
        // ctrl_off();
      }
      else
      {
        low_time=0;
      }
      if(low_time>3)
        ctrl_off();
      
      last=now;
      num++;
      dev_info_data.bettery_enage=bettery_soc;
      dev_info_data.bettery_volite=(float)bettery_volt/1000;
      if(bettery_soc<10)
        power_energy=0;
      else if (bettery_soc<40)
      {
            power_energy=1;
      }
      else if (bettery_soc<70)
      {
            power_energy=2;
      }  
      else if (bettery_soc<90)
      {
            power_energy=3;
      }
      else
      {
            power_energy=4;
      }
    
      if((bettery_avgCur >20)&&bettery_soc<91)
      // if((avgCur >20)&&HAL_GPIO_ReadPin(TYPEC_DEC_GPIO_Port,TYPEC_DEC_Pin)&&soc<91)
      {
        return BQ_Charging;
      }else if(bettery_soc>90){
        return BQ_Charge_Done;
      }else if(bettery_avgCur<(-150)){
        return Rod_Charging;
      }
      return 1;
    }
    
    
    uint8_t getBoxBattery(void)
    { 
      uint16_t volt,soc,fcc ;
      int16_t avgCur;     
      
      if(bq_ITPOR() !=0xAA )
      {
        HAL_Delay(500);
        bq_Config();
        if(bq_ConfigRead() != 0)
          return 0xFE;          
        
      }
      
      bq_Rdarg(&volt, &avgCur, &soc, &fcc,&bettery_temper,&bettery_intemper);
      
      return soc&0xFF;
    }
    
    
    
    uint8_t Batter_Gauge_Test(){
      uint8_t data;
      uint16_t volt,soc,fcc ;
      int16_t avgCur;     
      volt=bq_ITPOR();
            if(volt == 1 )
            {
              bq_Config();
              if(bq_ConfigRead() != 0)
              return 2;          
            }
      bq_Read_Ta_and_Qmax();      
      bq_Rdarg(&volt, &avgCur, &soc, &fcc,&bettery_temper,&bettery_intemper);
      return 1;
      
    }
    
    /********************************************************
    返回0,  进入配置模式并退出成功, 返回1, 进入配置失败, 返回0xFE, 超时
    *********************************************************/
    uint32_t bq_Config_nww(void) 
    {  
      uint8_t  rtBuf[2];
      uint16_t value;
      uint32_t result;
      
      static uint8_t m_tryCnt = 0;
      
      if (m_tryCnt++ > 10)
      {	   
        m_tryCnt = 0;
        return 0xFE;
      }
    
      if (bq_cmdWrite(0x00, 0x00) || bq_cmdWrite(0x01, 0x80)) //Places the device in UNSEALED access mode.
      {
        return 1;
      }
        
      if (bq_cmdWrite(0x00, 0x00) || bq_cmdWrite(0x01, 0x80))
      {
        return 2;
      }
      
      if (bq_cmdWrite(0x00, 0x13) || bq_cmdWrite(0x01, 0x00))
      {
        return 3;
      }
        
      HAL_Delay(1);
      result=1;
      while(result){
        result = bq_read(rtBuf, bq27421CMD_FLAG_LSB, 2);
        if (result == 0)
        {
          value = (rtBuf[1] << 8) | rtBuf[0];
          result=(value & 0x10);
          
        }
      
      }
      bq_cmdWrite(0x61,0x00);       // enables BlockData() to access to RAM.
      
      bq_CONFIG_subclass52();
      
      return result;
    }
    void bettery_task(void);
    void bq27441_init(void){ 
            if(bq_ITPOR() == 1){ 
              
             cmsLog_error("need_config\n");           
                HAL_Delay(110);
                bq_Config();
                HAL_Delay(10);            
                bq_ConfigRead();
    
    
    //            bq_fullReset();            
            }
            else
            cmsLog_error("noconfig=0\n");          
      xTaskCreatePinnedToCore(bettery_task, "bettery_task", 4096, NULL, 2, NULL, 1);       
    }
    
    
    
    void bettery_task(void)
    {
        printf("Num,ElapsedTime,Voltage_mV,Current_mA,SOC,FCC,Temperature,INTemperature\n");
        while (1)
        {
          if (tcp_ota_updating!=true)
          {
            BQ25895_STATE();
          }
          // printf("%d\n",tcp_ota_updating);
          vTaskDelay(pdMS_TO_TICKS(5000));
        }
    
    }
    bq27441_driver.h
  • 您好

    学习可以使容量这些计算更准确,学习成功的判断标准是Qmax、Ra table是否更新成功,可以查看Update Status, Ra flag。

    学习这个过程,请您参考之前发给您的电量计应用手册和下方链接

    https://www.tij.co.jp/jp/lit/an/slua903/slua903.pdf

    很遗憾,无法为您逐一检查配置,请按照TRM看软件配置。

    如果有新问题,请重新发帖。