1 BQ32Z100电池调试记录
实际项目中使用了BQ32Z100芯片,进行电池电量、电压、电流等参数,BQ34Z100-G1 器件提供多个接口选项, 其中包括一个I2C 从接口、一个 HDQ 从接口、 一个或四个直接 LED接口以及一个警报输出引脚。此外, BQ34Z100-G1 还支持外部端口扩展器, 连接四个以上的 LED。
MCU型号为STM32L151CBTx,采用IO模拟时序匹对IIC接口时序,对BQ32Z100芯片进行读取,该案例时序可以类比TI公司其他I2C接口芯片的读写操作。接下来,就对调试过程进行说明。
附上本文使用工程文件,下载链接,含代码工程、datasheet、说明文档等
https://download.csdn.net/download/li171049/90562312
2 原理图设计
连接到MCU IIC2管脚,PB10 PB11,这里可以供软件选择,是否使用MCU片上IIC2,或者使用模拟IO进行模拟时序操作。
IIC管脚需要做上拉处理,然后通过接插件连接到电池,需要说明的是BQ32Z100在电池内部。
使用串口1作为调试串口。
好了,原理图就是这样比较简单。
3 调试过程
使用STM32CubeIDE Version: 1.17.0搭建工程,
软件调试过程比较心累,这里需要记录一下。
第1天
刚开始使用模拟IO的iic时序,做好代码设计,进行调试,结果是从机(BQ34Z100)一直没有从机ACK信号。怀疑地址错误,各种替换地址,结果还是一样。
第2天
后续偶然有思路怀疑硬件工程师搞错了接线
赶紧调换SCL/SDA接线,试试
发现数据对上了。
4 模拟时序
采用iic模拟时序的方式,关键代码如下:
/**
* @brief BQ34Z100 I2C起始信号
* @param NONE
* @return NONE
*/
void bq34z100_i2c_start(void)
{
SDA_1();
I2CDELAY();
SCL_1();
I2CDELAY();
SDA_0();
I2CDELAY();
SCL_0();
I2CDELAY();
}
/**
* @brief BQ34Z100 I2C停止信号
* @param NONE
* @return NONE
*/
void bq34z100_i2c_stop(void)
{
SDA_0();
I2CDELAY();
SCL_1();
I2CDELAY();
SDA_1();
I2CDELAY();
}
/**
* @brief BQ34Z100 I2C发送字节
* @param u8 data 发送数据
* @return ACK
*/
u8 bq34z100_i2c_send_byte(u8 data)
{
u8 bits, temp, ack;
u16 wait_cnt;
SCL_0();
temp = data;
bits = 0x08;
while (bits != 0x00) {
if (temp & 0x80)
SDA_1();
else
SDA_0();
I2CDELAY();
SCL_1();
wait_cnt = 0;
while ((BQ34Z100_GPIO_SCL->IDR & BQ34Z100_SCL_pin) == 0) {
wait_cnt++;
if (wait_cnt > 200) {
bq34z100_i2c_stop();
return (0);
}
}
I2CDELAY();
temp = (temp << 1);
SCL_0();
bits = (bits - 1);
}
I2CDELAY();
SDA_1();
SCL_1();
wait_cnt = 0;
while ((BQ34Z100_GPIO_SCL->IDR & BQ34Z100_SCL_pin) == 0) {
wait_cnt++;
if (wait_cnt > 200) {
bq34z100_i2c_stop();
return (0);
}
}
I2CDELAY();
ack = (((BQ34Z100_GPIO_SDA->IDR & BQ34Z100_SDA_pin) == 0) ? 0 : 1);
SCL_0();
if (ack)
return (1);
else
return (0);
}
/**
* @brief BQ34Z100 I2C接收字节
* @param u8 ack 是否响应ACK
* @return u8 data 接收数据
*/
u8 bq34z100_i2c_rev_byte(u8 ack)
{
u8 bits, data = 0;
SDA_1();
bits = 0x08;
while (bits > 0) {
SCL_1();
while ((BQ34Z100_GPIO_SCL->IDR & BQ34Z100_SCL_pin) == 0)
I2CDELAY();
data = (data << 1);
if (BQ34Z100_GPIO_SDA->IDR & BQ34Z100_SDA_pin)
data = (data + 1);
SCL_0();
I2CDELAY();
bits = (bits - 1);
}
if (ack)
SDA_0();
else
SDA_1();
SCL_1();
I2CDELAY();
SCL_0();
SDA_1();
return (data);
}
5 关键记录
在板子上的调试记录如下,可以看到数据都是正确的了。
其中数据信息如下表所示,其中temperature表示温度,单位位K,charge_state表示电量百分比,比较重要的参数,full_charge_cap表示电池容量,remain_cap表示剩余电池容量,voltage表示电池电压,current表示电池电流,flag表示电池运行标识。
针对电流的描述如下:此只读命令对返回一个有符号整数值,即流经检测电阻器的电流。它每 1 秒更新一次。单位为每位 1 mA,除非选择 X10 模式。在 X10 模式下,单位为 10 mA单位为 1mA。但是,如果设置了 PackConfiguration [SCALED],则单位已缩放。
通过校准过程。实际的刻度未在设备中设置,SCALED 只是一个指示标志。
针对电池状态,这里有需要读取的数据,针对电池过热,以及充电状态指示,都需要状态显示。
OTC:检测到充电过热情况。设置 True 时
OTD:检测到放电条件下的过热。设置 True 时
BATHI:电池高位,表示电池电压高。有关以下内容,请参阅数据闪存 BATTERY HIGH 参数阈值设置。
BATLOW:电池电量不足位,表示电池电量不足tage 情况。有关以下内容,请参阅数据闪存 BATTERY LOW 参数阈值设置。
CHG_INH:充电抑制:无法开始充电。请参阅数据闪光 [Charge Inhibit Temp Low, Charge Inhibit TempHigh] 。设置 True 时
XCHG:不允许充电
RSVD:保留
FC:检测到充满电。当达到充电终止时设置 FC,并且 FC 设置百分比 = – 1(有关详细信息,请参阅第 7.2.10 节)或 StateOfCharge() 大于 FC Set% 且 FC Set% 不是 – 1。设置 True 时
CHG:允许(快速)充电。设置 True 时
OCVTAKEN:进入 RELAX 模式时清除,并在 RELAX 模式下执行 OCV 测量时设置为 1。
ISD:检测到内部短路。True 时
SOC1:已达到充电状态阈值1。当设置时为真。
SOCF:已达到充电状态最终阈值。当设置时为真。
DSG:检测到放电。当设置时为真。
附上本文使用工程文件,下载链接,含代码工程、datasheet、说明文档等
https://download.csdn.net/download/li171049/90562312