工具与软件:
大家好、
我将使用 bq79600和 bq79612读取电池电压。 由于此 bq79612作为菊花链进行通信、因此当其中一个模块的电缆出现问题时、我会丢失未来模块的数据、因此我想使用环网通信来防止这种情况发生。 发生这种情况时、我需要切换到南向并在发生错误后读取模块、然后切换回北向并再次读取、这里是否有适用于此操作的示例代码、在某个位置您可以提供参考、因为我可以单独读取南向和北向、但我无法在同一个环路中进行南向和北向运算
Error_Codes_enum PAL_BQ79600_ReadCellVoltages(BQ7961x_Modules_enum id)
{
Uint16 MSB_register = (VCELL11_HI >>8) & 0xFF;
Uint16 LSB_register = VCELL11_HI & 0xFF;
Uint16 cell_number = 11;
Uint16 receiveDataLength = cell_number *2;
Uint16 i = 0;
// Uint16 a = 0;
Error_Codes_enum stats = ERROR_CODES_SUCCESS;
CRC16_t crc16;
Uint16 readCellVoltagesArray[7]= {0x80, id, MSB_register, LSB_register, (receiveDataLength - 1), 0x00, 0x00};
CRC16_CalculateCRC16IBMAndWriteReverse(readCellVoltagesArray, 7);
// a = id;
HAL_SCI_EmptyRXFIFO(BQ79600_Module.UARTPort);
HAL_SCI_write_bytes(BQ79600_Module.UARTPort, readCellVoltagesArray, 7);
stats = HAL_SCI_Read_Into_CustomBuffer(BQ79600_Module.UARTPort, &(BQ79600_Module.Buffer[0]), 30,(6+ receiveDataLength));
if (stats == ERROR_CODES_SUCCESS)
{
CRC16_CalculateCRC16IBM(BQ79600_Module.Buffer,(receiveDataLength+4), &crc16);
if (BQ79600_Module.Buffer[(receiveDataLength+4)] != crc16.Bytes.LowByte || BQ79600_Module.Buffer[(receiveDataLength+5)] != crc16.Bytes.HighByte)
{
for (i = 0; i < 16; i++)
{
// ActiveBattery.Modules[BQ79600_Module.Buffer[1]].Cells[i].RawVoltage = 0xFFFF;
// ActiveBattery.Modules[BQ79600_Module.Buffer[1]].Cells[i].CellVoltage = 0xFFFF;
}
return ERROR_CODES_CRC16ERROR;
}
if ((BQ79600_Module.Buffer[0] == (receiveDataLength-1)) && (BQ79600_Module.Buffer[2] == MSB_register) && (BQ79600_Module.Buffer[3] == LSB_register))
{
for (i = 4; i<(receiveDataLength+4); i+=2)
{
BQ7961x_Modules[id].raw_Vcell[11-((i-4)/2)] = (BQ79600_Module.Buffer[i] << 8) + BQ79600_Module.Buffer[i+1];
BQ7961x_Modules[id].Vcell[11-((i-4)/2)] = (Uint16)(BQ7961x_Modules[id].raw_Vcell[11-((i-4)/2)] * VCELL_COEFF);
}
}
}
else
{
// PAL_BQ79600_ReverseDirection(a);
// Fail_Module_id = a;
return ERROR_CODES_SERIAL_COMMUNICATION_ERROR;
}
// }
// DELAY_US(50);
return ERROR_CODES_SUCCESS;
}
Uint16 PAL_BQ79600_ReverseDirection(Uint16 id)
{
BQ7961x_Modules_enum j;
PAL_BQ79600_WriteSingleDevice(MODULE_BQ79600_NOT_USED, CONTROL1, 0x80); // change base device direction
DELAY_US(10);
// PAL_BQ79600_WriteSingleDevice(BQ7961x_MODULE_8, COMM_CTRL, 0x02);
// DELAY_US(10);
PAL_BQ79600_WriteMultiDevices(REVERSE, COMM_CTRL, 0x02);
DELAY_US(10);
PAL_BQ79600_WriteMultiDevices(REVERSE, CONTROL1, 0x80); //change the stack device direction
DELAY_US(10);
//EnableAutoAddressing
PAL_BQ79600_WriteMultiDevices(BROADCAST, CONTROL1, 0x81);
DELAY_US(10);
//Set stack device address for 8 stack
// for (j = MODULE_BQ79600_NOT_USED; j < BQ7961x_MODULE_MAXNUM; j++)
// {
// PAL_BQ79600_WriteMultiDevices(BROADCAST, DIR1_ADDR, j);
// DELAY_US(10);
// }
//Set stack device address for 8 stack
for (j = BQ7961x_MODULE_8; j >= id; j--)
{
PAL_BQ79600_WriteMultiDevices(BROADCAST, DIR1_ADDR, j);
DELAY_US(10);
}
PAL_BQ79600_WriteSingleDevice(MODULE_BQ79600_NOT_USED, COMM_CTRL, 0x00);
DELAY_US(10);
//Stack All Devices
PAL_BQ79600_WriteMultiDevices(BROADCAST, COMM_CTRL, 0x02);
DELAY_US(10);
//Set Top Stack
PAL_BQ79600_WriteSingleDevice(id, COMM_CTRL, 0x03);
DELAY_US(10);
return ERROR_CODES_REVERSE_DIRECTION;
}
void PAL_CheckCommunicationError(Uint16 commStatus, Uint16 currentModule)
{
if ( commStatus == ERROR_CODES_SERIAL_COMMUNICATION_ERROR)
{
commErrorFlag = 1;
failedModuleID = currentModule;
direction = 1;
reverse_command= 1;
// currentModule--;
}
else
{
commErrorFlag = 0;
if(direction == 1 && currentModule == failedModuleID)
{
direction = 0;
}
}
}
Uint16 PAL_BQ79600_SendNormalDirectionCommand(Uint16 id)
{
BQ7961x_Modules_enum j;
PAL_BQ79600_WriteSingleDevice(MODULE_BQ79600_NOT_USED, CONTROL1, 0x00); // change base device direction
DELAY_US(10);
// PAL_BQ79600_WriteSingleDevice(BQ7961x_MODULE_8, COMM_CTRL, 0x02);
// DELAY_US(10);
PAL_BQ79600_WriteMultiDevices(REVERSE, COMM_CTRL, 0x02);
DELAY_US(10);
PAL_BQ79600_WriteMultiDevices(REVERSE, CONTROL1, 0x00); //change the stack device direction
DELAY_US(10);
//EnableAutoAddressing
PAL_BQ79600_WriteMultiDevices(BROADCAST, CONTROL1, 0x01);
DELAY_US(10);
//Set stack device address for 8 stack
for (j = MODULE_BQ79600_NOT_USED; j < BQ7961x_MODULE_MAXNUM; j++)
{
PAL_BQ79600_WriteMultiDevices(BROADCAST, DIR1_ADDR, j);
DELAY_US(10);
}
PAL_BQ79600_WriteSingleDevice(MODULE_BQ79600_NOT_USED, COMM_CTRL, 0x00);
DELAY_US(10);
//Stack All Devices
PAL_BQ79600_WriteMultiDevices(BROADCAST, COMM_CTRL, 0x02);
DELAY_US(10);
//Set Top Stack
PAL_BQ79600_WriteSingleDevice(id-1, COMM_CTRL, 0x03);
DELAY_US(10);
return 0 ;
}
void PAL_HandleDirection(BQ7961x_Modules_enum moduleId)
{
Error_Codes_enum commStatus = ERROR_CODES_SUCCESS;
if (direction == 0) // Normal (düz) yön
{
commStatus = PAL_BQ79600_ReadCellVoltages(moduleId);
PAL_CheckCommunicationError(commStatus, moduleId);
if (commErrorFlag == 0) // Eğer hata yoksa bir sonraki modüle geç
{
currentModule++; // Düz yönde ilerle
if (currentModule > BQ7961x_MODULE_8) // Modüller biterse tekrar başa dön
{
currentModule = 1;
}
}
}
else if (direction == 1 && currentModule >= 1) // Ters yön
{
if (reverse_command)
{
PAL_BQ79600_ReverseDirection(moduleId); // Ters yönde iletişim başlat
reverse_command = 0;
}
commStatus = PAL_BQ79600_ReadCellVoltages(moduleId);
PAL_CheckCommunicationError(commStatus, moduleId);
if (commErrorFlag == 0) // Hata düzelirse düz yöne geç
{
PAL_BQ79600_SendNormalDirectionCommand(moduleId);
direction = 0; // Yönü düz olarak değiştir
currentModule++; // Düz yönde devam etmek için bir sonraki modüle geç
if (currentModule > BQ7961x_MODULE_8) // Modüller biterse başa dön
{
currentModule = 1;
}
}
else
{
currentModule--; // Hata devam ederse ters yönde ilerlemeye devam et
if (currentModule == 0) // Eğer başa gelirsek
{
currentModule = BQ7961x_MODULE_8; // Modüller başa döner
}
}
}
}
App_4.12.42al() Frames_Active;
PAL_HandleDirection (当前模块);
我的主代码如下所示