1.博主目前在做BMS小练习,用的是stm32f103+bq76920芯片+五节串联的18650三元锂电池,通过读写bq芯片的寄存器,获得五节电池的电压值和控制电池的充放电,以及主路上的电流采集,用以实现开路电压法+安时积分法进行SOC估计、控制充放电、防止过充过放和被动均衡。
2.bq76920芯片是一款模拟前端(AFE)芯片,遵循iic通信协议,一开始,我通过阅读数据手册,得知该款芯片的从机地址为0x08,注意,从地址是高位7bit,发送字节应该是:0x10(写)0x11(读),然后就实现通信了。
接下来,通过看时序图和寄存器地址,接收到了五节电池的电压值,但值却是10000多的值,这把我搞懵了,后来看了学习资料,原来是这个值是芯片传感器采到的值,还需要进行一定的计算转换成电压值(数据手册上也有,不过该部分是英文,我以为这个转换是在bq上就进行了的)。
最后,看了学习视频后,原来bq芯片的通信代码,TI公司官网上可以下载,而且根据不同的型号,把取各种值的代码都封装好了,还有该芯片是有CRC校验的,官网上的代码也是写好了的。
下面是我自己用来获取电压值测试的代码(用E2PROM)代码改的
uint8_t AT24Cxx_ReadByteData(uint8_t ADDR)
{
uint8_t Rxdata1=0;
uint8_t Rxdata2=0;
uint8_t Rxdata3=0;
uint8_t Rxdata4=0;
uint8_t Rxdata5=0;
uint8_t Rxdata6=0;
uint8_t Rxdata7=0;
uint8_t Rxdata8=0;
uint8_t Rxdata9=0;
uint8_t Rxdata10=0;
IIC_START();
IIC_SendByteData(0x10);
if(ACK!=IIC_WaitACK()){
IIC_Stop();
return 1;
}
IIC_SendByteData(ADDR);
if(ACK!=IIC_WaitACK()){
IIC_Stop();
return 2;
}
//IIC_Stop();
IIC_START();
IIC_SendByteData(0x11);
if(ACK!=IIC_WaitACK()){
IIC_Stop();
return 3;
}
Rxdata1=IIC_RxByteData(ACK);
//voalg = Rxdata;
//voalg = voalg<<8;
//printf("volage1:%d\n",voalg);
Rxdata2 = IIC_RxByteData(ACK);
Rxdata3=IIC_RxByteData(ACK);
Rxdata4=IIC_RxByteData(ACK);
Rxdata5=IIC_RxByteData(ACK);
Rxdata6=IIC_RxByteData(ACK);
Rxdata7=IIC_RxByteData(ACK);
Rxdata8=IIC_RxByteData(ACK);
Rxdata9=IIC_RxByteData(ACK);
Rxdata10=IIC_RxByteData(ACK);
//voalg = voalg|Rxdata;
IIC_Stop();
printf("rxdata1:%x\n",Rxdata1);
printf("rxdata2:%x\n",Rxdata2);
printf("rxdata3:%x\n",Rxdata3);
printf("rxdata4:%x\n",Rxdata4);
printf("rxdata5:%x\n",Rxdata5);
printf("rxdata6:%x\n",Rxdata6);
printf("rxdata7:%x\n",Rxdata7);
printf("rxdata8:%x\n",Rxdata8);
printf("rxdata9:%x\n",Rxdata9);
printf("rxdata10:%x\n",Rxdata10);
return 0;
}