尊敬的专家:
我目前正在尝试使用28.0039万C构建CAN FD的功能。
我的想法是使用RF0N (Rx FIFO 0 New Message)触发中断,读取中断1中的RAM FIFO数据。
问题在于,发出外部CAFD命令时,接收中断成功,但中断只执行一次,并且不能继续接收其它CAFD命令。
由于可以接收第一个中断的数据,因此可以确认我的硬件和中断设置没有问题。
问题可能出在某些固件设置或缺少某些项,我已经整理了一些基本设置,您能帮我确定我的设置是否有任何问题吗?
总体方案 如下
//#############################################################################
//
// FILE: mcan_ex4_receive.c
//
// TITLE: MCAN receive using Rx Buffer
//
//! \addtogroup driver_example_c28x_list
//! <h1> MCAN receive using Rx Buffer </h1>
//!
//! This example demonstrates the MCAN receive function. Communication is done
//! between two CAN nodes. The transmitting node could be another MCU or a
//! CAN bus analysis tool capable of transmitting CAN FD frames. The transmit
//! and receive pins of the MCAN module should be connected to a CAN
//! transceiver. Nominal Bit Rate of 500 kbps & Data bit rate of 1 Mbps is used
//!
//! Only Standard frame with message ID 0x4 is received.
//!
//! If another C2000 MCU is used as the transmitter, mcan_ex3_transmit.c can be
//! run on it for the transmit function.
//!
//! \b Hardware \b Required \n
//! - A C2000 board with CAN transceiver
//!
//! \b External \b Connections \n
//! Both nodes should communicate through CAN FD capable transceivers.
//!
//! - MCAN is on DEVICE_GPIO_PIN_CANRXA (MCANRXA)
//! - and DEVICE_GPIO_PIN_CANTXA (MCANTXA)
//!
//! \b Watch \b Variables \n
//! - rxMsg
//!
//
//
// Include Files
//
#include "driverlib.h"
#include "device.h"
#include "inc/stw_types.h"
#include "inc/stw_dataTypes.h"
#include <stdint.h>
#include "inc/hw_types_mcan.h"
#include "mcan.h"
#include "debug.h"
#include "interrupt.h"
//
// Defines.
//
#define NUM_OF_MSG (1U)
#define MCAN_STD_ID_FILT_START_ADDR (0x0U)
#define MCAN_STD_ID_FILTER_NUM (1U)
#define MCAN_EXT_ID_FILT_START_ADDR (0x14U)
#define MCAN_EXT_ID_FILTER_NUM (1U)
#define MCAN_TX_BUFF_START_ADDR (0x80U)
#define MCAN_TX_BUFF_SIZE (10U)
#define MCAN_FIFO_1_START_ADDR (0xc0U)
#define MCAN_FIFO_1_NUM (10U)
#define MCAN_TX_EVENT_START_ADDR (0x100U)
#define MCAN_TX_EVENT_SIZE (10U)
#define MCAN_EXT_ID_AND_MASK (0x1FFFFFFFU)
#define MCAN_RX_BUFF_START_ADDR (948U)
#define MCAN_FIFO_0_START_ADDR (548U)
#define MCAN_FIFO_0_NUM (5U)
#define MCAN_MSG_INT (0x81200)
#define MCAN0_BASE MCAN_MSG_RAM_BASE
#define INT_MCANSS0 INT_MCAN_0
#define INT_MCANSS1 INT_MCAN_1
//
// Global Variables.
//
volatile uint32_t isrIntr0Flag = 1U;
volatile uint32_t isrIntr1Flag = 1U;
volatile uint16_t monEn = 0x0;
volatile unsigned long msgCount = 0;
int32_t error = 0;
MCAN_RxBufElement rxMsg[NUM_OF_MSG], rxMsg1;
int32_t loopCnt = 0U;
int16_t UWSeanflag=0;
int16_t UWdataclear=0;
int16_t int0,int1;
//
// Function Prototype.
//
static void MCANConfig(void);
static void MCANIntrConfig(void);
__interrupt void MCANIntr0ISR(void);
__interrupt void MCANIntr1ISR(void);
void main()
{
int i = 0;
volatile uint32_t mode = 0U;
uint32_t dataBytes = 64;
MCAN_RxNewDataStatus newData;
newData.statusLow = 0;
//
// Initialize device clock and peripherals
//
Device_init();
//
// Initialize GPIO and unlock the GPIO configuration registers
//
Device_initGPIO();
//
// Configure the divisor for the MCAN bit-clock
//
SysCtl_setMCANClk(SYSCTL_MCANCLK_DIV_2);
MCANIntrConfig();
//
// Configure GPIO pins for MCANTX/MCANRX operation
//
GPIO_setPinConfig(DEVICE_GPIO_CFG_MCANRXA);
GPIO_setPinConfig(DEVICE_GPIO_CFG_MCANTXA);
//
// Initialize message to receive
//
rxMsg[loopCnt].id = 0U;
rxMsg[loopCnt].rtr = 0U;
rxMsg[loopCnt].xtd = 1U;
rxMsg[loopCnt].esi = 0U;
rxMsg[loopCnt].rxts = 0U; // Rx Timestamp
rxMsg[loopCnt].dlc = 0U;
rxMsg[loopCnt].brs = 1U;
rxMsg[loopCnt].fdf = 1U;
rxMsg[loopCnt].fidx = 0U; // Filter Index
// (of matching Rx acceptance filter element)
rxMsg[loopCnt].anmf = 0U; // Accepted Non-matching Frame
for(i = 0; i < dataBytes; i++) // Initialize receive buffer to 0
{
rxMsg[loopCnt].data[i] = 0;
}
//
// Configure the MCAN Module.
//
MCANConfig();
//
// Enable Interrupts.
//
MCAN_enableIntr(MCAN0_BASE, MCAN_INTR_MASK_ALL, 1U);
//MCAN_enableIntr(MCAN0_BASE, MCAN_INTR_SRC_RES_ADDR_ACCESS|
//MCAN_INTR_SRC_TIMESTAMP_WRAPAROUND,0);
//
// Select Interrupt Line.
//
MCAN_selectIntrLine(MCAN0_BASE, MCAN_INTR_MASK_ALL, MCAN_INTR_LINE_NUM_1);
//
// Enable Interrupt Line.
//
MCAN_enableIntrLine(MCAN0_BASE, MCAN_INTR_LINE_NUM_1, 1U);
MCAN_getNewDataStatus(MCAN0_BASE, &newData);
}
static void MCANConfig(void)
{
MCAN_InitParams initParams;
MCAN_MsgRAMConfigParams msgRAMConfigParams;
MCAN_ExtMsgIDFilterElement extFiltelem;
MCAN_BitTimingParams bitTimes;
//
// Configure MCAN initialization parameters
//
initParams.fdMode = 0x1U; // FD operation enabled.
initParams.brsEnable = 0x1U; // Bit rate switching enabled
//
// Initialize Message RAM Sections Configuration Parameters
//
msgRAMConfigParams.flesa = MCAN_STD_ID_FILT_START_ADDR;
msgRAMConfigParams.lse = MCAN_STD_ID_FILTER_NUM;
msgRAMConfigParams.flesa = MCAN_EXT_ID_FILT_START_ADDR;
msgRAMConfigParams.lse = MCAN_EXT_ID_FILTER_NUM;
msgRAMConfigParams.txStartAddr = MCAN_TX_BUFF_START_ADDR;
msgRAMConfigParams.txBufNum = MCAN_TX_BUFF_SIZE;
msgRAMConfigParams.txFIFOSize = 0U;
msgRAMConfigParams.txBufMode = 0U;
msgRAMConfigParams.txBufElemSize = MCAN_ELEM_SIZE_64BYTES;
msgRAMConfigParams.txEventFIFOStartAddr = MCAN_TX_EVENT_START_ADDR;
msgRAMConfigParams.txEventFIFOSize = MCAN_TX_BUFF_SIZE;
msgRAMConfigParams.txEventFIFOWaterMark = 3U;
msgRAMConfigParams.rxFIFO0startAddr = MCAN_FIFO_0_START_ADDR;
msgRAMConfigParams.rxFIFO0size = MCAN_FIFO_0_NUM;
msgRAMConfigParams.rxFIFO0waterMark = 3U;
msgRAMConfigParams.rxFIFO0OpMode = 0U;
msgRAMConfigParams.rxFIFO1startAddr = MCAN_FIFO_1_START_ADDR;
msgRAMConfigParams.rxFIFO1size = MCAN_FIFO_1_NUM;
msgRAMConfigParams.rxFIFO1waterMark = 3U;
msgRAMConfigParams.rxFIFO1OpMode = 0U;
msgRAMConfigParams.rxBufStartAddr = MCAN_RX_BUFF_START_ADDR;
msgRAMConfigParams.rxBufElemSize = MCAN_ELEM_SIZE_64BYTES;
msgRAMConfigParams.rxFIFO0ElemSize = MCAN_ELEM_SIZE_64BYTES;
msgRAMConfigParams.rxFIFO1ElemSize = MCAN_ELEM_SIZE_64BYTES;
extFiltelem.efid1 = 0x18EFB324U;
extFiltelem.eft = 0x1U;
extFiltelem.efec = 0x1U;
//
// Initialize bit timings.
//
bitTimes.nomRatePrescalar = 0x7U; // Nominal Baud Rate Pre-scaler
bitTimes.nomTimeSeg1 = 0x9U; // Nominal Time segment before SP
bitTimes.nomTimeSeg2 = 0x3U; // Nominal Time segment after SP
bitTimes.nomSynchJumpWidth = 0x4U; // Nominal SJW
bitTimes.dataRatePrescalar = 0x0U; // Data Baud Rate Pre-scaler
bitTimes.dataTimeSeg1 = 0x9U; // Data Time segment before SP
bitTimes.dataTimeSeg2 = 0x0U; // Data Time segment after SP
bitTimes.dataSynchJumpWidth = 0x4U; // Data SJW
//
// 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 Bit timings.
//
MCAN_setBitTime(MCAN0_BASE, &bitTimes);
//
// Configure Message RAM Sections
//
MCAN_msgRAMConfig(MCAN0_BASE, &msgRAMConfigParams);
//
// Configure Standard ID filter element
//
//MCAN_addStdMsgIDFilter(MCAN0_BASE, 0U, &stdFiltelem);
MCAN_addExtMsgIDFilter(MCAN0_BASE, 0U, &extFiltelem);
//
// 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))
{
}
}
static void MCANIntrConfig(void)
{
Interrupt_initModule();
Interrupt_initVectorTable();
Interrupt_register(INT_MCANSS0,&MCANIntr0ISR);
Interrupt_enable(INT_MCANSS0);
Interrupt_register(INT_MCANSS1,&MCANIntr1ISR);
Interrupt_enable(INT_MCANSS1);
Interrupt_enableMaster();
}
//
// This is Interrupt Service Routine for MCAN interrupt 0.
//
__interrupt void MCANIntr0ISR(void)
{
uint32_t intrStatus;
intrStatus = MCAN_getIntrStatus(MCAN0_BASE);
int0++;
if (MCAN_MSG_INT != intrStatus)
{
error++;
}
//
// Clear the interrupt Status.
//
MCAN_clearIntrStatus(MCAN0_BASE, intrStatus);
//
// Update the flag value.
//
isrIntr0Flag = 0U;
//
// Acknowledge this interrupt located in group 9
//
Interrupt_clearACKGroup(INTERRUPT_ACK_GROUP9);
}
//
// This is Interrupt Service Routine for MCAN interrupt 1.
//
__interrupt void MCANIntr1ISR(void)
{
uint32_t intrStatus;
int1++;
MCAN_RxNewDataStatus newData;
intrStatus = MCAN_getIntrStatus(MCAN0_BASE);
if (MCAN_MSG_INT != intrStatus)
{
error++;
}
MCAN_getNewDataStatus(MCAN0_BASE, &newData);
MCAN_readMsgRam(MCAN0_BASE, MCAN_MEM_TYPE_FIFO, 0, MCAN_RX_FIFO_NUM_0, &rxMsg1);
rxMsg[loopCnt] = rxMsg1;
MCAN_writeRxFIFOAck(MCAN0_BASE, MCAN_RX_FIFO_NUM_0, 0);
MCAN_clearNewDataStatus(MCAN0_BASE, &newData);
//
// Clear the interrupt Status.
//
HW_WR_FIELD32(MCAN0_BASE + MCAN_MCANSS_EOI, MCAN_MCANSS_EOI, 0x1U);
MCAN_clearIntrStatus(MCAN0_BASE, intrStatus);
//
// Update the flag value.
//
isrIntr1Flag = 0U;
//
// Acknowledge this interrupt located in group 9
//
Interrupt_clearACKGroup(INTERRUPT_ACK_GROUP9);
}
第150行:设置 启用中断源
行156:选择Interrupt MCAN interrupt 1 (中断MCAN中断1)。
行161: 启用中断MCAN中断1。
第207行 , 第208行和 第209行: 设置ID过滤器并将信息存储在FIFO中。
第327行:读取 从信息RAM收到的信息。
第328行: 将信息从RAM复制到自定义阵列。
行329: 写入Rx FIFO确认。
行335:清除中断状态。
感谢您的帮助!!