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.

[参考译文] TMS320F28388D:如何在 MCAN (CAN-FD)中连续 RX 中断?

Guru**** 2601915 points


请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

https://e2e.ti.com/support/microcontrollers/c2000-microcontrollers-group/c2000/f/c2000-microcontrollers-forum/1061518/tms320f28388d-how-can-i-continuous-rx-interrupt-in-mcan-can-fd

器件型号:TMS320F28388D

你(们)好

我正在使用28388D 进行开发。

CAN-FD 是一种必要的功能、正在实施中。

TX 正在轮询、RX 是中断。

因此、我在 C2000中搜索了 V304和 V400的相关示例、并尝试运行它们。

在 V304的 mCAN_ex_2_external_loopback _receive 示例中、确认中断仅在接收到数据时执行一次。

所提供的示例确实只有一个时间接收中断吗?

我有什么问题吗?

并且、当一个错误中断发生时、除了清除它之外、还有其他操作吗?

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    有人在这里吗?  

    https://e2e.ti.com/support/microcontrollers/c2000-microcontrollers-group/c2000/f/c2000-microcontrollers-forum/1012170/tmdscncd28388d-can-fd-rx-interrupt?tisearch=e2e-sitesearch&keymatch=can-fd

    我看到了几个问题和解答、包括上面的链接、但它仍然没有解决。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    我解决了这个问题。

    问题

    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);
    }

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好!

    这一问题已转交给我们的主题专家。

    此致、

    Praveen

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    谢谢、

    这是我的最后一个 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运行情况的信号。