微波EDA网,见证研发工程师的成长!
首页 > 研发问答 > 硬件电路设计 > TI电源管理交流 > 应用TI的bq76PL455 前端模拟IC遇到问题,无法采集到电池电压

应用TI的bq76PL455 前端模拟IC遇到问题,无法采集到电池电压

时间:10-02 整理:3721RD 点击:

本公司需要应用bq76PL455IC进行电池管理电压采集,在使用中根据bq76PL455A-Q1 Example Code 进行配置,单片机能与之通信,可以配置控制IO口,清除错语,测试均衡控制信号测试,都没有问题,但是一直无法采集到电压:
 

U16 nSent, nRead;// nTopFound = 0;
U16 nDev_ID;// nGrp_ID;
U8 cnt_test = 0;
U8 bFrame[132];
U16 crc;
U32 wTemp = 0;

WakeUp_PL455();
__delay_ms(10);

nSent = PL455_WriteReg(0, 107, 0x8000, 2, FRMWRT_ALL_NR); // clear all fault summary flags
nSent = PL455_WriteReg(0, 81, 0x38, 1, FRMWRT_ALL_NR); // clear fault flags in the system status register
nSent = PL455_WriteReg(0, 14, 0x19, 1, FRMWRT_ALL_NR); // set auto-address mode on all boards
nSent = PL455_WriteReg(0, 12, 0x08, 1, FRMWRT_ALL_NR); // enter auto address mode on all boards, the next write to this ID will be its address

for (nDev_ID = 0; nDev_ID < TOTALBOARDS; nDev_ID++)
{
nSent = PL455_WriteReg(nDev_ID, 10, nDev_ID, 1, FRMWRT_ALL_NR); // send address to each board
}


nSent = PL455_WriteReg(0, 16, 0x1080, 2, FRMWRT_SGL_NR);
// Clear all faults
nSent = PL455_WriteReg(0, 82, 0xffc0, 2, FRMWRT_SGL_NR); // clear all fault summary flags
nSent = PL455_WriteReg(0, 81, 0x38, 1, FRMWRT_SGL_NR); // clear fault flags in the system status register
////////////////////////////////////////////////////////////////////////////////////////////////
//nSent = PL455_WriteReg(0, 60, 0x00, 1, FRMWRT_SGL_NR);
nSent = PL455_WriteReg(0, 61, 0x00, 1, FRMWRT_SGL_NR); // set 0 initial delay

nDev_ID = 0;
nSent = PL455_WriteReg(nDev_ID, 62, 0xBC, 1, FRMWRT_SGL_NR); // set 99.92us ADC sampling period

nDev_ID = 0;
nSent = PL455_WriteReg(nDev_ID, 7, 0x00, 1, FRMWRT_SGL_NR); // set no oversampling period

nDev_ID = 0;
nSent = PL455_WriteReg(nDev_ID, 81, 0x38, 1, FRMWRT_SGL_NR); // clear fault flags in the system status register
nRead = PL455_ReadReg(nDev_ID, 81, &wTemp, 1, 4); // 0ms timeout

nSent = PL455_WriteReg(nDev_ID, 82, 0xFFC0, 2, FRMWRT_SGL_NR); // clear all fault summary flags
nRead = PL455_ReadReg(nDev_ID, 82, &wTemp, 1, 4); // 0ms timeout

nSent = PL455_WriteReg(0, 13, 0x08, 1, FRMWRT_SGL_NR); // set number of cells to 8
nSent = PL455_WriteReg(0, 3, 0x00FF03C0, 4, FRMWRT_SGL_NR); // select all cell channels 1-8, AUX channels 0 and 1, and internal digital die and internal analog die temperatures

nDev_ID = 0;
nSent = PL455_WriteReg(nDev_ID, 144, 0xD1EC, 2, FRMWRT_SGL_NR); // set OV threshold = 4.1000V
nSent = PL455_WriteReg(nDev_ID, 142, 0x6148, 2, FRMWRT_SGL_NR); // set UV threshold = 1.9000V

nSent = PL455_WriteReg(0, 144, 0xD1EC, 2, FRMWRT_ALL_NR); // set OV threshold = 4.1000V
nSent = PL455_WriteReg(0, 142, 0x6148, 2, FRMWRT_ALL_NR); // set UV threshold = 1.9000V

nSent = PL455_WriteReg(0, 2, 0x02, 1, FRMWRT_ALL_NR); // send sync sample command

nSent = PL455_WriteReg(0, 2, 0x00, 1, FRMWRT_ALL_NR); // send sync sample command

nSent = PL455_WriteReg(0, 13, 0x08, 1, FRMWRT_SGL_NR); // set number of cells to 8
nSent = PL455_WriteReg(0, 3, 0x00FF03C0, 4, FRMWRT_SGL_NR); // select all cell channels 1-8, AUX channels 0 and 1, and internal digital die and internal analog die temperatures

nDev_ID = 0;

nSent = PL455_WriteReg(nDev_ID, 2, 0x20, 1, FRMWRT_SGL_R); // send sync sample command //发送采样命令
nSent = WaitRespFrame(bFrame, 27, 4); // 24 bytes data + packet header + CRC, 0ms timeout //读取采集数据
while(1)
{////发送采集命令后在此查询接收到的数据(1)//接收断点1
PIN_LED = !PIN_LED;
__delay_ms(2000);
ClrWdt();
Uart_SendChar1(rx_buf,27); //打印接收到的数据
}

在接收断点1处,接收到来自于前端IC传过来的数据为:(8路节电池电压和四路AUX电压)
 17 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 87 7C 00 00 17 97
 17 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 86 eC 00 00 16 46

17 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 86 f4 00 00 96  41

.......

//一直不明白为什么返回来的数据电压点都不对!电路板是官网的DEMO,只是控制端用单片机来处理。
由于项目紧急,只能在论坛上请求支持! 期待TI的技术支持能给以帮助!

U16 nSent, nRead;// nTopFound = 0;
U16 nDev_ID;// nGrp_ID;
U8 cnt_test = 0;
U8 bFrame[132];
U16 crc;
U32 wTemp = 0;

WakeUp_PL455();
__delay_ms(10);

nSent = PL455_WriteReg(0, 107, 0x8000, 2, FRMWRT_ALL_NR); // clear all fault summary flags
nSent = PL455_WriteReg(0, 81, 0x38, 1, FRMWRT_ALL_NR); // clear fault flags in the system status register
nSent = PL455_WriteReg(0, 14, 0x19, 1, FRMWRT_ALL_NR); // set auto-address mode on all boards
nSent = PL455_WriteReg(0, 12, 0x08, 1, FRMWRT_ALL_NR); // enter auto address mode on all boards, the next write to this ID will be its address

for (nDev_ID = 0; nDev_ID < TOTALBOARDS; nDev_ID++)
{
nSent = PL455_WriteReg(nDev_ID, 10, nDev_ID, 1, FRMWRT_ALL_NR); // send address to each board
}


nSent = PL455_WriteReg(0, 16, 0x1080, 2, FRMWRT_SGL_NR);
// Clear all faults 
nSent = PL455_WriteReg(0, 82, 0xffc0, 2, FRMWRT_SGL_NR); // clear all fault summary flags
nSent = PL455_WriteReg(0, 81, 0x38, 1, FRMWRT_SGL_NR); // clear fault flags in the system status register
////////////////////////////////////////////////////////////////////////////////////////////////
//nSent = PL455_WriteReg(0, 60, 0x00, 1, FRMWRT_SGL_NR);
nSent = PL455_WriteReg(0, 61, 0x00, 1, FRMWRT_SGL_NR); // set 0 initial delay

nDev_ID = 0;
nSent = PL455_WriteReg(nDev_ID, 62, 0xBC, 1, FRMWRT_SGL_NR); // set 99.92us ADC sampling period

nDev_ID = 0;

//建议8次oversample。
nSent = PL455_WriteReg(nDev_ID, 7, 0x00, 1, FRMWRT_SGL_NR); // set no oversampling period

nDev_ID = 0;
nSent = PL455_WriteReg(nDev_ID, 81, 0x38, 1, FRMWRT_SGL_NR); // clear fault flags in the system status register
nRead = PL455_ReadReg(nDev_ID, 81, &wTemp, 1, 4); // 0ms timeout

nSent = PL455_WriteReg(nDev_ID, 82, 0xFFC0, 2, FRMWRT_SGL_NR); // clear all fault summary flags
nRead = PL455_ReadReg(nDev_ID, 82, &wTemp, 1, 4); // 0ms timeout

nSent = PL455_WriteReg(0, 13, 0x08, 1, FRMWRT_SGL_NR); // set number of cells to 8
nSent = PL455_WriteReg(0, 3, 0x00FF03C0, 4, FRMWRT_SGL_NR); // select all cell channels 1-8, AUX channels 0 and 1, and internal digital die and internal analog die temperatures

nDev_ID = 0;
nSent = PL455_WriteReg(nDev_ID, 144, 0xD1EC, 2, FRMWRT_SGL_NR); // set OV threshold = 4.1000V
nSent = PL455_WriteReg(nDev_ID, 142, 0x6148, 2, FRMWRT_SGL_NR); // set UV threshold = 1.9000V

nSent = PL455_WriteReg(0, 144, 0xD1EC, 2, FRMWRT_ALL_NR); // set OV threshold = 4.1000V 
nSent = PL455_WriteReg(0, 142, 0x6148, 2, FRMWRT_ALL_NR); // set UV threshold = 1.9000V

//无效,建议删除

nSent = PL455_WriteReg(0, 2, 0x02, 1, FRMWRT_ALL_NR); // send sync sample command

//无效,建议删除

nSent = PL455_WriteReg(0, 2, 0x00, 1, FRMWRT_ALL_NR); // send sync sample command

//重复配置可以省略

nSent = PL455_WriteReg(0, 13, 0x08, 1, FRMWRT_SGL_NR); // set number of cells to 8
nSent = PL455_WriteReg(0, 3, 0x00FF03C0, 4, FRMWRT_SGL_NR); // select all cell channels 1-8, AUX channels 0 and 1, and internal digital die and internal analog die temperatures

nDev_ID = 0;

//发送sample and store 指令, 并delay 5ms,

nSend = PL455_WriteReg(0, 2, 0x00, 1, FRMWRT_ALL_NR);

_delay_ms(5);

nSent = PL455_WriteReg(nDev_ID, 2, 0x20, 1, FRMWRT_SGL_R); // send sync sample command //发送采样命令

nSent = WaitRespFrame(bFrame, 27, 4); // 24 bytes data + packet header + CRC, 0ms timeout //读取采集数据

while(1)
{////发送采集命令后在此查询接收到的数据(1)//接收断点1
PIN_LED = !PIN_LED;
__delay_ms(2000);
ClrWdt();
Uart_SendChar1(rx_buf,27); //打印接收到的数据
}

在接收断点1处,接收到来自于前端IC传过来的数据为:(8路节电池电压和四路AUX电压)
 17 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 87 7C 00 00 17 97
 17 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 86 eC 00 00 16 46

17 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 86 f4 00 00 96  41

.......

//一直不明白为什么返回来的数据电压点都不对!电路板是官网的DEMO,只是控制端用单片机来处理。
由于项目紧急,只能在论坛上请求支持! 期待TI的技术支持能给以帮助!

谢谢TI员工的回复!

还有个小问题,是关于把数据写入EEPORM的,是否是在初始化的前面写入两条指令如下:(就是把寄存器的值也写入了EEPROM,当电池包断电后,再有电时,这些寄存器的值会从EEPROM那边读过来,而单片机不用再配置)

U8 i,bFrame[132];
U16 nSent, nRead;
U16 nDev_ID;
U32 wTemp = 0;

ClrWdt();

WakeUp_PL455();
__delay_ms(20);

nSent = PL455_WriteReg(0, 130, 0x8C2DB194, 4, FRMWRT_ALL_NR);      //写KEY1

__delay_ms(200);
nSent = PL455_WriteReg(0, 252, 0xA375E60F, 4, FRMWRT_ALL_NR); //get register to eeprom   //写KEY2

__delay_ms(200);

nSent = PL455_WriteReg(0, 107, 0x8000, 2, FRMWRT_ALL_NR); // clear all fault summary flags
nSent = PL455_WriteReg(0, 81, 0x38, 1, FRMWRT_ALL_NR); // clear fault flags in the system status register
nSent = PL455_WriteReg(0, 82, 0xFFC0, 2, FRMWRT_ALL_NR); // clear all fault summary flags

nSent = PL455_WriteReg(0, 14, 0x19, 1, FRMWRT_ALL_NR);
nSent = PL455_WriteReg(0, 12, 0x08, 1, FRMWRT_ALL_NR);
for (nDev_ID = 0; nDev_ID < TOTALBOARDS; nDev_ID++)
{
nSent = PL455_WriteReg(nDev_ID, 10, nDev_ID, 1, FRMWRT_ALL_NR);
}

nSent = PL455_WriteReg(0, 40, 0, 1, FRMWRT_SGL_NR); //禁用通信故障检测
nSent = PL455_WriteReg(0, 16, 0x1080, 2, FRMWRT_SGL_NR);

nSent = PL455_WriteReg(0, 19, 0x08, 1, FRMWRT_SGL_NR);
nSent = PL455_WriteReg(0, 61, 0x00, 1, FRMWRT_SGL_NR); // set 0 initial delay

 ...................

....................

.....................

END  Bq455_Init

是否在初始寄存器这前,写入KEY1 和KEY2之后,到初始化END Bq455_Init之间配置的寄存器的值都也存到了EEPROM当中,下次电池包断电后,不需要再配置Bq455了?

烧写就是把当前ram里的配置值写入到eeprom , 下次上电自动载入。

但是注意

1 . 不是所有寄存器都有对应的eeprom 状态寄存器 故障寄存器。还有一些测试寄存器 没有对应的eeprom, 如果要修改 依然要上电就配置 具体参照dataflash的描述

2. 地址寄存器也会被烧写 下次启动会自动载入eeprom的地址 , 如果是通过菊花链链接 而不是在同一个板子上的话 启动需要软件再做一次autoaddress分配地址。如果芯片发生复位 地址会变成eeprom内的地址,如果系统干扰导致芯片复位  一定要注意处理可能出现的地址变化的状况 做一次autoaddress

3. 烧写次数不超过5次,一般是产线下线检测和校准的之后做烧写即可

如果芯片发生复位 地址会变成eeprom内的地址? 此话怎么理解,不太明白,还有就是dataflash的描述的文档,方便留一个链接地址吗?非常感谢了

复位 会重新载入EEPROM到RAM。

http://www.ti.com/lit/ds/symlink/bq76pl455a-q1.pdf 

这个文档早前已经下载过的,但是对EEprom的存储描述得不是很详细,比如我在 bq76PL455A Q1 Software Design Reference PDF中看到的EEPROM操作方式是:

1. Write Magic Number 1.         //写入魔术值1     //94 00 82 8C2DB194 62B1
2. Write Magic Number 2.         //写入魔术值2     //94 00 FC A375E60F BC27
3. Save register values to EEPROM.                   //Write RAM to EEPROM:   // 91 00 0C 10 2830    ==>Device:00   寄存器地址 0x0C  data:10  //是否这个data的值不是                                                                                       //实际写入的值,而是操作EEPROM_BIT的写法? 没有看到PDF有相关的说明

4. Wait until save of register values is complete  //__delay_ms(200);

比如,需要把0xoc的寄存器配置成0X55;然后把它保存到EEPROM中,是否该这样操作:
1.先初始化BQ455,分配地址,清除错误

2.写入 0xoc的寄存器值为0X55

3......................

4. 94 00 82 8C2DB194 62B1   //写入魔术值1 

5.94 00 FC A375E60F BC27   //写入魔术值2 

6.91 00 0C 10 2830                  //0x0c  的值写入EEPROM //此处的 0x10 表示要把 0x0c的值0x55写入EEPROM中,而不是说把 0x10写入到EEPROM中的吧?

7.__delay_ms(200);

END bq455_init

91 00 0C 10 2830 是用来使能EEPROM的烧写。

写入magic就是让455A将当前寄存器的值保存到EEPROM中, 是整块区域所有的都保存。不能单个bit的写。

0x0c没有EEPROM。无法保存。请看page66的表格确认你要改的寄存器有没有EEPROM.

另外,烧写前请清除Customer check sum 错误。

好的,非常感谢wang's!

请问这是什么软件编译的?CCS吗

您好,请你是用CCS写的程序吗?

TI 例程是用CCS的。 

你好,请问返回的电压和温度数据具体是哪些值?数据头是那几个量,CRC是那几个量?

你好,我现在用MCU跟PL455通信时,读到器件状态寄存器(81)的数据为0x01,我看这的解释是系统正在进行初始化,然后我要是给寄存器2发送采集命令0x20的话,采集不到数据,455的Fault引脚为低电平;然后我要是给寄存器(81)写0x39的话,MCU有时就能读到数据,有时读不到,并且读到的电压数据都不对(实际的电池电压为3.8V,采集回来的显示电压为10mv~40mV),请问这是什么原因,为什么芯片会一直在进行初始化?

你好,我现在用MCU跟PL455通信时,读到器件状态寄存器(81)的数据为0x01,我看这的解释是系统正在进行初始化,然后我要是给寄存器2发送采集命令0x20的话,采集不到数据,455的Fault引脚为低电平;然后我要是给寄存器(81)写0x39的话,MCU有时就能读到数据,有时读不到,并且读到的电压数据都不对(实际的电池电压为3.8V,采集回来的显示电压为10mv~40mV),请问这是什么原因,为什么芯片会一直在进行初始化?

帧头是1个byte, 返回的是data 长度-1, CRC是最后两个byte。

我的按这个加大了OVERSMPL ,做了延迟,读出来来的数据也都是采样数据都是0

现在数据是第一个是0x1F,中间都是0x00,第34个数据是0xA5,第35个数据是0xC4,我设置的通道是采样16节电池电压;另外我请问下455的VM引脚是不是要输出-5V才正常?我的没有输出,请问这是什么情况?

1F是帧头,1F+1=32,是指你返回的有效数据是32个。第34个,第35个是CRC码。你试试中间接个电压

我知道数据传回来的格式;我就是接的电压测试的,实际电压是3.8V,采集回来的都为0,所以才有这疑问。

在调试455,求例程

Copyright © 2017-2020 微波EDA网 版权所有

网站地图

Top