让BQ34Z100电量计快速运行起来BMS

TI旗下的一款经典电量计BQ34Z100是一个可以支撑多种化学电池类型的专业电量计,我们可以用EV2400与BQStudio上位机软件来修改配置参数,建立必要的数学模型和化学模型.

「链接」

BQStudio软件


EV2500通讯模块

需要通讯模块可以点击这里:「链接」

也可以通过独立的MCU来写一段I2C读写程序来配置和修改必要的数据对应的寄存器值.

#include 
#include 

#define BQ34Z100_SLAVE_ADDR 0x55 // BQ34Z100的I2C从机地址

void i2c_init() {
  // 设置I2C引脚功能
  P1SEL |= BIT6 + BIT7; // I2C SDA和SCL引脚
  P1SEL2 |= BIT6 + BIT7;

  // 设置I2C模块
  UCB0CTL1 |= UCSWRST; // 复位I2C模块
  UCB0CTL0 = UCMST + UCMODE_3 + UCSYNC; // 主模式,I2C模式,同步模式
  UCB0CTL1 = UCSSEL_2 + UCSWRST; // 选择SMCLK作为时钟源,保持复位状态
  UCB0BR0 = 10; // 设置时钟分频,适当调整以满足I2C时钟要求
  UCB0BR1 = 0;
  UCB0I2CSA = BQ34Z100_SLAVE_ADDR; // 设置从机地址
  UCB0CTL1 &= ~UCSWRST; // 释放I2C模块
}

void i2c_write(uint8_t reg, uint8_t data) {
  while (UCB0CTL1 & UCTXSTP); // 等待上一个传输完成
  UCB0CTL1 |= UCTR + UCTXSTT; // 主模式写入开始位
  while (!(IFG2 & UCB0TXIFG)); // 等待TX缓冲区空
  UCB0TXBUF = reg; // 发送寄存器地址
  while (!(IFG2 & UCB0TXIFG)); // 等待TX缓冲区空
  UCB0TXBUF = data; // 发送数据
  while (!(IFG2 & UCB0TXIFG)); // 等待TX缓冲区空
  UCB0CTL1 |= UCTXSTP; // 主模式写入停止位
}

uint8_t i2c_read(uint8_t reg) {
  while (UCB0CTL1 & UCTXSTP); // 等待上一个传输完成
  UCB0CTL1 |= UCTR + UCTXSTT; // 主模式写入开始位
  while (!(IFG2 & UCB0TXIFG)); // 等待TX缓冲区空
  UCB0TXBUF = reg; // 发送寄存器地址
  while (!(IFG2 & UCB0TXIFG)); // 等待TX缓冲区空
  UCB0CTL1 &= ~UCTR; // 主模式读取开始位
  UCB0CTL1 |= UCTXSTT; // 重复开始位
  while (UCB0CTL1 & UCTXSTT); // 等待重复开始位发送完成
  UCB0CTL1 |= UCTXSTP; // 主模式读取停止位
  while (!(IFG2 & UCB0RXIFG)); // 等待接收数据
  return UCB0RXBUF; // 返回接收到的数据
}

void bq34z100_init() {
  // 初始化BQ34Z100
  i2c_write(0x00, 0x00); // 发送命令,选择控制寄存器
  i2c_write(0x01, 0x80); // 发送数据,使能BQ34Z100
}

uint16_t bq34z100_read_voltage() {
  // 读取电压寄存器
  uint8_t msb = i2c_read(0x04);
  uint8_t lsb = i2c_read(0x05);
  return (msb << 8) | lsb;
}

uint16_t bq34z100_read_current() {
  // 读取电流寄存器
  uint8_t msb = i2c_read(0x0A);
  uint8_t lsb = i2c_read(0x0B);
  return (msb << 8) | lsb;
}

void main(void) {
  WDTCTL = WDTPW + WDTHOLD; // 停用看门狗定时器
  i2c_init(); // 初始化I2C
  bq34z100_init(); // 初始化BQ34Z100

  while (1) {
    uint16_t voltage = bq34z100_read_voltage(); // 读取电压
    uint16_t current = bq34z100_read_current(); // 读取电流

    // 打印电压和电流
    printf("Voltage: %d mV
", voltage);
    printf("Current: %d mA
", current);

    __delay_cycles(1000000); // 延迟1秒
  }
}

不过我们还是有基本的思路才能利用好这个芯片

首先要了解这个芯片的特性:


然后大致了解一下这个芯片的电路架构



内部寄存器也是需要了解的




既然是电量计,那么误差特性也是要了解的


这款电量计还有一个上锁的功能,当然也要了解喔



全面都了解了,那么当然就需要开始实际操作了,如开始建立数学参数模型


逻辑流程图也应该了解


实际的电路图也看看



很多时候我们要从电气特性,应用条件,应用方法,以及逻辑流程,还有对不同化学电池的特性要充分了解并理解,才能开始用前面的通讯模块和BQStudio软件配置相当多的参数,这是一个长期的过程.

前面这些配置完成,等于完成了数学模型的建立,后面还有化学模型建立以及learning过程,这个将放到下一节里面讲解.


最后分享一下读取或者改写数据的C代码程序过程供给参考:

快速配置流程:

1. 连接硬件:将BQ34Z100电量计与Arduino或其他微控制器连接。连接时,确保正确连接电量计的SDA和SCL引脚到微控制器的对应引脚,并连接电量计的GND引脚到共地。

2. 初始化I2C总线:在代码中使用Wire库初始化I2C总线。

#include

void setup() {

Wire.begin(); // 初始化I2C总线

Serial.begin(9600); // 初始化串口通信

}

3. 配置电量计寄存器:通过I2C通信向BQ34Z100电量计的寄存器写入配置数据。以下是一些常见的配置参数及其对应的寄存器地址:

- 设定容量:使用命令0x06写入容量值到寄存器0x4A和0x4B。容量值以mAh为单位。

- 设定电流阈值:使用命令0x06写入电流阈值到寄存器0x10和0x11。电流阈值以mA为单位。

- 设定电池类型:使用命令0x06写入电池类型到寄存器0x3A和0x3B。电池类型的值可以在BQ34Z100的数据手册中找到。

void configureBQ34Z100() {

// 设置容量为3000mAh

writeRegister(0x4A, 0x0B);

writeRegister(0x4B, 0xB8);

// 设置电流阈值为500mA

writeRegister(0x10, 0x01);

writeRegister(0x11, 0xF4);

// 设置电池类型为Li-ion

writeRegister(0x3A, 0x00);

writeRegister(0x3B, 0x01);

}

void writeRegister(byte address, byte value) {

Wire.beginTransmission(BQ34Z100_ADDRESS);

Wire.write(address);

Wire.write(value);

Wire.endTransmission();

}

在上述代码中,`configureBQ34Z100()`函数用于配置BQ34Z100电量计的寄存器。`writeRegister()`函数用于向指定的寄存器地址写入数据。

4. 读取电量计数据:使用I2C通信从BQ34Z100电量计的寄存器读取电量计数据。以下是一些常见的数据读取操作:

- 读取电池电压:使用命令0x02从寄存器0x08和0x09读取电池电压。电压值以mV为单位。

- 读取电池电流:使用命令0x02从寄存器0x0C和0x0D读取电池电流。电流值以mA为单位。

- 读取剩余容量:使用命令0x02从寄存器0x02和0x03读取剩余容量。容量值以mAh为单位。

float readBatteryVoltage() {

Wire.beginTransmission(BQ34Z100_ADDRESS);

Wire.write(0x08);

Wire.endTransmission(false);

Wire.requestFrom(BQ34Z100_ADDRESS, 2);

byte msb = Wire.read();

byte lsb = Wire.read();

int rawValue = (msb << 8) | lsb;

float voltage = rawValue * 0.001;

return voltage;

}

float readBatteryCurrent() {

Wire.beginTransmission(BQ34Z100_ADDRESS);

Wire.write(0x0C);

Wire.endTransmission(false);

Wire.requestFrom(BQ34Z100_ADDRESS, 2);

byte msb = Wire.read();

byte lsb = Wire.read();

int rawValue = (msb << 8) | lsb;

float current = rawValue * 0.001;

return current;

}

float readRemainingCapacity() {

Wire.beginTransmission(BQ34Z100_ADDRESS);

Wire.write(0x02);

Wire.endTransmission(false);

Wire.requestFrom(BQ34Z100_ADDRESS, 2);

byte msb = Wire.read();

byte lsb = Wire.read();

int rawValue = (msb << 8) | lsb;

float capacity = rawValue * 0.1;

return capacity;

}

在上述代码中,`readBatteryVoltage()`函数用于读取电池电压,`readBatteryCurrent()`函数用于读取电池电流,`readRemainingCapacity()`函数用于读取剩余容量。

请注意,确保正确连接BQ34Z100电量计和正确配置I2C总线。

展开阅读全文

页面更新:2024-05-03

标签:电量   寄存器   缓冲区   初始化   电流   电压   容量   电池   快速   模式   数据

1 2 3 4 5

上滑加载更多 ↓
推荐阅读:
友情链接:
更多:

本站资料均由网友自行发布提供,仅用于学习交流。如有版权问题,请与我联系,QQ:4156828  

© CopyRight 2020-2024 All Rights Reserved. Powered By 71396.com 闽ICP备11008920号-4
闽公网安备35020302034903号

Top