TI旗下的一款经典电量计BQ34Z100是一个可以支撑多种化学电池类型的专业电量计,我们可以用EV2400与BQStudio上位机软件来修改配置参数,建立必要的数学模型和化学模型.
「链接」
需要通讯模块可以点击这里:「链接」
也可以通过独立的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
本站资料均由网友自行发布提供,仅用于学习交流。如有版权问题,请与我联系,QQ:4156828
© CopyRight 2020-2024 All Rights Reserved. Powered By 71396.com 闽ICP备11008920号-4
闽公网安备35020302034903号