Part Number:BQ24160
Tool/software: Code Composer Studio
I am using the BQ24160 Battery Charger to charge a 3.7 Li polymer battery and I'm not seeing it reach the full voltage set in the Control/Battery Voltage Register (03). I set the value to 3.8V using the I2C bus and then set a Watchdog Timer reset to the Status/Control Register every one second. The battery charges to the default 3.6V but then stops charging after that.
I can manually charge the battery to 4.0V without a problem using a CV/CC power supply.
I'm sending one register byte and one data byte to slave address 0x6B. I've looked at the I2C commands to the BQ24160 with a scope and they appear correct and the BQ24160 ACKs all the commands.
I have the external FET controlled by BGATE installed. The SYS voltage is sitting at 3.9V and the BAT voltage usually around 3.58V~3.68V.
Hopefully someone has insights on what the problem is. I'm not sure what should happen when the battery falls below the regulation voltage. I would assume the battery charger tries to maintain the 3.8V .
Here is the code I am using on an MSP430F5659:
unsigned int BQ2416_reset[] = { 0x02, 0x80 }; // Control Register > Reset all registers to default
unsigned int BQ2416_defaults[] = { 0x02, 0x0D }; // Control Register > Enter Hi-Z Mode, defaults
unsigned int BQ2416_current[] = { 0x02, 0x2C }; // Control Register > Leave Hi-Z Mode, 500mA current limit
unsigned int BQ2416_voltage[] = { 0x03, 0x3C }; // Battery Voltage Register > Charge Voltage = 3.8V
// I2C Write to Battery Charger
void I2C_write(int byteCount, unsigned int *data)
{
B1_Tx_Data = data; // TX data array address
B1_ByteCtr = byteCount; // load TX byte counter
UCB1IE |= UCTXIE; // Enable TX interrupt
UCB1CTL1 |= UCTR | UCTXSTT; // I2C TX, start condition
_delay_cycles(1500); // allow transmission completion
while (UCB1STAT & UCBBUSY); // wait for transmission to complete
}
// Battery Initialization
void initBattery(void)
{
P8DIR |= BIT5 | BIT6; // P8.5 to UCB1SDA and
P8SEL |= BIT5 | BIT6; // P8.6 to UCB1SCL
UCB1CTL1 |= UCSWRST; // Enable SW reset
UCB1CTL0 = UCMST | UCMODE_3 | UCSYNC; // I2C Master, synchronous mode
UCB1CTL1 = UCSSEL_2 | UCSWRST; // Use SMCLK, keep SW reset
UCB1BR0 = 40; // fSCL = SMCLK/40 = ~100kHz
UCB1BR1 = 0; // high byte of word
UCB1I2CSA = 0x6B; // BQ24160 Slave Address is 6Bh
UCB1CTL1 &= ~UCSWRST; // Clear SW reset, resume operation
UCB1IE |= UCNACKIE | UCTXIE; // Enable TX interrupt, NACK interrupt
UCB1IFG &= ~UCTXIFG; // Clear USCI_B1 TX interrupt flag
// Control Register > Reset all registers to default (0x02, 0x80)
I2C_write(2, BQ2416_reset); // I2C write data to register
// Control Register > Enter Hi-Z Mode, defaults (0x02, 0x0D)
I2C_write(2, BQ2416_defaults); // I2C write data to register
// Control Register > Leave Hi-Z Mode, 500mA current limit (0x02, 0x2C)
I2C_write(2, BQ2416_current); // I2C write data to register
// Battery Voltage Register > Charge Voltage = 3.8V (0x03, 0x3C)
I2C_write(2, BQ2416_voltage); // I2C write data to register
}
#pragma vector = USCI_B1_VECTOR
__interrupt void USCI_B1_ISR(void)
{
switch(__even_in_range(UCB1IV,12))
{
case 0: break; // Vector 0: No interrupts
case 2: break; // Vector 2: ALIFG
case 4: break; // Vector 4: NACKIFG
case 6: break; // Vector 6: STTIFG
case 8: break; // Vector 8: STPIFG
case 10: // Vector 10: RXIFG
if (UCB1STAT & UCNACKIFG) // send STOP if slave sends NACK
{
UCB1CTL1 |= UCTXSTP;
UCB1STAT &= ~UCNACKIFG;
}
break;
case 12: // Vector 12: TXIFG
if (B1_ByteCtr) // Check TX byte counter
{
UCB1TXBUF = *B1_Tx_Data++; // Load TX buffer
B1_ByteCtr--; // Decrement TX byte counter
}
else
{
UCB1CTL1 |= UCTXSTP; // I2C stop condition
UCB1IFG &= ~UCTXIFG; // Clear USCI_B1 TX int flag
}
default: break;
}
}