主题中讨论的其他器件: BQ79616
大家好
我们的最终设计是使用79616、但在我们购买开发板时、我们又购买了79656开发板。
我当前使用一个 MCU 通过 UART 与79656进行通信。 现在可以唤醒79656芯片、但无法读取79656的任何寄存器。 我已经配置了主 ADC、但无法从79656读取任何数据。 下面是我的主代码(79616驱动程序)。
测试中只有一个79656开发板。 请给我一个帮助,谢谢!
此致、
//*****
//自动寻址序列
//*****
空 AutoAddress()
{
//虚拟写入 SNCHRONIZE 所有菊花链器件 DLL (如果在此之前发生器件复位)
WriteReg (0、OTP_ECC_DATAIN1、0x00、1、FRMWRT_ALL_W);
WriteReg (0、OTP_ECC_DATAIN2、0x00、1、FRMWRT_ALL_W);
WriteReg (0、OTP_ECC_DATAIN3、0x00、1、FRMWRT_ALL_W);
WriteReg (0、OTP_ECC_DATAIN4、0x00、1、FRMWRT_ALL_W);
WriteReg (0、OTP_ECC_DATAIN5、0x00、1、FRMWRT_ALL_W);
WriteReg (0、OTP_ECC_DATAIN6、0x00、1、FRMWRT_ALL_W);
WriteReg (0、OTP_ECC_DATAIN7、0x00、1、FRMWRT_ALL_W);
WriteReg (0、OTP_ECC_DATAIN8、0x00、1、FRMWRT_ALL_W);
//启用自动寻址模式
WriteReg (0、CONTROL1、0x01、1、FRMWRT_ALL_W);
//为每个板设置地址
for (currentBoard=0;currentBoard<TOTALBOARDS;currentBoard++)
{
WriteReg (0、DIR0_ADDR、电流板、1、FRMWRT_ALL_W);
}
WriteReg (0、COMM_CTRL、0x02、1、FRMWRT_ALL_W); //首先将所有内容设置为堆栈设备
if (TOTALBOARDS=1)//如果只有1个板、则它是栈的底部和顶部、因此应将其更改为这些
{
WriteReg (0、COMM_CTRL、0x01、1、FRMWRT_SGL_W);
}
else //否则分别设置栈的底部和顶部
{
WriteReg (0、COMM_CTRL、0x00、1、FRMWRT_SGL_W);
WriteReg (TOTALBOARDS-1、COMM_CTRL、0x03、1、FRMWRT_SGL_W);
}
//SYNCRHONIZE 具有抛出式读取功能的 DLL
ReadReg (0、OTP_ECC_DATAIN1、Response_frame2、1、0、 FRMWRT_ALL_R);
ReadReg (0、OTP_ECC_DATAIN2、Response_frame2、1、0、 FRMWRT_ALL_R);
ReadReg (0、OTP_ECC_DATAIN3、Response_frame2、1、0、 FRMWRT_ALL_R);
ReadReg (0、OTP_ECC_DATAIN4、Response_frame2、1、0、 FRMWRT_ALL_R);
ReadReg (0、OTP_ECC_DATAIN5、Response_frame2、1、0、 FRMWRT_ALL_R);
ReadReg (0、OTP_ECC_DATAIN6、Response_frame2、1、0、 FRMWRT_ALL_R);
ReadReg (0、OTP_ECC_DATAIN7、Response_frame2、1、0、 FRMWRT_ALL_R);
ReadReg (0、OTP_ECC_DATAIN8、Response_frame2、1、0、 FRMWRT_ALL_R);
/*//可选:回读所有设备地址
for (currentBoard=0;currentBoard<TOTALBOARDS;currentBoard++)
{
ReadReg (currentBoard、DIR0_ADDR、Response_frame2、1、0、 FRMWRT_SGL_R);
printf ("board %d\n"、response_frame2[4]);
}*/
//从启动状态重置所有 COMM 故障条件
WriteReg (0、FAULT_RST2、0x03、1、FRMWRT_ALL_W);
返回;
}
//********
//结束自动寻址序列
//********
//*****
//写入和读取函数
//*****
//格式化写入数据,发送到
//与帧的其余部分组合
int WriteReg (byte bid、uint16_t wAddr、uint64_t dwData、字节 bLen、字节 bWriteType){
//器件地址、寄存器起始地址、数据字节、数据长度、写入类型(单个、 广播、堆栈)
Bres = 0;
memset (bBuf、0、sizeof (bBuf));
开关(bLen){
情形1:
bBuf[0]= dwData & 0x00000000000000FF;
bres = WriteFrame (bid、wAddr、bBuf、1、bWriteType);
中断;
情形2:
bBuf[0]=(dwData & 0x00000000FF00)>>8;
bBuf[1]= dwData & 0x00000000000000FF;
bres = WriteFrame (bid、wAddr、bBuf、2、bWriteType);
中断;
情形3:
bBuf[0]=(DwData & 0x0000000000FF0000)>>16;
bBuf[1]=(dwData & 0x00000000FF00)>>8;
bBuf[2]= dwData & 0x00000000000000FF;
bres = WriteFrame (bid、wAddr、bBuf、3、bWriteType);
中断;
情形4:
bBuf[0]=(dwData & 0x0000FF000000)>>24;
bBuf[1]=(dwData & 0x0000000000FF0000)>> 16;
bBuf[2]=(dwData & 0x00000000FF00)>>8;
bBuf[3]= dwData & 0x00000000000000FF;
bres = WriteFrame (bid、wAddr、bBuf、4、bWriteType);
中断;
情形5:
bBuf[0]=(DwData & 0x000000FF00000000)>> 32;
bBuf[1]=(dwData & 0x0000FF000000)>> 24;
bBuf[2]=(dwData & 0x0000000000FF0000)>>16;
bBuf[3]=(dwData & 0x00000000FF00)>>8;
bBuf[4]= dwData & 0x00000000000000FF;
bres = WriteFrame (bid、wAddr、bBuf、5、bWriteType);
中断;
情况6:
bBuf[0]=(dwData & 0x0000FF0000000000)>> 40;
bBuf[1]=(dwData & 0x000000FF00000000)>>32;
bBuf[2]=(dwData & 0x0000FF000000)>> 24;
bBuf[3]=(dwData & 0x0000000000FF0000)>>16;
bBuf[4]=(dwData & 0x00000000FF00)>>8;
bBuf[5]= dwData & 0x00000000000000FF;
bres = WriteFrame (bid、wAddr、bBuf、6、bWriteType);
中断;
情形7:
bBuf[0]=(DwData & 0x00FF000000000000)>> 48;
bBuf[1]=(dwData & 0x0000FF0000000000)>> 40;
bBuf[2]=(dwData & 0x000000FF00000000)>>32;
bBuf[3]=(dwData & 0x0000FF000000)>>24;
bBuf[4]=(dwData & 0x0000000000FF0000)>>16;
bBuf[5]=(dwData & 0x00000000FF00)>>8;
bBuf[6]= dwData & 0x00000000000000FF;
bres = WriteFrame (bid、wAddr、bBuf、7、bWriteType);
中断;
情形8:
bBuf[0]=(dwData & 0xFF0000000000)>>56;
bBuf[1]=(dwData & 0x00FF00000000)>> 48;
bBuf[2]=(dwData & 0x0000FF0000000000)>> 40;
bBuf[3]=(dwData & 0x000000FF00000000)>>32;
bBuf[4]=(dwData & 0x0000FF000000)>>24;
bBuf[5]=(dwData & 0x0000000000FF0000)>>16;
bBuf[6]=(dwData & 0x00000000FF00)>>8;
bBuf[7]= dwData & 0x00000000000000FF;
bres = WriteFrame (bid、wAddr、bBuf、8、bWriteType);
中断;
默认值:
中断;
}
返回表述;
}
//生成命令帧
int WriteFrame (byte bid、uint16_t wAddr、字节* pData、字节 bLen、字节 bWriteType){
int bPktLen = 0;
uint8_t * pBuf = pFrame;
memset (pFrame、0x7F、sizeof (pFrame));
*pBuf++= 0x80 |(bWriteType)|(bWriteType & 0x10)? bLen - 0x01:0x00);//如果是写入,则仅包括 blen;写入为0x90、0xB0、0xD0
如果(bWriteType == FRMWRT_SGL_R || bWriteType == FRMWRT_SGL_W)
{
*pBuf++=(BID & 0x00FF);
}
* pBuf++=(wAddr & 0xFF00)>> 8;
* pBuf++= wAddr & 0x00FF;
while (blen-)
*pBuf++=*pData++;
bPktLen = pBuf - pFrame;
wCRC = CRC16 (pFrame、bPktLen);
*pBuf++= wCRC & 0x00FF;
* pBuf++=(wCRC & 0xFF00)>> 8;
bPktLen += 2;
//这似乎偶尔会从帧中删除字节。 有时不会发送 CRC 的最后一帧。
//(似乎是由堆栈溢出引起的、因此应采取预防措施来减少函数调用中的堆栈使用量)
// sciSend (sciREG、bPktLen、pFrame);
//发送 g_tipString 输出。
xfer.data = pFrame;
Xfer.dataSize = bPktLen;
txOnGoing = true;
// LPUART_WriteBlocking (demo_LPUART, pBuf, bPktLen );
LPUART_TransferSendNonBlocking (DEMO_LPUART、&g_lpuartHandle、&xfer);
while (txOnGoing)
{
}
返回 bPktLen;
}
//生成读取命令帧,然后等待响应数据(SCIRX 的中断模式)
int ReadReg (byte BID、uint16_t wAddr、uint8_t * pData、byte bLen、uint32_t dwTimeOut、
字节 bWriteType){
//器件地址、寄存器起始地址、用于存储数据的字节帧指针、数据长度、读取类型(单次、广播、堆栈)
Bres = 0;
count = 1000000;//完成这么多次尝试后超时
如果(bWriteType => FRMWRT_SGL_R){
ReadFrameReq (BID、wAddr、bLen、bWriteType);
memset (pData、0、bLen + 6);
// sciEnableNotification (sciREG、SCI_RX_INT);
receiveXfer.data = pData;
receiveXfer.dataSize = bLen + 6;
if ((!rxOnGoing)&& rxBufferEmpty)
{
rxOnGoing = true;
LPUART_TransferReceiveNonBlocking (DEMO_LPUART、&g_lpuartHandle、&receiveXfer、NULL);
}
// while (rxOnGoing){}
// LPUART_ReadBlocking (DEMO_LPUART、pData、bLen + 6);
// while (UART_RX_RDY = 0u && count>0) count -;//*等待*/
// UART_RX_RDY = 0;
Bres = bLen + 6;
}否则、如果(bWriteType == FRMWRT_STK_R){
bres = ReadFrameReq (BID、wAddr、bLen、bWriteType);
memset (pData、0、(bLen + 6)*(TOTALBOARDS - 1));
// sciEnableNotification (sciREG、SCI_RX_INT);
receiveXfer.data = pData;
receiveXfer.dataSize =(bLen + 6)*(TOTALBOARDS - 1);
// LPUART_ReadBlocking (DEMO_LPUART、pData、(bLen + 6)*(TOTALBOARDS - 1));
if ((!rxOnGoing)&& rxBufferEmpty)
{
rxOnGoing = true;
LPUART_TransferReceiveNonBlocking (DEMO_LPUART、&g_lpuartHandle、&receiveXfer、NULL);
}
// while (rxOnGoing){}
// sciReceive (sciREG、(bLen + 6)*(TOTALBOARDS - 1)、pData);
// while (UART_RX_RDY = 0u && count>0) count -;//*等待*/
// UART_RX_RDY = 0;
BRES =(bLen + 6)*(TOTALBOARDS - 1);
} else if (bWriteType == FRMWRT_ALL_R){
bres = ReadFrameReq (BID、wAddr、bLen、bWriteType);
memset (pData、0、(bLen + 6)* TOTALBOARDS);
receiveXfer.data = pData;
receiveXfer.dataSize =(bLen + 6)* TOTALBOARDS;
rxOnGoing=0;
if ((!rxOnGoing)&& rxBufferEmpty)
{
rxOnGoing = true;
LPUART_TransferReceiveNonBlocking (DEMO_LPUART、&g_lpuartHandle、&receiveXfer、NULL);
}
// while (rxOnGoing){}
/* LPUART_ReadBlocking (DEMO_LPUART、pData、(bLen + 6)* TOTALBOARDS);*/
// while (UART_RX_RDY = 0u && count>0) count -;//*等待*/
// UART_RX_RDY = 0;
BRES =(bLen + 6)* TOTALBOARDS;
}其他{
Bres = 0;
}
////检查 CRC 是否正确
// for (crc_i=0;crc_i<bres;crc_i+=(bLen+6))
//{
// if (CRC16 (&pData[CRC_I]、bLen+6)!=0)
//{
// printf ("bad crc\n");
//}
//}
返回表述;
}
int ReadFrameReq (字节 BID、uint16_t wAddr、字节 bByteToReturn、字节 bWriteType)
{
bReturn = bByteToReturn - 1;
如果(bReturn > 127)
返回0;
返回 WriteFrame (BID、wAddr、&bReturn、1、bWriteType);
}
// CRC16表
// ITU_T 多项式:x^16 + x^15 + x^2 + 1
const uint16_t crc16_table[256]={0x0000、0xC0C1、0xC181、0x0140、0xC301、
0x03C0、0x0280、0xC241、0xC601、0x06C0、 0x0780、0xC741、0x0500、0xC5C1、
0xC481、0x0440、0xCC01、0x0CC0、0x0D80、 0xCD41、0x0F00、0xCFC1、0xCE81、
0x0E40、0x0A00、0xCAC1、0xCB81、0x0B40、 0xC901、0x09C0、0x0880、0xC841、
0xD801、0x18C0、0x1980、0xD941、0x1B00、 0xDBC1、0xDA81、0x1A40、0x1E00、
0xDEC1、0xDF81、0x1F40、0xDD01、0x1DC0、 0x1C80、0xDC41、0x1400、0xD4C1、
0xD581、0x1540、0xD701、0x17C0、0x1680、 0xD641、0xD201、0x12C0、0x1380、
0xD341、0x1100、0xD1C1、0xD081、0x1040、 0xF001、0x30C0、0x3180、0xF141、
0x3300、0xF3C1、0xF281、0x3240、0x3600、 0xF6C1、0xF781、0x3740、0xF501、
0x35C0、0x3480、0xF441、0x3C00、0xFCC1、 0xFD81、0x3D40、0xFF01、0x3FC0、
0x3E80、0xFE41、0xFA01、0x3AC0、0x3B80、 0xFB41、0x3900、0xF9C1、0xF881、
0x3840、0x2800、0xE8C1、0xE981、0x2940、 0xEB01、0x2BC0、0x2A80、0xEA41、
0xEE01、0x2EC0、0x2F80、0xEF41、0x2D00、 0xEDC1、0xEC81、0x2C40、0xE401、
0x24C0、0x2580、0xE541、0x2700、0xE7C1、 0xE681、0x2640、0x2200、0xE2C1、
0xE381、0x2340、0xE101、0x21C0、0x2080、 0xE041、0xA001、0x60C0、0x6180、
0xA141、0x6300、0xA3C1、0xA281、0x6240 0x6600、0xA6C1、0xA781、0x6740、
0xA501、0x65C0、0x6480、0xA441、0x6C00、 0xACC1、0xAD81、0x6D40、0xAF01、
0x6FC0、0x6E80、0xAE41、0xAA01、0x6AC0、 0x6B80、0xAB41、0x6900、0xA9C1、
0xA881、0x6840、0x7800、0xB8C1、0xB981、 0x7940、0xBB01、0x7BC0、0x7A80、
0xBA41、0xBE01、0x7EC0、0x7F80、0xBF41 0x7D00、0xBDC1、0xBC81、0x7C40、
0xB401、0x74C0、0x7580、0xB541、0x7700、 0xB7C1、0xB681、0x7640、0x7200、
0xB2C1、0xB381、0x7340、0xB101、0x71C0、 0x7080、0xB041、0x5000、0x90C1、
0x9181、0x5140、0x9301、0x53C0、0x5280、 0x9241、0x9601、0x56C0、0x5780、
0x9741、0x5500、0x95C1、0x9481、0x5440、 0x9C01、0x5CC0、0x5D80、0x9D41、
0x5F00、0x9FC1、0x9E81、0x5E40、0x5A00、 0x9AC1、0x9B81、0x5B40、0x9901、
0x59C0、0x5880、0x9841、0x8801、0x48C0、 0x4980、0x8941、0x4B00、0x8BC1、
0x8A81、0x4A40、0x4E00、0x8EC1、0x8F81、 0x4F40、0x8D01、0x4DC0、0x4C80、
0x8C41、0x4400、0x84C1、0x8581、0x4540、 0x8701、0x47C0、0x4680、0x8641、
0x8201、0x42C0、0x4380、0x8341、0x4100、 0x81C1、0x8081、0x4040};
uint16_t CRC16 (byte *pBuf、int nLen){
uint16_t wCRC = 0xFFFF;
INT I;
对于(I = 0;I < nLen;I++){
wCRC ^=(*pBuf++)& 0x00FF;
wCRC = crc16_table[wCRC & 0x00FF]^(wCRC >> 8);
}
返回 wCRC;
}
//********
//结束写入和读取函数
//********
//*****
//混合函数
//*****
/*
bool GetFaultStat (){
if (!gioGetBit (gioPORTA、0))
返回0;
返回1;
}
*/
空 ResetAllFaults (字节 BID、字节 bWriteType)
{
//广播包括使用当前设置覆盖 CUST_CRC 的额外功能
if (bWriteType=FRMWRT_All_W)
{
//读取计算出的客户 CRC 值
ReadReg (0、CUST_CRC_RSLT_HI、FAULT_FRAME、2、0、 FRMWRT_ALL_R);
//使用正确的 CRC 覆盖堆栈中每个板的 CRC
for (currentBoard=0;currentBoard<TOTALBOARDS;currentBoard++)
{
//返回帧从最高板开始,因此将首先写入最高板
WriteReg (TOTALBOARDS-CURRENTBoard-1、CUST_CRC_HI、FAULT_FRAME [ CURRENTBOD*8+4]<< 8 | FAULT_FRAME[CURRENTBOD*8+5]、2、FRMWRT_SGL_W);
}
//现在清除每个故障
WriteReg (0、FAULT_RST1、0xFFFF、2、FRMWRT_ALL_W);
}
否则、如果(bWriteType=FRMWRT_SGL_W)
{
WriteReg (BID、FAULT_RST1、0xFFFF、2、FRMWRT_SGL_W);
}
否则、如果(bWriteType=FRMWRT_STK_W)
{
WriteReg (0、FAULT_RST1、0xFFFF、2、FRMWRT_STK_W);
}
方案
{
// printf ("错误:ResetAllFaults bWriteType 不正确\n");
}
}
void MaskAllFaults (字节 BID、字节 bWriteType)
{
if (bWriteType=FRMWRT_All_W)
{
WriteReg (0、FAULT_MSK1、0xFFFF、2、FRMWRT_ALL_W);
}
否则、如果(bWriteType=FRMWRT_SGL_W)
{
WriteReg (BID、FAULT_MSK1、0xFFFF、2、FRMWRT_SGL_W);
}
否则、如果(bWriteType=FRMWRT_STK_W)
{
WriteReg (0、FAULT_MSK1、0xFFFF、2、FRMWRT_STK_W);
}
方案
{
// printf ("错误:MaskAllFaults bWriteType 不正确\n");
}
}
空 PrintAllFaults (字节 BID、字节 bWriteType)
{
//从 FAULT_SUMMARY 开始打印39个寄存器(包括保留的寄存器)
// printf ("\n");
电流板= 0;
currentCell = 0;
memset (FAULT_FRAME、0、sizeof (FAULT_FRAME));
if (bWriteType==FRMWRT_ALL_R)
{
ReadReg (0、FAULT_SUMMARY、FAULT_FRAME、39、0、 FRMWRT_ALL_R);
for (currentBoard = 0;currentBoard<TOTALBOARDS;currentBoard++)
{
// printf ("Board %d Faults:\t"、TOTALBOARDS-currentBoard);
for (currentCell = 0;currentCell <39;currentCell++)
{
// printf ("%02x "、FAULT_FRAME [(currentBoard*(39+6))+4+currentCell]);
}
// printf ("\n");
}
}
否则、如果(bWriteType=FRMWRT_SGL_R)
{
ReadReg (BID、FAULT_SUMMARY、FAULT_FRAME、39、0、 FRMWRT_SGL_R);
// printf ("Board %d faults:\t"、bid);
for (currentCell = 0;currentCell <39;currentCell++)
{
// printf ("%02x "、FAULT_FRAME [4+currentCell]);
}
// printf ("\n");
}
否则、如果(bWriteType=FRMWRT_STK_R)
{
ReadReg (0、FAULT_SUMMARY、FAULT_FRAME、39、0、 FRMWRT_STK_R);
for (currentBoard = 0;currentBoard<(TOTALBOARDS-1);currentBoard++)
{
// printf ("Board %d Faults:\t"、TOTALBOARDS-currentBoard);
for (currentCell = 0;currentCell <39;currentCell++)
{
// printf ("%02x "、FAULT_FRAME [(currentBoard*(39+6))+4+currentCell]);
}
// printf ("\n");
}
}
方案
{
// printf ("错误:PrintAllFaults bWriteType 不正确\n");
}
// printf ("\n");
}
//对所有设备运行基本的电池平衡
void RunCB (uint8_t Chipaddr、uint64_t CB_16_9_CTRL、uint64_t CB_8_1_CTRL)//添加芯片地址、CB 通道、
{
//将平衡计时器设置为9小时
WriteReg (Chipaddr、CB_CELL16_CTRL、CB_16_9_CTRL、8、FRMWRT_SGL_W); //电池16-9 (最大8字节写入) FRMWRT_SGL_W 0x1F1F1F1F1F1F1 FBF
WriteReg (Chipaddr、CB_CELL8_CTRL、CB_8_1_CTRL、8、FRMWRT_SGL_W); //将所有电池设置为9小时
//将占空比设置为10s (默认值)
WriteReg (Chipaddr、BAL_CTRL1、0x01、1、FRMWRT_SGL_W); //10s 的占空比
//可选:将 VCBDONE THRESH 设置为3V、并将 OVUV_GO
WriteReg (Chipaddr、VCB_DONE_THRESH、0x08、1、FRMWRT_SGL_W); //3V 阈值(8*25mV + 2.8V)
WriteReg (Chipaddr、OVUV_CTRL、0x05、1、FRMWRT_SGL_W); //循环和 OVUV_GO
//开始平衡
WriteReg (Chipaddr、BAL_CTRL2、0x03、1、FRMWRT_SGL_W); //自动平衡和 BAL_GO
}
//对所有设备运行基本的电池平衡
void StopCB (uint8_t Chipaddr)//添加芯片地址,CB 通道,
{
//开始平衡
WriteReg (Chipaddr、BAL_CTRL2、0x00、1、FRMWRT_SGL_W); //自动平衡和 BAL_GO
}
//运行基本反向寻址序列
void ReverseAddressing()
{
//更改基本设备方向
WriteReg (0、control1、0x80、1、FRMWRT_SGL_W);
//更改其余的堆栈方向
WriteReg (0、CONTROL1、0x80、1、FRMWRT_REV_ALL_W);
//执行正常的自动地址序列,但是对于 DIR1_ADDR
//虚拟写入 SNCHRONIZE 所有菊花链器件 DLL (如果在此之前发生器件复位)
WriteReg (0、OTP_ECC_DATAIN1、0x00、1、FRMWRT_ALL_W);
WriteReg (0、OTP_ECC_DATAIN2、0x00、1、FRMWRT_ALL_W);
WriteReg (0、OTP_ECC_DATAIN3、0x00、1、FRMWRT_ALL_W);
WriteReg (0、OTP_ECC_DATAIN4、0x00、1、FRMWRT_ALL_W);
WriteReg (0、OTP_ECC_DATAIN5、0x00、1、FRMWRT_ALL_W);
WriteReg (0、OTP_ECC_DATAIN6、0x00、1、FRMWRT_ALL_W);
WriteReg (0、OTP_ECC_DATAIN7、0x00、1、FRMWRT_ALL_W);
WriteReg (0、OTP_ECC_DATAIN8、0x00、1、FRMWRT_ALL_W);
//启用自动寻址模式,同时保持反向
WriteReg (0、CONTROL1、0x81、1、FRMWRT_ALL_W);
//为每个板设置地址(反向)
for (currentBoard=0;currentBoard<TOTALBOARDS;currentBoard++)
{
WriteReg (0、DIR1_ADDR、电流板、1、FRMWRT_ALL_W);
}
WriteReg (0、COMM_CTRL、0x02、1、FRMWRT_ALL_W); //首先将所有内容设置为堆栈设备
if (TOTALBOARDS=1)//如果只有1个板、则它是栈的底部和顶部、因此应将其更改为这些
{
WriteReg (0、COMM_CTRL、0x01、1、FRMWRT_SGL_W);
}
else //否则分别设置栈的底部和顶部
{
WriteReg (0、COMM_CTRL、0x00、1、FRMWRT_SGL_W);
WriteReg (TOTALBOARDS-1、COMM_CTRL、0x03、1、FRMWRT_SGL_W);
}
//SYNCRHONIZE 具有抛出式读取功能的 DLL
ReadReg (0、OTP_ECC_DATAIN1、Response_frame2、1、0、 FRMWRT_ALL_R);
ReadReg (0、OTP_ECC_DATAIN2、Response_frame2、1、0、 FRMWRT_ALL_R);
ReadReg (0、OTP_ECC_DATAIN3、Response_frame2、1、0、 FRMWRT_ALL_R);
ReadReg (0、OTP_ECC_DATAIN4、Response_frame2、1、0、 FRMWRT_ALL_R);
ReadReg (0、OTP_ECC_DATAIN5、Response_frame2、1、0、 FRMWRT_ALL_R);
ReadReg (0、OTP_ECC_DATAIN6、Response_frame2、1、0、 FRMWRT_ALL_R);
ReadReg (0、OTP_ECC_DATAIN7、Response_frame2、1、0、 FRMWRT_ALL_R);
ReadReg (0、OTP_ECC_DATAIN8、Response_frame2、1、0、 FRMWRT_ALL_R);
////可选:回读所有设备地址
//用于(currentBoard=0;currentBoard<TOTALBOARDS;currentBoard++)
//{
// ReadReg (currentBoard、DIR0_ADDR、Response_frame2、1、0、 FRMWRT_SGL_R);
// printf ("board %d\n",response_frame2[4]);
//}
//从启动状态重置所有 COMM 故障条件
WriteReg (0、FAULT_RST2、0x03、1、FRMWRT_ALL_W);
}
//***********
//结束其他函数
//***********
void Wake79616 (void){
LPUART_SoftwareReset (DEMO_LPUART);
LPUART_Deinit (DEMO_LPUART);
IOMUXC_SetPinMux (IOMUXC_GPIO_AD_24_GPIO9_IO23、0U);
IOMUXC_SetPinConfig (IOMUXC_GPIO_AD_24_GPIO9_IO23、2);//2.
GPIO_PinInit (Board_UART_TX_GPIO、Board_UART_TX_GPIO_PIN、&UARTx_CONFIG);
GPIO_PinWrite (Board_UART_TX_GPIO、Board_UART_TX_GPIO_PIN、0U);
SDK_DelayAtLeastU ((2500)、SDK_DEVICE_MAXIMUM_CPU_CLOCK_FREQUENCY);
// delayus (2500);//唤醒 ping = 2ms 至2.5ms
IOMUXC_SetPinMux (IOMUXC_GPIO_AD_24_LPUART1_TXD、0u);
IOMUXC_SetPinConfig (IOMUXC_GPIO_AD_24_LPUART1_TXD、0x02U);
LPUART_GetDefaultConfig (&config);
CONFIG.baudrate_BPS = Board_DEBUG_UART_BAUDRATE;
config.enableTx = true;
config.enableRx = true;
LPUART_Init (DEMO_LPUART、&CONFIG、DEMO_LPUART_CLK_FREQ);
LPUART_TransferCreateHandle (demo_LPUART、&g_lpuartHandle、LPUART_UserCallback、NULL);
}
*/李启英
***** AFE 进入SHUTDOWN è ne
* /
void SD79616 (void){
LPUART_SoftwareReset (DEMO_LPUART);
LPUART_Deinit (DEMO_LPUART);
IOMUXC_SetPinMux (IOMUXC_GPIO_AD_24_GPIO9_IO23、0U);
IOMUXC_SetPinConfig (IOMUXC_GPIO_AD_24_GPIO9_IO23、0x00);
GPIO_PinInit (Board_UART_TX_GPIO、Board_UART_TX_GPIO_PIN、&UARTx_CONFIG);
GPIO_PinWrite (Board_UART_TX_GPIO、Board_UART_TX_GPIO_PIN、0U);
SDK_DelayAtLeastU ((9000)、SDK_DEVICE_MAXIMUM_CPU_CLOCK_FREQUENCY);
// delayus (9000);// sd ping = 7ms 至10ms
IOMUXC_SetPinMux (IOMUXC_GPIO_AD_24_LPUART1_TXD、0u);
IOMUXC_SetPinConfig (IOMUXC_GPIO_AD_24_LPUART1_TXD、0x02U);
LPUART_GetDefaultConfig (&config);
CONFIG.baudrate_BPS = 1000000;//Board_debug_UART_BAUDRATE;
config.enableTx = true;
config.enableRx = true;
LPUART_Init (DEMO_LPUART、&CONFIG、DEMO_LPUART_CLK_FREQ);
LPUART_TransferCreateHandle (demo_LPUART、&g_lpuartHandle、LPUART_UserCallback、NULL);
}
*/李启英
***** AFE 睡眠到活动
* /
void StA79616 (void){
LPUART_SoftwareReset (DEMO_LPUART);
LPUART_Deinit (DEMO_LPUART);
IOMUXC_SetPinMux (IOMUXC_GPIO_AD_24_GPIO9_IO23、0U);
IOMUXC_SetPinConfig (IOMUXC_GPIO_AD_24_GPIO9_IO23、0x00U);
GPIO_PinInit (Board_UART_TX_GPIO、Board_UART_TX_GPIO_PIN、&UARTx_CONFIG);
GPIO_PinWrite (Board_UART_TX_GPIO、Board_UART_TX_GPIO_PIN、0U);
SDK_DelayAtLeastU ((250)、SDK_DEVICE_MAXIMUM_CPU_CLOCK_FREQUENCY);
// delayus (250);// STA ping = 250us 至300us
IOMUXC_SetPinMux (IOMUXC_GPIO_AD_24_LPUART1_TXD、0u);
IOMUXC_SetPinConfig (IOMUXC_GPIO_AD_24_LPUART1_TXD、0x02U);
LPUART_GetDefaultConfig (&config);
CONFIG.baudrate_BPS = 1000000;//Board_debug_UART_BAUDRATE;
config.enableTx = true;
config.enableRx = true;
LPUART_Init (DEMO_LPUART、&CONFIG、DEMO_LPUART_CLK_FREQ);
LPUART_TransferCreateHandle (demo_LPUART、&g_lpuartHandle、LPUART_UserCallback、NULL);
}
*/李启英
***** AFE 复位
* /
void HWRST79616 (void){
LPUART_SoftwareReset (DEMO_LPUART);
LPUART_Deinit (DEMO_LPUART);
IOMUXC_SetPinMux (IOMUXC_GPIO_AD_24_GPIO9_IO23、0U);
IOMUXC_SetPinConfig (IOMUXC_GPIO_AD_24_GPIO9_IO23、0x06U);
GPIO_PinInit (Board_UART_TX_GPIO、Board_UART_TX_GPIO_PIN、&UARTx_CONFIG);
GPIO_PinWrite (Board_USER_LED_GPIO、Board_USER_LED_GPIO_PIN、0U);
SDK_DelayAtLeastU ((36000)、SDK_DEVICE_MAXIMUM_CPU_CLOCK_FREQUENCY);
// delayus (36000);// STA ping = 36ms
IOMUXC_SetPinMux (IOMUXC_GPIO_AD_24_LPUART1_TXD、0u);
IOMUXC_SetPinConfig (IOMUXC_GPIO_AD_24_LPUART1_TXD、0x02U);
LPUART_GetDefaultConfig (&config);
CONFIG.baudrate_BPS = 1000000;//Board_debug_UART_BAUDRATE;
config.enableTx = true;
config.enableRx = true;
LPUART_Init (DEMO_LPUART、&CONFIG、DEMO_LPUART_CLK_FREQ);
LPUART_TransferCreateHandle (demo_LPUART、&g_lpuartHandle、LPUART_UserCallback、NULL);
}
/*!
*@简短的主函数
*/
int main (空)
{
特性;
/*初始化板硬件。 */
Board_ConfigMPU ();
Board_InitPins ();
Board_BootClockRUN ();
Board_InitDebugConsole ();
printf ("hello world。\r\n ");
uint32_t i;
INT j = 0;
INT currentBoard = 0;
/* lpuart_config_t config;
CONFIG.baudrate_BPS = 1000000U;
config.parityMode = kLPUART_ParityDisabled;
config.stopBitCount = kLPUART_OneStopBit;
CONFIG.txFifoWatermark = 0;
config.rxFifoWatermark = 0;*/
LPUART_GetDefaultConfig (&config);
CONFIG.baudrate_BPS = 1000000;//Board_debug_UART_BAUDRATE;
config.enableTx = true;
config.enableRx = true;
LPUART_Init (DEMO_LPUART、&CONFIG、DEMO_LPUART_CLK_FREQ);
LPUART_TransferCreateHandle (demo_LPUART、&g_lpuartHandle、LPUART_UserCallback、NULL);
/***** 获得了 GPT 并将其初始化 /
/***** 这份 GPT 仅仅是为了***** /
// gpt_init_a ( gptConfig_6 );
// gpt_init_a ( gptConfig_5 );
浮动 CellVoltage;
uint16_t RawData;
int boardByteStart;
uint8_t tmp1;
//初始化 BQ79616-Q1
//由于该特定的微控制器默认输出 Rx=0,因此需要2次唤醒,因此在加载程序时将设备置于硬件复位状态
wake79616();
SDK_DelayAtLeastUs ((12*TOTALBOARDS*1000)、SDK_DEVICE_MAXIMUM_CPU_CLOCK_FREQUENCY);
// delayms (12* TOTALBOARDS);//唤醒音持续时间为每个电路板~1.6ms +每个电路板10ms、用于从关断中唤醒每个器件=每个616个电路板11.6ms (舍入为12ms、因为使用的变量是整数)
wake79616();
SDK_DelayAtLeastUs ((12*TOTALBOARDS*1000)、SDK_DEVICE_MAXIMUM_CPU_CLOCK_FREQUENCY);
// delayms (12* TOTALBOARDS);//唤醒音持续时间为每个电路板~1.6ms +每个电路板10ms、用于从关断中唤醒每个器件=每个616个电路板11.6ms (舍入为12ms、因为使用的变量是整数)
AutoAddress();
SDK_DelayAtLeastU ((4000)、SDK_DEVICE_MAXIMUM_CPU_CLOCK_FREQUENCY);
// delayus (4000);//4ms 从关断到唤醒转换为 AFE 建立时间所需的总时间,仅适用于顶部器件
WriteReg (0、FAULT_MSK2、0x40、1、FRMWRT_ALL_W); //屏蔽 CUST_CRC,使配置更改不会标记故障
ResetAllFaults (0、FRMWRT_All_W);//清除所有故障
//变量
//可选示例函数
// RunCB();
///反向寻址();
//设置主 ADC
WriteReg (0、ACTIVE_CELL、0x0A、1、FRMWRT_ALL_W); //将所有电池设置为活动状态
WriteReg (0、ADC_CONF1、0x02、1、FRMWRT_ALL_W); // 26Hz LPF_Vcell (平均值38ms)
WriteReg (0、ADC_CTRL1、0x0E、1、FRMWRT_ALL_W); //连续运行、LPF 启用以及 MAIN_GO
SDK_DelayAtLeastU ((38000+5* TOTALBOARDS)、SDK_DEVICE_MAXIMUM_CPU_CLOCK_FREQUENCY);
//****
//主循环
//****
操作
{
//*****
//读取电池电压
//*****
//重置变量
I = 0;
电流板= 0;
//清除阵列,以便我们知道每个循环都有新的数据
memset (Response_FRAME、0、sizeof (Response_FRAME));
//等待单次循环周期时间+每个器件、每个循环的重新计时延迟
// delayus(192+5*TOTALBOARDS);
SDK_DelayAtLeastU ((192+5* TOTALBOARDS)、SDK_DEVICE_MAXIMUM_CPU_CLOCK_FREQUENCY);
//读取所有值(每个电芯的 HI/LO 总计= 32)
// ReadReg (0、VCELL16_HI、RESPONSE _FRAME、(16+19)* 2、0、 FRMWRT_ALL_R);
ReadReg (0、VCELL16_HI、Response_FRAME、(16)* 2、0、 FRMWRT_ALL_R);
/****************
*注意:某些计算机通过 printf 语句传输大量数据时会出现问题。
*以下响应数据打印输出不能保证在所有系统上都能正常工作。
*************** */
//格式化并打印生成的响应帧
// printf ("\n");//从换行开始在循环之间增加一些额外的间距
for (currentBoard=0;currentBoard<TOTALBOARDS;currentBoard++)
{
//遍历当前电路板中的每个字节(32字节= 16个单元*每个2个字节)
for (I=0;I<32;I+=2)
{
//每个电路板都使用32个数据字节+ 6个标头字节进行响应
//所以需要通过这样做* currentboard 来找到每个电路板的起点
boardByteStart =(16*2+6)*电流板;
//将每个单元的两个单独的字节转换为单个16位数据项(通过位移动)
RawData =(Response_FRAME[boardByteStart+i+4]<< 8)| Response_FRAME[boardByteStart+i+5];
//转换为有符号的16位数据项,并乘以190.73uV,得到实际电压
电芯电压=(RawData)* 1.9073;
//打印电压-它是(32-I)/2,因为电池从16开始到1
//并且每个单元有2个字节(I 值是单元号的两倍)
AFEdata[currentBoard].MainData_p.AFEVcell[15-j]= CELLVoltage;
}
//将每个单元的两个单独的字节转换为单个16位数据项(通过位移动)
}
//*****
//结束读取电池电压
//*****
}while (1);
}
