ZHCABD1 October   2021 BQ21061 , BQ21062 , BQ24179 , BQ25150 , BQ25155 , BQ25157 , BQ25672 , BQ25790 , BQ25792 , BQ25798 , BQ25882 , BQ25883 , BQ25887 , BQ25895 , BQ25896 , BQ25898 , BQ25898D

 

  1.   使用智能电池充电器估计充电状态
  2.   商标
  3. 1引言
  4. 2电池特征
  5. 3生成查找表
  6. 4BQ25155 寄存器配置
  7. 5最佳用例
  8. 6Python 查找表发生器
  9. 7MSP430 代码片段

MSP430 代码片段

{...
	
    //Disable Watchdog and Enable TS
    StdI2C_P_TX_Single(BQ25150_ADDR, BQ25150_CHARGERCTRL0, 0x90, &Err);
	
    // Disable interrupts for all the rest except ADC comparator
    StdI2C_P_TX_Single(BQ25150_ADDR, BQ25150_MASK0, 0xFE, &Err); //Mask all but VIN_PGOOD
    StdI2C_P_TX_Single(BQ25150_ADDR, BQ25150_MASK1, 0xBF, &Err); //Mask all
    StdI2C_P_TX_Single(BQ25150_ADDR, BQ25150_MASK2, 0xF7, &Err); //Mask all
    StdI2C_P_TX_Single(BQ25150_ADDR, BQ25150_MASK3, 0xFF, &Err); //Mask all
	
    // Enable ADC channels for VBAT only
    StdI2C_P_TX_Single(BQ25150_ADDR, BQ25150_ADC_READ_EN, 0x08, &Err);
	
    // Enable ADC
    StdI2C_P_TX_Single(BQ25150_ADDR, BQ25150_ADCCTRL0, 0x80, &Err); //Set ADC to perform conversion every 1s at 24ms conversion speed
    StdI2C_P_TX_Single(BQ25150_ADDR, BQ25150_ADCCTRL1, 0x00, &Err); //Disables comparator channels

    //Set PG pin as GPIO for discharge
    StdI2C_P_TX_Single(BQ25150_ADDR, BQ25150_ICCTRL1, 0x08, &Err);
    StdI2C_P_TX_Single(BQ25150_ADDR, BQ25150_ICCTRL2, 0x10, &Err);

    //GPIO_setAsInputPinWithPullUpResistor(BQ_INT2);
    GPIO_setAsInputPin(BQ_INT2);
    GPIO_enableInterrupt(BQ_INT2);
    GPIO_selectInterruptEdge(BQ_INT2, GPIO_HIGH_TO_LOW_TRANSITION);
    GPIO_clearInterrupt(BQ_INT2);

	StdI2C_P_RX_Single(BQ25150_ADDR, BQ25150_ADCDATA_VBAT_M, &VBAT_Meas_M, &Err); //Finding current battery voltage
	StdI2C_P_RX_Single(BQ25150_ADDR, BQ25150_ADCDATA_VBAT_M, &VBAT_Meas_L, &Err);
	VBAT_Meas = (uint16_t)(VBAT_Meas_M << 8) | VBAT_Meas_L; //Converting to 16-bit integer
	cur_SOC = find_initial_SOC(VBAT_Meas); //Finding initial SOC
	sprintf(SOC_string, "SOC = %d %%        ", cur_SOC);

    while(1) {

		waitms(1000); //Period between SOC updates
		StdI2C_P_RX_Single(BQ25150_ADDR, BQ25150_ADCDATA_VBAT_M, &VBAT_Meas_M, &Err);
		StdI2C_P_RX_Single(BQ25150_ADDR, BQ25150_ADCDATA_VBAT_L, &VBAT_Meas_L, &Err);
		VBAT_Meas = (uint16_t)(VBAT_Meas_M << 8) | VBAT_Meas_L;
		cur_SOC = update_SOC_discharge(cur_SOC, VBAT_Meas); //Update SOC
		sprintf(SOC_string, "SOC = %d %%        ", cur_SOC);    }
}

uint8_t find_initial_SOC(uint16_t VBAT_Meas){
	int i;

	for (i = 99; i >= 0; i--){
		if (VBAT_Meas >= SOC_lookup_table[i]){
			return (uint8_t)(i + 1);
		}
	}
	return 0;
}

uint8_t update_SOC_discharge(uint8_t cur_SOC, uint16_t VBAT_Meas){
	int i;

	for (i = cur_SOC - 1; i >= 0; i--){ //Begins at current SOC so it doesn't have to go through the whole array each time. 
		if (VBAT_Meas >= SOC_lookup_table[i]){ 
			return (uint8_t)(i + 1); //Must add 1 to the SOC found because array is zero-indexed.
		}
	}

	return 0; //Default is SOC = 0.
}