F28377S 使用PeripheralDriverLibrary,当CAN总线出现错误时,程序会进入CAN的故障中断。如下:
void CanaIsrFxn(void)
{
uint32_t status;
//
// Read the CAN-B interrupt status to find the cause of the interrupt
//
status = CANIntStatus(CANA_BASE, CAN_INT_STS_CAUSE);
//
// If the cause is a controller status interrupt, then get the status
//
if(status == CAN_INT_INT0ID_STATUS)
{
//
// Read the controller status. This will return a field of status
// error bits that can indicate various errors. Error processing
// is not done in this example for simplicity. Refer to the
// API documentation for details about the error status bits.
// The act of reading this status will clear the interrupt.
//
status = CANStatusGet(CANA_BASE, CAN_STS_CONTROL);
//
// Check to see if an error occurred.
//
if(((status & ~(CAN_ES_RXOK)) != 7) && ((status & ~(CAN_ES_RXOK)) != 0))
{
if(status != CAN_STATUS_TXOK)
{
//
// Set a flag to indicate some errors may have occurred.
//
if(errorFlag == 0)
asm (" ESTOP0");
errorFlag = 1; // ————————————————————–利用这个标志判断出CAN总线出现故障——————————————————-
}
}
}
//
// Check if the cause is the CAN-B receive message object 1
//
else if(status == RX_MSG_OBJ_ID)
{
//
// Get the received message
//
CANMessageGet(CANA_BASE, RX_MSG_OBJ_ID, &sRXCANMessage, true);
//
// Getting to this point means that the RX interrupt occurred on
// message object 1, and the message RX is complete. Clear the
// message object interrupt.
//
CANIntClear(CANA_BASE, RX_MSG_OBJ_ID);
//
// Increment a counter to keep track of how many messages have been
// received. In a real application this could be used to set flags to
// indicate when a message is received.
//
rxMsgCount++;
//
// Since the message was received, clear any error flags.
//
errorFlag = 0;
}
//
// If something unexpected caused the interrupt, this would handle it.
//
else
{
//
// Spurious interrupt handling can go here.
asm (" ESTOP0");
//
}
//
// Clear the global interrupt flag for the CAN interrupt line
//
CANGlobalIntClear(CANA_BASE, CAN_GLB_INT_CANINT0);
}
判断出CAN总线故障后,我尝试把CAN的初始化都重新执行一次,但是还是没有效果。现象是无法发送数据。如下:
Void TaskFxn(Void)
{
while (TRUE)
{
Task_sleep(1000);
if(errorFlag == 1)// ——————————————————- CAN总线故障时重新初始化CAN—————————————————————–
{
CANInit(CANA_BASE);
CANClkSourceSelect(CANA_BASE, 0); // 1000kHz CAN-Clock
CANBitRateSet(CANA_BASE, 200000000, 1000000);
CANIntEnable(CANA_BASE, CAN_INT_MASTER | CAN_INT_ERROR | CAN_INT_STATUS);
CANGlobalIntEnable(CANA_BASE, CAN_GLB_INT_CANINT0);
sRXCANMessage.ui32MsgID = 0x400;// 接收0x400~0x407
sRXCANMessage.ui32MsgIDMask = 0;
sRXCANMessage.ui32Flags = MSG_OBJ_RX_INT_ENABLE | MSG_OBJ_USE_ID_FILTER;
sRXCANMessage.ui32MsgLen = MSG_DATA_LENGTH;
sRXCANMessage.pucMsgData = rxMsgData;
CANMessageSet(CANA_BASE, RX_MSG_OBJ_ID, &sRXCANMessage, MSG_OBJ_TYPE_RX);
CANEnable(CANA_BASE);
asm (" ESTOP0");
errorFlag = 0;
}
}
}