主题中讨论的其他器件:C2000WARE
大家好、
我一直在努力将 CAN_EXTERNAL_Transmit 示例修改为与物理2节点(2个板)系统的通信。
我使用的是 CANA、而不是 CANB。 我成功测试了单向通信、即我可以从一个节点传输数据、并在另一个节点上正确接收数据。 对于我的应用、我有一个主节点和一个从节点。 从机每次从机接收到一条消息时都需要发回一个特定的数据。 为此、我想我可以简单地构建消息、然后在由 CANbus 消息接收触发的 ISR 中使用 CANMessageSet。
为什么这不起作用? 我的错在哪里? 这是正确的方法吗? 我附上下面的代码。 接收到之后、我基本上停用了用于在主代码中传输的代码并在 ISR 中使用了相同的函数。
非常感谢、
Nicola
//
// Main
//
void main(void)
{
InitSysCtrl();
InitGpio();
// additional function for setting up toggling checking pins for timing
InitGpioPins();
// Setup GPIO pin mux for CAN-A TX/RX and CAN-B TX/RX
// NC modification according to board
GPIO_SetupPinMux(36, GPIO_MUX_CPU1, 6); //GPIO36 - CANRXA
GPIO_SetupPinOptions(36, GPIO_INPUT, GPIO_ASYNC);
GPIO_SetupPinMux(37, GPIO_MUX_CPU1, 6); //GPIO36 - CANTXA
GPIO_SetupPinOptions(37, GPIO_OUTPUT, GPIO_PUSHPULL);
// Initialize the CAN controllers
CANInit(CANA_BASE);
// Setup CAN to be clocked off the PLL output clock
CANClkSourceSelect(CANA_BASE, 0); // 500kHz CAN-Clock
// set up timing 1Mbit/s
CANBitRateSet(CANA_BASE, 200000000, 1000000);
// Enable interrupts on the CAN B peripheral.
CANIntEnable(CANA_BASE, CAN_INT_MASTER | CAN_INT_ERROR | CAN_INT_STATUS);
// Clear all interrupts and initialize PIE vector table:
// Disable CPU interrupts
DINT;
// Initialize the PIE control registers to their default state.
// The default state is all PIE interrupts disabled and flags
// are cleared.
InitPieCtrl();
// Disable CPU interrupts and clear all CPU interrupt flags
IER = 0x0000;
IFR = 0x0000;
InitPieVectTable();
EALLOW;
PieVectTable.CANA0_INT = canaISR;
EDIS;
PieCtrlRegs.PIEIER9.bit.INTx5 = 1;
IER |= M_INT9;
EINT;
CANGlobalIntEnable(CANA_BASE, CAN_GLB_INT_CANINT0); // enable CANA
//
// Initialize the transmit message object used for sending CAN messages.
// Message Object Parameters:
// Message Identifier: 0x5555
// Message ID Mask: 0x0
// Message Object Flags: None
// Message Data Length: 4 Bytes
// Message Transmit data: txMsgData
//
//sTXCANMessage.ui32MsgID = 0x5555; // deafult example message
sTXCANMessage.ui32MsgID = 0x096; // master to slave
sTXCANMessage.ui32MsgIDMask = 0;
sTXCANMessage.ui32Flags = 0;
sTXCANMessage.ui32MsgLen = MSG_DATA_LENGTH;
sTXCANMessage.pucMsgData = txMsgData;
//
// Initialize the receive message object used for receiving CAN messages.
// Message Object Parameters:
// Message Identifier: 0x5555
// Message ID Mask: 0x0
// Message Object Flags: Receive Interrupt
// Message Data Length: 4 Bytes
// Message Receive data: rxMsgData
//
//sRXCANMessage.ui32MsgID = 0x5555; // deafult example message
sRXCANMessage.ui32MsgID = 0x226; // receive message from slave
sRXCANMessage.ui32MsgIDMask = 0;
sRXCANMessage.ui32Flags = MSG_OBJ_RX_INT_ENABLE;
sRXCANMessage.ui32MsgLen = MSG_DATA_LENGTH;
sRXCANMessage.pucMsgData = rxMsgData;
// set received message
CANMessageSet(CANA_BASE, RX_MSG_OBJ_ID, &sRXCANMessage, MSG_OBJ_TYPE_RX);
// Initialize the transmit message object data buffer to be sent
txMsgData[0] = 0x12;
txMsgData[1] = 0x34;
txMsgData[2] = 0x56;
txMsgData[3] = 0x78;
txMsgData[4] = 0x12;
txMsgData[5] = 0x34;
txMsgData[6] = 0x56;
txMsgData[7] = 0x78;
CANEnable(CANA_BASE); // Start CAN module A and B operations
// DE ACTIVATED THIS PART OF CODE, THIS NODE RECEIVES THE MESSAGE AND THEN TRANSMIT ACCORDINGLY
#if 0
//for(i = 0; i < TXCOUNT; i++)
for(;;)
{
// Check the error flag to see if errors occurred
if(errorFlag)
{
asm(" ESTOP0");
}
// timing the transmission of the message
GpioDataRegs.GPBSET.bit.GPIO53 = 1; // set test point high for execution time measurement
// verify transmission
if(txMsgCount == rxMsgCount)
{
// Transmit Message
CANMessageSet(CANA_BASE, TX_MSG_OBJ_ID, &sTXCANMessage,
MSG_OBJ_TYPE_TX);
txMsgCount++;
}
else
{
errorFlag = 1;
}
GpioDataRegs.GPBCLEAR.bit.GPIO53 = 1; // set point low for execution time measurements
DELAY_US(1000 * 1000); // delay of 1 sec
// Increment the value in the transmitted message data
txMsgData[0] += 0x01;
txMsgData[1] += 0x01;
txMsgData[2] += 0x01;
txMsgData[3] += 0x01;
// Reset data if exceeds a byte
if(txMsgData[0] > 0xFF)
txMsgData[0] = 0;
if(txMsgData[1] > 0xFF)
txMsgData[1] = 0;
if(txMsgData[2] > 0xFF)
txMsgData[2] = 0;
if(txMsgData[3] > 0xFF)
txMsgData[3] = 0;
}
asm(" ESTOP0"); // Stop application
#endif
}
//
// CAN B ISR - The interrupt service routine called when a CAN interrupt is
// triggered on CAN module B.
// MODIFIED TO CAN A
__interrupt void
canaISR(void)
{
uint32_t status;
// testing time
//GpioDataRegs.GPBSET.bit.GPIO53 = 1; // set test point high for execution time measurement
// 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))
{
// Set a flag to indicate some errors may have occurred.
errorFlag = 1;
}
}
// 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;
// MODIFICATION ---
trigger_transmit = true;
// before transmitting increment the data (as in main)
// Increment the value in the transmitted message data.
txMsgData[0] += 0x01;
txMsgData[1] += 0x01;
txMsgData[2] += 0x01;
txMsgData[3] += 0x01;
// Reset data if exceeds a byte
if(txMsgData[0] > 0xFF)
txMsgData[0] = 0;
if(txMsgData[1] > 0xFF)
txMsgData[1] = 0;
if(txMsgData[2] > 0xFF)
txMsgData[2] = 0;
if(txMsgData[3] > 0xFF)
txMsgData[3] = 0;
}
// If something unexpected caused the interrupt, this would handle it.
else
{
//
// Spurious interrupt handling can go here.
//
}
// THIS SECTION GENERATES ERROR WHEN RUNNING
#if 0
// ---------------------------------------------------------
if (trigger_transmit == true)
{
CANMessageSet(CANA_BASE, TX_MSG_OBJ_ID, &sTXCANMessage,
MSG_OBJ_TYPE_TX);
txMsgCount++;
trigger_transmit = false;
}
// ---------------------------------------------------------
#endif
// Clear the global interrupt flag for the CAN interrupt line
CANGlobalIntClear(CANA_BASE, CAN_GLB_INT_CANINT0);
// Acknowledge this interrupt located in group 9
PieCtrlRegs.PIEACK.all = PIEACK_GROUP9;
// GpioDataRegs.GPBCLEAR.bit.GPIO53 = 1; // set point low for execution time measurements
}