你(们)好
我正在使用28388D 进行开发。
CAN-FD 是一种必要的功能、正在实施中。
TX 正在轮询、RX 是中断。
因此、我在 C2000中搜索了 V304和 V400的相关示例、并尝试运行它们。
在 V304的 mCAN_ex_2_external_loopback _receive 示例中、确认中断仅在接收到数据时执行一次。
所提供的示例确实只有一个时间接收中断吗?
我有什么问题吗?
并且、当一个错误中断发生时、除了清除它之外、还有其他操作吗?
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.
你(们)好
我正在使用28388D 进行开发。
CAN-FD 是一种必要的功能、正在实施中。
TX 正在轮询、RX 是中断。
因此、我在 C2000中搜索了 V304和 V400的相关示例、并尝试运行它们。
在 V304的 mCAN_ex_2_external_loopback _receive 示例中、确认中断仅在接收到数据时执行一次。
所提供的示例确实只有一个时间接收中断吗?
我有什么问题吗?
并且、当一个错误中断发生时、除了清除它之外、还有其他操作吗?
有人在这里吗?
我看到了几个问题和解答、包括上面的链接、但它仍然没有解决。
我解决了这个问题。
问题
MCAN_enableIntr (MCAN0_BASE、MCAN_INTR_MASK_ALL、0);
MCAN_enableIntr (MCAN0_BASE、MCAN_INTR_SRC_Dedicated _RX_buff _MSG | MCAN_INTR_SRC_RX_FIFO0_NEW_MSG | MCAN_INTR_SRC_RX_FIFO1_NEW_MSG、1);
MCAN_enableIntr (MCAN0_BASE、MCAN_INTR_SRC_RX_FIFO0_NEW_MSG | MCAN_INTR_SRC_RX_FIFO1_NEW_MSG、0);
MCAN_selectIntrLine (MCAN0_BASE、MCAN_INTR_SRC_Dedicated RX_buff _MSG | MCAN_INTR_SRC_RX_FIFO0_NEW_NUM | MCAN_INTR_SRC_RX_FIFO1_NEW_MSG、MCAN_INTR_LINE_MSG);
MCAN_enableIntrLine (MCAN0_BASE、MCAN_INTR_LINE_NUM_1、1U);
正常
MCAN_enableIntr (MCAN0_BASE、MCAN_INTR_MASK_ALL、1);
MCAN_enableIntr (MCAN0_BASE、MCAN_INTR_SRC_RES_ADDR_ACCESS | MCAN_INTR_SRC_TIMESTAMP_wraparound、0);
MCAN_selectIntrLine (MCAN0_BASE、MCAN_INTR_SRC_RX_FIFO1_NEW_MSG、MCAN_INTR_LINE_NUM_1);
MCAN_enableIntrLine (MCAN0_BASE、MCAN_INTR_LINE_NUM_1、1U);
我的意思是禁用所有中断并仅启用我需要的中断。
但是、中断在第一次之后没有发生。
正常情况是启用所有中断并禁用不必要的中断。
我不知道两者之间的区别。
我还有其他问题。
如何使用 RX BUF 来使用连续接收中断?
MCAN_INTR_SRC_Dedicated RX_buff MSG、
MCAN_readMsgRam (MCAN0_BASE、MCAN_MEM_TYP_BUF、0U、MCAN_RX_FIFO_NUM_1、&drv_mCAN_Rx_msg);
使用 RX FIFO 时、有一个连续接收中断、但为什么它跳转到中断两次?
__interrupt void drv_irq1_MCAN(void)
{
/*
* MCAN_INTR_SRC_RX_FIFO0_NEW_MSG = 0x00000001U
* MCAN_INTR_SRC_RX_FIFO0_WATERMARK = 0x00000002U
* MCAN_INTR_SRC_RX_FIFO0_FULL = 0x00000004U
* MCAN_INTR_SRC_RX_FIFO0_MSG_LOST = 0x00000008U
* MCAN_INTR_SRC_RX_FIFO1_NEW_MSG = 0x00000010U
* MCAN_INTR_SRC_RX_FIFO1_WATERMARK = 0x00000020U
* MCAN_INTR_SRC_RX_FIFO1_FULL = 0x00000040U
* MCAN_INTR_SRC_RX_FIFO1_MSG_LOST = 0x00000080U
* MCAN_INTR_SRC_HIGH_PRIO_MSG = 0x00000100U
* MCAN_INTR_SRC_TRANS_COMPLETE = 0x00000200U
* MCAN_INTR_SRC_TRANS_CANCEL_FINISH = 0x00000400U
* MCAN_INTR_SRC_TX_FIFO_EMPTY = 0x00000800U
* MCAN_INTR_SRC_TX_EVT_FIFO_NEW_ENTRY = 0x00001000U
* MCAN_INTR_SRC_TX_EVT_FIFO_WATERMARK = 0x00002000U
* MCAN_INTR_SRC_TX_EVT_FIFO_FULL = 0x00004000U
* MCAN_INTR_SRC_TX_EVT_FIFO_ELEM_LOST = 0x00008000U
* MCAN_INTR_SRC_TIMESTAMP_WRAPAROUND = 0x00010000U
* MCAN_INTR_SRC_MSG_RAM_ACCESS_FAILURE = 0x00020000U
* MCAN_INTR_SRC_TIMEOUT = 0x00040000U
* MCAN_INTR_SRC_DEDICATED_RX_BUFF_MSG = 0x00080000U
* MCAN_INTR_SRC_BIT_ERR_CORRECTED = 0x00100000U
* MCAN_INTR_SRC_BIT_ERR_UNCORRECTED = 0x00200000U
* MCAN_INTR_SRC_ERR_LOG_OVRFLW = 0x00400000U
* MCAN_INTR_SRC_ERR_PASSIVE = 0x00800000U
* MCAN_INTR_SRC_WARNING_STATUS = 0x01000000U
* MCAN_INTR_SRC_BUS_OFF_STATUS = 0x02000000U
* MCAN_INTR_SRC_WATCHDOG = 0x04000000U
* MCAN_INTR_SRC_PROTOCOL_ERR_ARB = 0x08000000U
* MCAN_INTR_SRC_PROTOCOL_ERR_DATA = 0x10000000U
* MCAN_INTR_SRC_RES_ADDR_ACCESS = 0x20000000U
*/
//uint32_t intrStatus;
intrStatus1 = MCAN_getIntrStatus(MCAN0_BASE);
isrIntr1Flag++;
printf("\r\nintrStatus1 : 0x%lx, ", intrStatus1);
if (MCAN_getIntrStatus(MCAN0_BASE) & MCAN_INTR_SRC_RX_FIFO0_NEW_MSG) printf("Rx FIFO 0 New Message interrupt\r\n");
if (MCAN_getIntrStatus(MCAN0_BASE) & MCAN_INTR_SRC_RX_FIFO0_WATERMARK) printf("Rx FIFO 0 Watermark Reached interrupt\r\n");
if (MCAN_getIntrStatus(MCAN0_BASE) & MCAN_INTR_SRC_RX_FIFO0_FULL) printf("Rx FIFO 0 Full interrupt\r\n");
if (MCAN_getIntrStatus(MCAN0_BASE) & MCAN_INTR_SRC_RX_FIFO0_MSG_LOST) printf("Rx FIFO 0 Message Lost interrupt\r\n");
if (MCAN_getIntrStatus(MCAN0_BASE) & MCAN_INTR_SRC_RX_FIFO1_NEW_MSG) printf("Rx FIFO 1 New Message interrupt\r\n");
if (MCAN_getIntrStatus(MCAN0_BASE) & MCAN_INTR_SRC_RX_FIFO1_WATERMARK) printf("Rx FIFO 1 Watermark Reached interrupt\r\n");
if (MCAN_getIntrStatus(MCAN0_BASE) & MCAN_INTR_SRC_RX_FIFO1_FULL) printf("Rx FIFO 1 Full interrupt\r\n");
if (MCAN_getIntrStatus(MCAN0_BASE) & MCAN_INTR_SRC_RX_FIFO1_MSG_LOST) printf("Rx FIFO 1 Message Lost interrupt\r\n");
if (MCAN_getIntrStatus(MCAN0_BASE) & MCAN_INTR_SRC_HIGH_PRIO_MSG) printf("High Priority Message interrupt\r\n");
if (MCAN_getIntrStatus(MCAN0_BASE) & MCAN_INTR_SRC_TRANS_COMPLETE) printf("Transmission Completed interrupt\r\n");
if (MCAN_getIntrStatus(MCAN0_BASE) & MCAN_INTR_SRC_TRANS_CANCEL_FINISH) printf("Transmission Cancellation Finished interrupt\r\n");
if (MCAN_getIntrStatus(MCAN0_BASE) & MCAN_INTR_SRC_TX_FIFO_EMPTY) printf("Tx FIFO Empty interrupt\r\n");
if (MCAN_getIntrStatus(MCAN0_BASE) & MCAN_INTR_SRC_TX_EVT_FIFO_NEW_ENTRY) printf("Tx Event FIFO New Entry interrupt\r\n");
if (MCAN_getIntrStatus(MCAN0_BASE) & MCAN_INTR_SRC_TX_EVT_FIFO_WATERMARK) printf("Tx Event FIFO Watermark Reached interrupt\r\n");
if (MCAN_getIntrStatus(MCAN0_BASE) & MCAN_INTR_SRC_TX_EVT_FIFO_FULL) printf("Tx Event FIFO Full interrupt\r\n");
if (MCAN_getIntrStatus(MCAN0_BASE) & MCAN_INTR_SRC_TX_EVT_FIFO_ELEM_LOST) printf("Tx Event FIFO Element Lost interrupt\r\n");
if (MCAN_getIntrStatus(MCAN0_BASE) & MCAN_INTR_SRC_TIMESTAMP_WRAPAROUND) printf("Timestamp Wraparound interrupt\r\n");
if (MCAN_getIntrStatus(MCAN0_BASE) & MCAN_INTR_SRC_MSG_RAM_ACCESS_FAILURE) printf("Message RAM Access Failure interrupt\r\n");
if (MCAN_getIntrStatus(MCAN0_BASE) & MCAN_INTR_SRC_TIMEOUT) printf("Timeout Occurred interrupt\r\n");
if (MCAN_getIntrStatus(MCAN0_BASE) & MCAN_INTR_SRC_DEDICATED_RX_BUFF_MSG) printf("Message stored to Dedicated Rx Buffer interrupt\r\n");
if (MCAN_getIntrStatus(MCAN0_BASE) & MCAN_INTR_SRC_BIT_ERR_CORRECTED) printf("Bit Error Corrected interrupt\r\n");
if (MCAN_getIntrStatus(MCAN0_BASE) & MCAN_INTR_SRC_BIT_ERR_UNCORRECTED) printf("Bit Error Uncorrected interrupt\r\n");
if (MCAN_getIntrStatus(MCAN0_BASE) & MCAN_INTR_SRC_ERR_LOG_OVRFLW) printf("Error Logging Overflow interrupt\r\n");
if (MCAN_getIntrStatus(MCAN0_BASE) & MCAN_INTR_SRC_ERR_PASSIVE) printf("Error Passive interrupt\r\n");
if (MCAN_getIntrStatus(MCAN0_BASE) & MCAN_INTR_SRC_WARNING_STATUS) printf("Warning Status interrupt\r\n");
if (MCAN_getIntrStatus(MCAN0_BASE) & MCAN_INTR_SRC_BUS_OFF_STATUS) printf("Bus_Off Status interrupt\r\n");
if (MCAN_getIntrStatus(MCAN0_BASE) & MCAN_INTR_SRC_WATCHDOG) printf("Watchdog Interrupt interrupt\r\n");
if (MCAN_getIntrStatus(MCAN0_BASE) & MCAN_INTR_SRC_PROTOCOL_ERR_ARB) printf("Protocol Error in Arbitration Phase interrupt\r\n");
if (MCAN_getIntrStatus(MCAN0_BASE) & MCAN_INTR_SRC_PROTOCOL_ERR_DATA) printf("Protocol Error in Data Phase interrupt\r\n");
if (MCAN_getIntrStatus(MCAN0_BASE) & MCAN_INTR_SRC_RES_ADDR_ACCESS) printf("Access to Reserved Address interrupt\r\n");
if (intrStatus1 & MCAN_INTR_SRC_DEDICATED_RX_BUFF_MSG || intrStatus1 & MCAN_INTR_SRC_RX_FIFO0_NEW_MSG || intrStatus1 & MCAN_INTR_SRC_RX_FIFO1_NEW_MSG) {
//MCAN_getNewDataStatus(MCAN0_BASE, &newData);
MCAN_readMsgRam(MCAN0_BASE, MCAN_MEM_TYPE_FIFO, 0U, MCAN_RX_FIFO_NUM_1, &drv_mcan_rx_msg);
drv_mcan_rx_fifo_status.num = MCAN_RX_FIFO_NUM_1;
//MCAN_getRxFIFOStatus(MCAN0_BASE, &drv_mcan_rx_fifo_status);
//MCAN_writeRxFIFOAck(MCAN0_BASE, MCAN_RX_FIFO_NUM_1, drv_mcan_rx_fifo_status.getIdx);
newData.statusHigh = 0;
newData.statusLow = 0;
//MCAN_clearNewDataStatus(MCAN0_BASE, &newData);
isrIntr1_1Flag++;
}
HW_WR_FIELD32(MCAN0_BASE + MCAN_MCANSS_EOI, MCAN_MCANSS_EOI, 0x2U);
//MCAN_extTSWriteEOI(MCAN0_BASE);
//MCAN_extTSClearRawStatus(MCAN0_BASE);
MCAN_clearIntrStatus(MCAN0_BASE, intrStatus1);
// Acknowledge this interrupt located in group 9
Interrupt_clearACKGroup(INTERRUPT_ACK_GROUP9);
}

谢谢、
这是我的最后一个 mcan 源。
它正在工作...但我不知道为什么会发生 IRQ 二维...
/*
* drv_canfd.c
*
* Created on: 2021. 12. 9.
* Author: JOO
*/
#include <string.h>
#include <stdio.h>
#include "f28x_project.h"
#include "driverlib.h"
#include "device.h"
#include "stw_dataTypes.h"
#include "hw_types_mcan.h"
#include "drv_mcan.h"
#include "drv_gpio.h"
#ifdef CPU1
#ifdef _FLASH
#pragma CODE_SECTION(drv_WriteMCAN, ".TI.ramfunc");
#pragma CODE_SECTION(drv_irq_MCAN0, ".TI.ramfunc");
#endif
#define MCAN_STD_ID_FILT_START_ADDR (0U)
#define MCAN_STD_ID_FILTER_NUM (1U)
#define MCAN_EXT_ID_FILT_START_ADDR (48U)
#define MCAN_EXT_ID_FILTER_NUM (1U)
#define MCAN_TX_EVENT_START_ADDR (100U)
#define MCAN_TX_BUFF_START_ADDR (148U)
#define MCAN_FIFO_0_START_ADDR (548U)
#define MCAN_FIFO_1_START_ADDR (748U)
#define MCAN_RX_BUFF_START_ADDR (948U)
#define MCAN_EXT_ID_AND_MASK (0x1FFFFFFFU)
#define MCAN_TS_PRESCALAR (0xB0)
MCAN_TxBufElement drv_mcan_tx_msg;
MCAN_RxBufElement drv_mcan_rx_msg;
uint32_t drv_irq_mcan0_status = 0;
uint32_t drv_irq_mcan0_recv_cnt = 0;
static void drv_ConfigMCANGpio(void);
static void drv_ConfigMCAN(void);
__interrupt void drv_irq_MCAN0(void);
static void drv_ConfigMCANGpio(void)
{
#ifndef _28377D
//MCAN(CAN-FD) RX
drv_ConfigGPIO(GPIO_CORE_CPU1, 5, 0xFFFF, GPIO_5_MCAN_RX, 0xFFFF, 0xFFFF, 0xFFFF);
//MCAN(CAN-FD) TX
drv_ConfigGPIO(GPIO_CORE_CPU1, 4, 0xFFFF, GPIO_4_MCAN_TX, 0xFFFF, 0xFFFF, 0xFFFF);
#endif
}
static void drv_ConfigMCAN(void)
{
#ifndef _28377D
MCAN_RevisionId revId;
MCAN_InitParams initParams;
MCAN_ConfigParams configParams;
MCAN_MsgRAMConfigParams msgRAMConfigParams;
MCAN_StdMsgIDFilterElement stdFiltelem;
MCAN_ExtMsgIDFilterElement extFiltelem;
MCAN_BitTimingParams bitTimes;
// Initialize MCAN Init parameters.
initParams.fdMode = 0x1U; // FD operation enabled.
initParams.brsEnable = 0x1U; // Bit rate switching for transmissions enabled.
initParams.txpEnable = 0x1U; // Transmit pause disabled.
initParams.efbi = 0x0U; // Edge filtering disabled.
initParams.pxhddisable = 0x0U; // Protocol exception handling enabled.
initParams.darEnable = 0x1U; // Automatic retransmission of messages not transmitted successfully enabled.
initParams.wkupReqEnable = 0x1U; // Wakeup request is enabled.
initParams.autoWkupEnable = 0x1U; // Auto-Wakeup is enabled.
initParams.emulationEnable = 0x1U; // Emulation/Debug Suspend is enabled.
initParams.tdcEnable = 0x1U; // Transmitter Delay Compensation is enabled.
initParams.wdcPreload = 0xFFU; // Start value of the Message RAM Watchdog Counter preload.
// Transmitter Delay Compensation parameters.
initParams.tdcConfig.tdcf = 0xAU;
initParams.tdcConfig.tdco = 0x6U;
// Initialize MCAN Config parameters.
configParams.monEnable = 0x0U; // Bus Monitoring Mode is disabled.
configParams.asmEnable = 0x0U; // Normal CAN operation.
configParams.tsPrescalar = 0x0U; // Prescaler Value.
configParams.tsSelect = 0x0U; // Timestamp counter value.
configParams.timeoutSelect = MCAN_TIMEOUT_SELECT_CONT; // Time-out counter source select.
configParams.timeoutPreload = 0xFFFFU; // Start value of the Timeout Counter.
configParams.timeoutCntEnable = 0x0U; // Time-out Counter is disabled.
configParams.filterConfig.rrfs = 0x1U; // Reject all remote frames with 29-bit extended IDs.
configParams.filterConfig.rrfe = 0x1U; // Reject all remote frames with 11-bit standard IDs.
configParams.filterConfig.anfe = 0x1U; // Accept in Rx FIFO 1.
configParams.filterConfig.anfs = 0x1U; // Accept in Rx FIFO 1.
// Initialize Message RAM Sections Configuration Parameters
//msgRAMConfigParams.flssa = MCAN_STD_ID_FILT_START_ADDR; // Standard ID Filter List Start Address.
//msgRAMConfigParams.lss = MCAN_STD_ID_FILTER_NUM; // List Size: Standard ID.
//msgRAMConfigParams.flesa = MCAN_EXT_ID_FILT_START_ADDR; // Extended ID Filter List Start Address.
//msgRAMConfigParams.lse = MCAN_EXT_ID_FILTER_NUM; // List Size: Extended ID.
msgRAMConfigParams.txStartAddr = MCAN_TX_BUFF_START_ADDR; // Tx Buffers Start Address.
msgRAMConfigParams.txBufNum = 1; // Number of Dedicated Transmit Buffers.
msgRAMConfigParams.txFIFOSize = 1; // Tx FIFO/Queue.
msgRAMConfigParams.txBufMode = 1U; //Tx FIFO operation
msgRAMConfigParams.txBufElemSize = MCAN_ELEM_SIZE_64BYTES; // Tx Buffer Element Size.
msgRAMConfigParams.txEventFIFOStartAddr = MCAN_TX_EVENT_START_ADDR; // Tx Event FIFO Start Address.
msgRAMConfigParams.txEventFIFOSize = 1; // Event FIFO Size.
msgRAMConfigParams.txEventFIFOWaterMark = 0; // Level for Tx Event FIFO watermark interrupt.
msgRAMConfigParams.rxFIFO0startAddr = MCAN_FIFO_0_START_ADDR; // Rx FIFO0 Start Address.
msgRAMConfigParams.rxFIFO0size = 1; // Number of Rx FIFO elements.
msgRAMConfigParams.rxFIFO0waterMark = 0;
msgRAMConfigParams.rxFIFO0OpMode = 1U;
msgRAMConfigParams.rxFIFO1startAddr = MCAN_FIFO_1_START_ADDR; // Rx FIFO1 Start Address.
msgRAMConfigParams.rxFIFO1size = 1; // Number of Rx FIFO elements.
msgRAMConfigParams.rxFIFO1waterMark = 0; // Level for Rx FIFO 1 watermark interrupt.
msgRAMConfigParams.rxFIFO1OpMode = 1U; // FIFO blocking mode.
msgRAMConfigParams.rxBufStartAddr = MCAN_RX_BUFF_START_ADDR; // Rx Buffer Start Address.
msgRAMConfigParams.rxBufElemSize = MCAN_ELEM_SIZE_64BYTES; // Rx Buffer Element Size.
msgRAMConfigParams.rxFIFO0ElemSize = MCAN_ELEM_SIZE_64BYTES; // Rx FIFO0 Element Size.
msgRAMConfigParams.rxFIFO1ElemSize = MCAN_ELEM_SIZE_64BYTES; // Rx FIFO1 Element Size.
// Initialize Tx Buffer Configuration parameters.
//stdFiltelem.sfid2 = 0x0U; // Standard Filter ID 2.
//stdFiltelem.sfid1 = 0x4U; // Standard Filter ID 1.
//stdFiltelem.sfec = 0x7U; // Store into Rx Buffer or as debug message, configuration of SFT[1:0] ignored.
//stdFiltelem.sft = 0x11U; // Range filter from SFID1 to SFID2.
// Initialize Tx Buffer Configuration parameters.
//extFiltelem.efid2 = 0x0U;
//extFiltelem.efid1 = 0x0U;
//extFiltelem.efec = 0x0U;
//extFiltelem.eft = 0x11U;
#if 1
/*
* MCANBitClk = CM_Clk/MCANCLKDIV
* NominalbitTime = (NTSEG1 + 1) + (NTSEG2 + 1) + 1
* NominalBRP = (NBRP+1)
* FinalNominalBaudRate = MCANBitClk/( NominalBRP * NominalbitTime)
*
* DatabitTime = (DTSEG1 + 1) + (DTSEG2 + 1) + 1
* DataBRP = (DBRP+1)
* FinalDataBaudRate = MCANBitClk/( DataBRP * DatabitTime)
*/
// Nominal Bit Rate of 500 kbps & Data bit rate of 1 Mbps
// Initialize bit timings.
bitTimes.nomRatePrescalar = 0x3U; // Nominal Baud Rate Pre-scaler.
bitTimes.nomTimeSeg1 = 0x9U; // Nominal Time segment before sample point.
bitTimes.nomTimeSeg2 = 0x8U; // Nominal Time segment after sample point.
bitTimes.nomSynchJumpWidth = 0x8U; // Nominal (Re)Synchronization Jump Width Range.
bitTimes.dataRatePrescalar = 0x1U; // Data Baud Rate Pre-scaler.
bitTimes.dataTimeSeg1 = 0x9U; // Data Time segment before sample point.
bitTimes.dataTimeSeg2 = 0x8U; // Data Time segment after sample point.
bitTimes.dataSynchJumpWidth = 0x8U; // Data (Re)Synchronization Jump Width.
#endif
// Get MCANSS Revision ID
MCAN_getRevisionId(MCAN0_BASE, &revId);
// Wait for memory initialization to happen.
while (FALSE == MCAN_isMemInitDone(MCAN0_BASE)) {
}
// Put MCAN in SW initialization mode.
MCAN_setOpMode(MCAN0_BASE, MCAN_OPERATION_MODE_SW_INIT);
// Wait till MCAN is not initialized.
while (MCAN_OPERATION_MODE_SW_INIT != MCAN_getOpMode(MCAN0_BASE)) {
}
// Initialize MCAN module.
MCAN_init(MCAN0_BASE, &initParams);
// Configure MCAN module.
MCAN_config(MCAN0_BASE, &configParams);
// Enable external timeStamp overflow interrupt.
MCAN_extTSEnableIntr(MCAN0_BASE, 1);
// Configure TimeStamp Counter.
MCAN_extTSCounterConfig(MCAN0_BASE, MCAN_TS_PRESCALAR);
// Configure Bit timings.
MCAN_setBitTime(MCAN0_BASE, &bitTimes);
// Set Extended ID Mask.
MCAN_setExtIDAndMask(MCAN0_BASE, MCAN_EXT_ID_AND_MASK);
// Configure Message RAM Sections
MCAN_msgRAMConfig(MCAN0_BASE, &msgRAMConfigParams);
// Configure Standard ID filter element
MCAN_addStdMsgIDFilter(MCAN0_BASE, 0U, &stdFiltelem);
// Configure Extended ID filter element
//MCAN_addExtMsgIDFilter(MCAN0_BASE, 0U, &extFiltelem);
// Enable external counter.
MCAN_extTSCounterEnable(MCAN0_BASE, 1U);
// Take MCAN out of the SW initialization mode
MCAN_setOpMode(MCAN0_BASE, MCAN_OPERATION_MODE_NORMAL);
while (MCAN_OPERATION_MODE_NORMAL != MCAN_getOpMode(MCAN0_BASE)) {
}
#endif
}
void drv_InitMCAN(void)
{
drv_ConfigMCANGpio();
SysCtl_allocateSharedPeripheral(SYSCTL_PALLOCATE_MCAN_A, 0x0U); //allocated to C28x
SysCtl_setMCANClk(SYSCTL_MCANCLK_DIV_5);
//Interrupt
Interrupt_register(INT_MCANSS0, &drv_irq_MCAN0);
Interrupt_enable(INT_MCANSS0);
drv_ConfigMCAN();
MCAN_enableIntr(MCAN0_BASE, MCAN_INTR_MASK_ALL, 1);
MCAN_enableIntr(MCAN0_BASE, MCAN_INTR_SRC_RES_ADDR_ACCESS | MCAN_INTR_SRC_TIMESTAMP_WRAPAROUND, 0);
MCAN_selectIntrLine(MCAN0_BASE, MCAN_INTR_SRC_RX_FIFO1_NEW_MSG | MCAN_INTR_SRC_TRANS_COMPLETE, MCAN_INTR_LINE_NUM_0);
MCAN_enableIntrLine(MCAN0_BASE, MCAN_INTR_LINE_NUM_0, 1U);
drv_mcan_tx_msg.id = ((uint32_t) (0x4)) << 18U; // STDID[28:18]
drv_mcan_tx_msg.rtr = 0U; // RTR = 0 (Data frame)
drv_mcan_tx_msg.xtd = 0U; // XTD = 0 (11-bit standard identifier)
drv_mcan_tx_msg.esi = 1U;
drv_mcan_tx_msg.dlc = 15U; // 64 bytes
drv_mcan_tx_msg.brs = 0U; // Bit-rate switching enabled
drv_mcan_tx_msg.fdf = 1U; // Frame transmitted in CAN FD format
drv_mcan_tx_msg.efc = 1U; // Store TX events
drv_mcan_tx_msg.mm = 0xAAU;
}
void drv_WriteMCAN(uint32_t id, uint16_t *data)
{
uint16_t i;
drv_mcan_tx_msg.id = ((uint32_t) (id)) << 18U; // STDID[28:18]
for (i = 0; i < 64; i++) {
drv_mcan_tx_msg.data[i] = data[i];
}
MCAN_writeMsgRam(MCAN0_BASE, MCAN_MEM_TYPE_FIFO, 0, (const MCAN_TxBufElement*) &drv_mcan_tx_msg);
MCAN_txBufTransIntrEnable(MCAN0_BASE, 0, 1U);
MCAN_txBufAddReq(MCAN0_BASE, 1);
}
__interrupt void drv_irq_MCAN0(void)
{
drv_irq_mcan0_status = MCAN_getIntrStatus(MCAN0_BASE);
#if 0
printf("\r\nintrStatus : 0x%lx\r\n", drv_irq_mcan0_status);
if (MCAN_getIntrStatus(MCAN0_BASE) & MCAN_INTR_SRC_RX_FIFO0_NEW_MSG) printf("Rx FIFO 0 New Message interrupt\r\n");
if (MCAN_getIntrStatus(MCAN0_BASE) & MCAN_INTR_SRC_RX_FIFO0_WATERMARK) printf("Rx FIFO 0 Watermark Reached interrupt\r\n");
if (MCAN_getIntrStatus(MCAN0_BASE) & MCAN_INTR_SRC_RX_FIFO0_FULL) printf("Rx FIFO 0 Full interrupt\r\n");
if (MCAN_getIntrStatus(MCAN0_BASE) & MCAN_INTR_SRC_RX_FIFO0_MSG_LOST) printf("Rx FIFO 0 Message Lost interrupt\r\n");
if (MCAN_getIntrStatus(MCAN0_BASE) & MCAN_INTR_SRC_RX_FIFO1_NEW_MSG) printf("Rx FIFO 1 New Message interrupt\r\n");
if (MCAN_getIntrStatus(MCAN0_BASE) & MCAN_INTR_SRC_RX_FIFO1_WATERMARK) printf("Rx FIFO 1 Watermark Reached interrupt\r\n");
if (MCAN_getIntrStatus(MCAN0_BASE) & MCAN_INTR_SRC_RX_FIFO1_FULL) printf("Rx FIFO 1 Full interrupt\r\n");
if (MCAN_getIntrStatus(MCAN0_BASE) & MCAN_INTR_SRC_RX_FIFO1_MSG_LOST) printf("Rx FIFO 1 Message Lost interrupt\r\n");
if (MCAN_getIntrStatus(MCAN0_BASE) & MCAN_INTR_SRC_HIGH_PRIO_MSG) printf("High Priority Message interrupt\r\n");
if (MCAN_getIntrStatus(MCAN0_BASE) & MCAN_INTR_SRC_TRANS_COMPLETE) printf("Transmission Completed interrupt\r\n");
if (MCAN_getIntrStatus(MCAN0_BASE) & MCAN_INTR_SRC_TRANS_CANCEL_FINISH) printf("Transmission Cancellation Finished interrupt\r\n");
if (MCAN_getIntrStatus(MCAN0_BASE) & MCAN_INTR_SRC_TX_FIFO_EMPTY) printf("Tx FIFO Empty interrupt\r\n");
if (MCAN_getIntrStatus(MCAN0_BASE) & MCAN_INTR_SRC_TX_EVT_FIFO_NEW_ENTRY) printf("Tx Event FIFO New Entry interrupt\r\n");
if (MCAN_getIntrStatus(MCAN0_BASE) & MCAN_INTR_SRC_TX_EVT_FIFO_WATERMARK) printf("Tx Event FIFO Watermark Reached interrupt\r\n");
if (MCAN_getIntrStatus(MCAN0_BASE) & MCAN_INTR_SRC_TX_EVT_FIFO_FULL) printf("Tx Event FIFO Full interrupt\r\n");
if (MCAN_getIntrStatus(MCAN0_BASE) & MCAN_INTR_SRC_TX_EVT_FIFO_ELEM_LOST) printf("Tx Event FIFO Element Lost interrupt\r\n");
if (MCAN_getIntrStatus(MCAN0_BASE) & MCAN_INTR_SRC_TIMESTAMP_WRAPAROUND) printf("Timestamp Wraparound interrupt\r\n");
if (MCAN_getIntrStatus(MCAN0_BASE) & MCAN_INTR_SRC_MSG_RAM_ACCESS_FAILURE) printf("Message RAM Access Failure interrupt\r\n");
if (MCAN_getIntrStatus(MCAN0_BASE) & MCAN_INTR_SRC_TIMEOUT) printf("Timeout Occurred interrupt\r\n");
if (MCAN_getIntrStatus(MCAN0_BASE) & MCAN_INTR_SRC_DEDICATED_RX_BUFF_MSG) printf("Message stored to Dedicated Rx Buffer interrupt\r\n");
if (MCAN_getIntrStatus(MCAN0_BASE) & MCAN_INTR_SRC_BIT_ERR_CORRECTED) printf("Bit Error Corrected interrupt\r\n");
if (MCAN_getIntrStatus(MCAN0_BASE) & MCAN_INTR_SRC_BIT_ERR_UNCORRECTED) printf("Bit Error Uncorrected interrupt\r\n");
if (MCAN_getIntrStatus(MCAN0_BASE) & MCAN_INTR_SRC_ERR_LOG_OVRFLW) printf("Error Logging Overflow interrupt\r\n");
if (MCAN_getIntrStatus(MCAN0_BASE) & MCAN_INTR_SRC_ERR_PASSIVE) printf("Error Passive interrupt\r\n");
if (MCAN_getIntrStatus(MCAN0_BASE) & MCAN_INTR_SRC_WARNING_STATUS) printf("Warning Status interrupt\r\n");
if (MCAN_getIntrStatus(MCAN0_BASE) & MCAN_INTR_SRC_BUS_OFF_STATUS) printf("Bus_Off Status interrupt\r\n");
if (MCAN_getIntrStatus(MCAN0_BASE) & MCAN_INTR_SRC_WATCHDOG) printf("Watchdog Interrupt interrupt\r\n");
if (MCAN_getIntrStatus(MCAN0_BASE) & MCAN_INTR_SRC_PROTOCOL_ERR_ARB) printf("Protocol Error in Arbitration Phase interrupt\r\n");
if (MCAN_getIntrStatus(MCAN0_BASE) & MCAN_INTR_SRC_PROTOCOL_ERR_DATA) printf("Protocol Error in Data Phase interrupt\r\n");
if (MCAN_getIntrStatus(MCAN0_BASE) & MCAN_INTR_SRC_RES_ADDR_ACCESS) printf("Access to Reserved Address interrupt\r\n");
#endif
if (drv_irq_mcan0_status & MCAN_INTR_SRC_DEDICATED_RX_BUFF_MSG || drv_irq_mcan0_status & MCAN_INTR_SRC_RX_FIFO0_NEW_MSG || drv_irq_mcan0_status & MCAN_INTR_SRC_RX_FIFO1_NEW_MSG) {
MCAN_readMsgRam(MCAN0_BASE, MCAN_MEM_TYPE_FIFO, 0U, MCAN_RX_FIFO_NUM_1, &drv_mcan_rx_msg);
drv_irq_mcan0_recv_cnt++;
}
HW_WR_FIELD32(MCAN0_BASE + MCAN_MCANSS_EOI, MCAN_MCANSS_EOI, 0x1U);
MCAN_clearIntrStatus(MCAN0_BASE, drv_irq_mcan0_status);
// Acknowledge this interrupt located in group 9
Interrupt_clearACKGroup(INTERRUPT_ACK_GROUP9);
}
#endif
最后、我需要的 CAN-FD 发送/接收行为如下所示。
接收用作中断。
通过轮询调用函数来进行传输。
为了便于参考、我还共享了我如上所述实现和使用的通用 CAN 代码。
/*
* drv_can.c
*
* Created on: Nov 4, 2021
* Author: JOO
*/
#include "f28x_project.h"
#include "driverlib.h"
#include "device.h"
#include <string.h>
#include "drv_gpio.h"
#include "drv_can.h"
#ifdef CPU1
#ifdef _FLASH
#pragma CODE_SECTION(drv_WriteCAN, ".TI.ramfunc");
#pragma CODE_SECTION(drv_irq_CANA, ".TI.ramfunc");
#endif
#endif
volatile DrvCanMsg drv_can_msg;
static void drv_ConfigCANGpio(void);
static void drv_InitCANMsgObj(void);
static void drv_ConfigCANGpio(void)
{
#ifndef _28377D
//CAN-A RX
drv_ConfigGPIO(GPIO_CORE_CPU1, 62, GPIO_DIR_MODE_OUT, GPIO_62_CANA_RX, GPIO_PIN_TYPE_STD, GPIO_QUAL_SYNC, 1);
//CAN-A TX
drv_ConfigGPIO(GPIO_CORE_CPU1, 63, GPIO_DIR_MODE_OUT, GPIO_63_CANA_TX, GPIO_PIN_TYPE_STD, GPIO_QUAL_SYNC, 1);
#endif
}
static void drv_InitCANMsgObj(void)
{
memset((void*)&drv_can_msg, NULL, sizeof(DrvCanMsg));
//TX Report 1
drv_can_msg.obj[0].obj_id = 1;
drv_can_msg.obj[0].can_id = 0x110;
drv_can_msg.obj[0].type = CAN_MSG_OBJ_TYPE_TX;
drv_can_msg.obj[0].flag = CAN_MSG_OBJ_NO_FLAGS;
drv_can_msg.obj[0].irq_cnt = 0;
//TX Report 2
drv_can_msg.obj[1].obj_id = 2;
drv_can_msg.obj[1].can_id = 0x120;
drv_can_msg.obj[1].type = CAN_MSG_OBJ_TYPE_TX;
drv_can_msg.obj[1].flag = CAN_MSG_OBJ_NO_FLAGS;
drv_can_msg.obj[1].irq_cnt = 0;
//RX Command
drv_can_msg.obj[2].obj_id = 3;
drv_can_msg.obj[2].can_id = 0x100;
drv_can_msg.obj[2].type = CAN_MSG_OBJ_TYPE_RX;
drv_can_msg.obj[2].flag = CAN_MSG_OBJ_RX_INT_ENABLE;
drv_can_msg.obj[2].irq_cnt = 0;
//RX Command
drv_can_msg.obj[3].obj_id = 4;
drv_can_msg.obj[3].can_id = 0x101;
drv_can_msg.obj[3].type = CAN_MSG_OBJ_TYPE_RX;
drv_can_msg.obj[3].flag = CAN_MSG_OBJ_RX_INT_ENABLE;
drv_can_msg.obj[3].irq_cnt = 0;
//RX Command
drv_can_msg.obj[4].obj_id = 5;
drv_can_msg.obj[4].can_id = 0x102;
drv_can_msg.obj[4].type = CAN_MSG_OBJ_TYPE_RX;
drv_can_msg.obj[4].flag = CAN_MSG_OBJ_RX_INT_ENABLE;
drv_can_msg.obj[4].irq_cnt = 0;
//RX Command
drv_can_msg.obj[5].obj_id = 6;
drv_can_msg.obj[5].can_id = 0x103;
drv_can_msg.obj[5].type = CAN_MSG_OBJ_TYPE_RX;
drv_can_msg.obj[5].flag = CAN_MSG_OBJ_RX_INT_ENABLE;
drv_can_msg.obj[5].irq_cnt = 0;
//RX Command
drv_can_msg.obj[6].obj_id = 7;
drv_can_msg.obj[6].can_id = 0x104;
drv_can_msg.obj[6].type = CAN_MSG_OBJ_TYPE_RX;
drv_can_msg.obj[6].flag = CAN_MSG_OBJ_RX_INT_ENABLE;
drv_can_msg.obj[6].irq_cnt = 0;
//RX Command
drv_can_msg.obj[7].obj_id = 8;
drv_can_msg.obj[7].can_id = 0x105;
drv_can_msg.obj[7].type = CAN_MSG_OBJ_TYPE_RX;
drv_can_msg.obj[7].flag = CAN_MSG_OBJ_RX_INT_ENABLE;
drv_can_msg.obj[7].irq_cnt = 0;
//RX Command
drv_can_msg.obj[8].obj_id = 9;
drv_can_msg.obj[8].can_id = 0x106;
drv_can_msg.obj[8].type = CAN_MSG_OBJ_TYPE_RX;
drv_can_msg.obj[8].flag = CAN_MSG_OBJ_RX_INT_ENABLE;
drv_can_msg.obj[8].irq_cnt = 0;
//RX Command
drv_can_msg.obj[9].obj_id = 10;
drv_can_msg.obj[9].can_id = 0x107;
drv_can_msg.obj[9].type = CAN_MSG_OBJ_TYPE_RX;
drv_can_msg.obj[9].flag = CAN_MSG_OBJ_RX_INT_ENABLE;
drv_can_msg.obj[9].irq_cnt = 0;
//RX Command
drv_can_msg.obj[10].obj_id = 11;
drv_can_msg.obj[10].can_id = 0x108;
drv_can_msg.obj[10].type = CAN_MSG_OBJ_TYPE_RX;
drv_can_msg.obj[10].flag = CAN_MSG_OBJ_RX_INT_ENABLE;
drv_can_msg.obj[10].irq_cnt = 0;
//RX Command
drv_can_msg.obj[11].obj_id = 12;
drv_can_msg.obj[11].can_id = 0x109;
drv_can_msg.obj[11].type = CAN_MSG_OBJ_TYPE_RX;
drv_can_msg.obj[11].flag = CAN_MSG_OBJ_RX_INT_ENABLE;
drv_can_msg.obj[11].irq_cnt = 0;
}
void drv_InitCAN(void)
{
Uint16 i;
#ifdef CPU1
drv_ConfigCANGpio();
SysCtl_selectCPUForPeripheral(SYSCTL_CPUSEL8_CAN, 1, SYSCTL_CPUSEL_CPU1);
#endif
#ifdef CPU1
drv_InitCANMsgObj();
CAN_initModule(USE_CAN);
CAN_setBitRate(USE_CAN, DEVICE_SYSCLK_FREQ, CAN_BITRATE, 20);
CAN_enableInterrupt(CANA_BASE, CAN_INT_IE0 | CAN_INT_ERROR | CAN_INT_STATUS);
Interrupt_register(INT_CANA0, &drv_irq_CANA);
Interrupt_enable(INT_CANA0);
CAN_enableGlobalInterrupt(USE_CAN, CAN_GLOBAL_INT_CANINT0);
for (i = 0; i < 32; i++) {
if(drv_can_msg.obj[i].obj_id != NULL) {
CAN_setupMessageObject(USE_CAN, //base
drv_can_msg.obj[i].obj_id, //obj ID
drv_can_msg.obj[i].can_id, //msg ID
CAN_MSG_FRAME_STD, //frame
drv_can_msg.obj[i].type, //msg type
0, //msg IDMask
drv_can_msg.obj[i].flag, //flag
8); //msg len
}
}
CAN_startModule(USE_CAN);
#endif
}
void drv_WriteCAN(uint32_t id, Uint16 *data, Uint16 size)
{
Uint16 i;
Uint16 data_temp[8] = { 0, };
for (i = 0; i < size; i++) {
data_temp[i] = data[i];
}
CAN_sendMessage(USE_CAN, id, 8, data_temp);
}
//
// CAN ISR - The interrupt service routine called when a CAN interrupt is
// triggered. It checks for the cause of the interrupt, and
// maintains a count of all messages that have been transmitted.
//
__interrupt void drv_irq_CANA(void)
{
uint32_t status;
Uint16 i;
// Read the CAN interrupt status to find the cause of the interrupt
status = CAN_getInterruptCause(USE_CAN);
// 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 = CAN_getStatus(USE_CAN);
// Check to see if an error occurred.
if (((status & ~(CAN_STATUS_TXOK | CAN_STATUS_RXOK)) != 7) && ((status & ~(CAN_STATUS_TXOK | CAN_STATUS_RXOK)) != 0)) {
// Set a flag to indicate some errors may have occurred.
drv_can_msg.error_cnt++;
}
} else {
for (i = 0; i < 32 && drv_can_msg.obj[i].can_id != NULL; i++) {
if (status == drv_can_msg.obj[i].obj_id) {
drv_can_msg.obj[i].irq_cnt++;
CAN_readMessage(USE_CAN, drv_can_msg.obj[i].obj_id, (uint16_t*) &drv_can_msg.obj[i].data);
CAN_clearInterruptStatus(USE_CAN, drv_can_msg.obj[i].obj_id);
break;
}
}
}
// Clear the global interrupt flag for the CAN interrupt line
CAN_clearGlobalInterruptStatus(USE_CAN, CAN_GLOBAL_INT_CANINT0);
// Acknowledge this interrupt located in group 9
Interrupt_clearACKGroup(INTERRUPT_ACK_GROUP9);
}
如上所述、我还想制造 CAN-FD。
我想解决中断花费2次的原因、
在我的系统中、主中断是一个计时器、运行频率为20kHz。
对于 UI 连接、对于通信数据加载测试、以频繁的周期速率发送数据、并尝试匹配接收到的 IRQ 数量。
CAN 和 CAN-FD 的接收是正常的。 无数据丢失。
但是、主计时器中断在 CAN-FD 中断开。
不能中断主定时器中断。
的示例


进行比较


这两个寄存器都在 CPU1中运行、黄色是用于检查定时器1运行情况的信号。