This thread has been locked.
If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.
Hi Susan
目前是使用開發版TM4C1294XL Rev D
一塊開發版測試CAN0與CAN1發送與接收測試
一開始就有提到沒有接transceiver測試
無量測CAN引脚的波形
#include "CANFunctions.h"
extern uint32_t g_ui32SysClock;
volatile uint8_t CAN0ErrFlag = 0;
volatile uint8_t CAN1ErrFlag = 0;
tCANMsgObject CAN0RxMsgObject,CAN0TxMsgObject; //CAN0 have32 objects
tCANMsgObject CAN1RxMsgObject,CAN1TxMsgObject; //CAN1 have32 objects
uint8_t CAN0_Obj1RxData[8],CAN0_Obj2RxData[8],CAN0_Obj3RxData[8];
uint8_t CAN1_Obj1RxData[8],CAN1_Obj2RxData[8],CAN1_Obj3RxData[8];
uint8_t CAN0_Obj1TxData[8],CAN1_Obj1TxData[8];
volatile bool CAN0TxMsgObj4Sent = 0;
volatile bool CAN1TxMsgObj4Sent = 0;
void
CAN0IntHandler(void)
{
uint32_t ui32Status;
//
// Read the CAN interrupt status to find the cause of the interrupt
//
ui32Status = CANIntStatus(CAN0_BASE, CAN_INT_STS_CAUSE);
//
// If the cause is a controller status interrupt, then get the status
//
if(ui32Status == CAN_INT_INTID_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.
//
ui32Status = CANStatusGet(CAN0_BASE, CAN_STS_CONTROL);
CAN0ErrFlag++;
}
//
// Check if the cause is message object 1.
//
else if(ui32Status == 1)
{
CANIntClear(CAN0_BASE, ui32Status);
CAN0RxMsgObject.pui8MsgData = CAN0_Obj1RxData;
CANMessageGet(CAN0_BASE, ui32Status, &CAN0RxMsgObject, 0);
CAN0ErrFlag = 0;
}
//
// Check if the cause is message object 2.
//
else if(ui32Status == 2)
{
CANIntClear(CAN0_BASE, ui32Status);
CAN0RxMsgObject.pui8MsgData = CAN0_Obj2RxData;
CANMessageGet(CAN0_BASE, ui32Status, &CAN0RxMsgObject, 0);
CAN0ErrFlag = 0;
}
//
// Check if the cause is message object 3.
//
else if(ui32Status == 3)
{
CANIntClear(CAN0_BASE, ui32Status);
CAN0RxMsgObject.pui8MsgData = CAN0_Obj3RxData;
CANMessageGet(CAN0_BASE, ui32Status, &CAN0RxMsgObject, 0);
CAN0ErrFlag = 0;
}
// Check if the cause is message object 4, which is used for sending messages.
else if(ui32Status == 4)
{
CANIntClear(CAN0_BASE, ui32Status);
CAN0TxMsgObj4Sent = 1;
CAN0ErrFlag = 0;
}
}
void
CAN1IntHandler(void)
{
uint32_t ui32Status;
//
// Read the CAN interrupt status to find the cause of the interrupt
//
ui32Status = CANIntStatus(CAN1_BASE, CAN_INT_STS_CAUSE);
//
// If the cause is a controller status interrupt, then get the status
//
if(ui32Status == CAN_INT_INTID_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.
//
ui32Status = CANStatusGet(CAN1_BASE, CAN_STS_CONTROL);
CAN1ErrFlag++;
}
//
// Check if the cause is message object 1.
//
else if(ui32Status == 1)
{
CANIntClear(CAN1_BASE, 1);
CAN1RxMsgObject.pui8MsgData = CAN1_Obj1RxData;
CANMessageGet(CAN0_BASE, ui32Status, &CAN1RxMsgObject, 0);
CAN1ErrFlag = 0;
}
//
// Check if the cause is message object 2.
//
else if(ui32Status == 2)
{
CANIntClear(CAN1_BASE, 2);
CAN1RxMsgObject.pui8MsgData = CAN1_Obj2RxData;
CANMessageGet(CAN0_BASE, ui32Status, &CAN1RxMsgObject, 0);
CAN1ErrFlag = 0;
}
//
// Check if the cause is message object 3.
//
else if(ui32Status == 3)
{
CANIntClear(CAN1_BASE, 3);
CAN1RxMsgObject.pui8MsgData = CAN1_Obj3RxData;
CANMessageGet(CAN0_BASE, ui32Status, &CAN1RxMsgObject, 0);
CAN1ErrFlag = 0;
}
// Check if the cause is message object 4, which is used for sending messages.
else if(ui32Status == 4)
{
CANIntClear(CAN1_BASE, ui32Status);
CAN1TxMsgObj4Sent = 1;
CAN1ErrFlag = 0;
}
}
void CAN0RXConfig(uint8_t ObjNum,uint32_t MsgID)
{
// Initialize a message object to receive CAN messages with ID 0x1001.
// The expected ID must be set along with the mask to indicate that all
// bits in the ID must match.
//
CAN0RxMsgObject.ui32MsgID = MsgID;
CAN0RxMsgObject.ui32MsgIDMask = 0xfffff;
CAN0RxMsgObject.ui32Flags = (MSG_OBJ_RX_INT_ENABLE | MSG_OBJ_USE_ID_FILTER |
MSG_OBJ_EXTENDED_ID);
CAN0RxMsgObject.ui32MsgLen = 8;
// Now load the message object into the CAN peripheral message object 1.
// Once loaded the CAN will receive any messages with this CAN ID into
// this message object, and an interrupt will occur.
//
CANMessageSet(CAN0_BASE, ObjNum, &CAN0RxMsgObject, MSG_OBJ_TYPE_RX);
}
void CAN1RXConfig(uint8_t ObjNum,uint32_t MsgID)
{
// Initialize a message object to receive CAN messages with ID 0x1001.
// The expected ID must be set along with the mask to indicate that all
// bits in the ID must match.
//
CAN1RxMsgObject.ui32MsgID = MsgID;
CAN1RxMsgObject.ui32MsgIDMask = 0xfffff;
CAN1RxMsgObject.ui32Flags = (MSG_OBJ_RX_INT_ENABLE | MSG_OBJ_USE_ID_FILTER |
MSG_OBJ_EXTENDED_ID);
CAN1RxMsgObject.ui32MsgLen = 8;
// Now load the message object into the CAN peripheral message object 1.
// Once loaded the CAN will receive any messages with this CAN ID into
// this message object, and an interrupt will occur.
//
CANMessageSet(CAN0_BASE, ObjNum, &CAN1RxMsgObject, MSG_OBJ_TYPE_RX);
}
void CANMultiRXConfig()
{
CAN0RXConfig(1,0x1001);
CAN0RXConfig(2,0x1002);
CAN0RXConfig(3,0x1003);
CAN1RXConfig(1,0x2001);
CAN1RXConfig(2,0x2002);
CAN1RXConfig(3,0x2003);
}
void CAN0TXSend(uint8_t ObjNum,uint32_t MsgID)
{
CAN0TxMsgObject.ui32MsgID = MsgID;
CAN0TxMsgObject.ui32MsgIDMask = 0;
CAN0TxMsgObject.ui32Flags = MSG_OBJ_TX_INT_ENABLE;
CAN0TxMsgObject.ui32MsgLen = sizeof(CAN0_Obj1TxData);
CAN0_Obj1TxData[0]++;
CAN0TxMsgObject.pui8MsgData = CAN0_Obj1TxData;
CAN0TxMsgObj4Sent=0;
CANMessageSet(CAN0_BASE, ObjNum, &CAN0TxMsgObject, MSG_OBJ_TYPE_TX);
}
void CAN1TXSend(uint8_t ObjNum,uint32_t MsgID)
{
CAN1TxMsgObject.ui32MsgID = MsgID;
CAN1TxMsgObject.ui32MsgIDMask = 0;
CAN1TxMsgObject.ui32Flags = MSG_OBJ_TX_INT_ENABLE;
CAN1TxMsgObject.ui32MsgLen = sizeof(CAN1_Obj1TxData);
CAN1_Obj1TxData[0]++;
CAN1TxMsgObject.pui8MsgData = CAN1_Obj1TxData;
CAN1TxMsgObj4Sent=0;
CANMessageSet(CAN1_BASE, ObjNum, &CAN1TxMsgObject, MSG_OBJ_TYPE_TX);
}
void CANInitial(void)
{
SysCtlPeripheralEnable(SYSCTL_PERIPH_CAN0); // The GPIO port and pins have been set up for CAN. The CAN peripheral must be enabled.
CANInit(CAN0_BASE); // Initialize the CAN controller
CANBitRateSet(CAN0_BASE, g_ui32SysClock, 1000000u); // Set up the 1M bit rate for the CAN bus.
//HWREG(CAN0_BASE+CAN_O_CTL) |= CAN_CTL_TEST;
//HWREG(CAN0_BASE+CAN_O_TST) |= CAN_TST_LBACK;
//CANIntRegister(CAN0_BASE, CAN0IntHandler); // if using dynamic vectors
CANIntEnable(CAN0_BASE, CAN_INT_MASTER | CAN_INT_ERROR | CAN_INT_STATUS);
IntEnable(INT_CAN0);// Enable the CAN interrupt on the processor (NVIC).
CANEnable(CAN0_BASE);// Enable the CAN for operation.
SysCtlPeripheralEnable(SYSCTL_PERIPH_CAN1); // The GPIO port and pins have been set up for CAN. The CAN peripheral must be enabled.
CANInit(CAN1_BASE); // Initialize the CAN controller
CANBitRateSet(CAN1_BASE, g_ui32SysClock, 1000000u); // Set up the 1M bit rate for the CAN bus.
//CANIntRegister(CAN1_BASE, CAN1IntHandler); // if using dynamic vectors
CANIntEnable(CAN1_BASE, CAN_INT_MASTER | CAN_INT_ERROR | CAN_INT_STATUS);
IntEnable(INT_CAN1);// Enable the CAN interrupt on the processor (NVIC).
CANEnable(CAN1_BASE);// Enable the CAN for operation.
CANMultiRXConfig();
}