你好,我在配置280039C芯片的MCAN的过滤器时,发现第一个过滤器的sfid2无法正常工作,请问是什么原因呢?具体配置如下:
ConfigParams.filterConfig.anfs = 2U;
MCAN_config(MCANA_DRIVER_BASE, &ConfigParams );
StdFilterElement.sfid1 = 0x009U;
StdFilterElement.sfid2 = 0x0ADU;
StdFilterElement.sfec = 1U;
StdFilterElement.sft = 1U;
MCAN_addStdMsgIDFilter(MCANA_DRIVER_BASE, 0U, &StdFilterElement);
配置如上,sfid1正常工作,但是sfid2无法工作,请问是什么原因呢
SFID2确定Rx缓冲元素(在64个可能的元素中),其中将存储接受的帧(由相应的过滤器元素确定)。请参考C2000软件示例“mcan_ex10_receive_multiple_buffers”以了解其实现。
在上述例程中,
1.0x1属于过滤ID么?如果接收ID有0x1会怎么样?
2.为什么StdFilterElement.sfec = 1U;这种模式的两个ID不可以用?
3.例程没有配置filterConfig.anfs ,不是所有ID都会接受么?
ANFS=2表示不匹配的消息被拒绝。
StdFilterElement.sfec=1U;-->匹配的消息存储在RX FIFO0中
StdFilterElement.sft=1U;-->使用两个ID过滤器(从SFI1到SFID2)来过滤传入消息。
因此,根据您的配置,ID为0x09到0xAD的消息将存储在FIFO0中。所有其他不匹配的消息都将被拒绝。
通常,过滤设置位于MCAN消息RAM的开头。但它也可以位于MCAN配置定义的其他位置。
例如:
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: Standard ID.
过滤器配置位于mcan_ex4_receive示例的MCANConfig()中:
//#############################################################################
//
// 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
//!
//
//#############################################################################
//
//
// $Copyright:
// Copyright (C) 2024 Texas Instruments Incorporated - http://www.ti.com/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
//
// Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
//
// Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the
// distribution.
//
// Neither the name of Texas Instruments Incorporated nor the names of
// its contributors may be used to endorse or promote products derived
// from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// $
//#############################################################################
//
// Include Files
//
#include "driverlib.h"
#include "device.h"
#include "inc/stw_types.h"
#include "inc/stw_dataTypes.h"
#include <string.h>
//
// Defines.
//
#define NUM_OF_MSG (1U)
#define MCAN_STD_ID_FILTER_NUM (1U)
#define MCAN_EXT_ID_FILTER_NUM (1U)
#define MCAN_FIFO_0_NUM (0U)
#define MCAN_FIFO_0_ELEM_SIZE (MCAN_ELEM_SIZE_64BYTES)
#define MCAN_FIFO_1_NUM (0U)
#define MCAN_FIFO_1_ELEM_SIZE (MCAN_ELEM_SIZE_64BYTES)
#define MCAN_RX_BUFF_NUM (10U)
#define MCAN_RX_BUFF_ELEM_SIZE (MCAN_ELEM_SIZE_64BYTES)
#define MCAN_TX_BUFF_SIZE (0U)
#define MCAN_TX_FQ_SIZE (0U)
#define MCAN_TX_BUFF_ELEM_SIZE (MCAN_ELEM_SIZE_64BYTES)
#define MCAN_TX_EVENT_SIZE (0U)
//
// Defining Starting Addresses for Message RAM Sections,
// (Calculated from Macros based on User defined configuration above)
//
#define MCAN_STD_ID_FILT_START_ADDR (0x0U)
#define MCAN_EXT_ID_FILT_START_ADDR (MCAN_STD_ID_FILT_START_ADDR + ((MCAN_STD_ID_FILTER_NUM * MCANSS_STD_ID_FILTER_SIZE_WORDS * 4U)))
#define MCAN_FIFO_0_START_ADDR (MCAN_EXT_ID_FILT_START_ADDR + ((MCAN_EXT_ID_FILTER_NUM * MCANSS_EXT_ID_FILTER_SIZE_WORDS * 4U)))
#define MCAN_FIFO_1_START_ADDR (MCAN_FIFO_0_START_ADDR + (MCAN_getMsgObjSize(MCAN_FIFO_0_ELEM_SIZE) * 4U * MCAN_FIFO_0_NUM))
#define MCAN_RX_BUFF_START_ADDR (MCAN_FIFO_1_START_ADDR + (MCAN_getMsgObjSize(MCAN_FIFO_1_ELEM_SIZE) * 4U * MCAN_FIFO_1_NUM))
#define MCAN_TX_BUFF_START_ADDR (MCAN_RX_BUFF_START_ADDR + (MCAN_getMsgObjSize(MCAN_RX_BUFF_ELEM_SIZE) * 4U * MCAN_RX_BUFF_NUM))
#define MCAN_TX_EVENT_START_ADDR (MCAN_TX_BUFF_START_ADDR + (MCAN_getMsgObjSize(MCAN_TX_BUFF_ELEM_SIZE) * 4U * (MCAN_TX_BUFF_SIZE + MCAN_TX_FQ_SIZE)))
//
// Global Variables.
//
int32_t error = 0;
MCAN_RxBufElement rxMsg[NUM_OF_MSG], rxMsg1;
int32_t loopCnt = 0U;
//
// Function Prototype.
//
static void MCANConfig(void);
static void MCANIntrConfig(void);
__interrupt void MCANIntr1ISR(void);
void main()
{
int i = 0, count=0;
volatile uint32_t mode = 0U;
uint32_t dataBytes = 64;
//
// 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_3); //40MHz = 120MHz/3
//
// ISR Configuration.
//
MCANIntrConfig();
//
// Configure GPIO pins for MCANTX/MCANRX operation
//
GPIO_setPinConfig(DEVICE_GPIO_CFG_MCANRXA);
GPIO_setPinConfig(DEVICE_GPIO_CFG_MCANTXA);
// GPIO_setPinConfig(GPIO_5_MCAN_RX); //QJ
// GPIO_setPinConfig(GPIO_4_MCAN_TX); //QJ
//
// Initialize message to receive
//
rxMsg[loopCnt].id = 0U;
rxMsg[loopCnt].rtr = 0U;
rxMsg[loopCnt].xtd = 1U; //QJ
rxMsg[loopCnt].esi = 0U;
rxMsg[loopCnt].rxts = 0U; // Rx Timestamp
rxMsg[loopCnt].dlc = 0U;
rxMsg[loopCnt].brs = 0U;
rxMsg[loopCnt].fdf = 0U;
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(MCANA_DRIVER_BASE, MCAN_INTR_MASK_ALL, 1U);
MCAN_enableIntr(MCANA_DRIVER_BASE, MCAN_IR_DRX_MASK, 1U);
//
// Select Interrupt Line.
//
MCAN_selectIntrLine(MCANA_DRIVER_BASE, MCAN_INTR_MASK_ALL, MCAN_INTR_LINE_NUM_1);
//
// Enable Interrupt Line.
//
MCAN_enableIntrLine(MCANA_DRIVER_BASE, MCAN_INTR_LINE_NUM_1, 1U);
while(1)
{
//
// Adding delay of 1 second
//
DEVICE_DELAY_US(1000000);
if(rxMsg[loopCnt].data[0] == 1)
count = 1; //GPIO_writePin(myGPIO0, 1);
else
count = 2; //GPIO_writePin(myGPIO0, 0);
//
// Message Handling Code goes here
//
}
//
// Stop Application.
//
asm(" ESTOP0");
}
static void MCANConfig(void)
{
MCAN_InitParams initParams;
MCAN_MsgRAMConfigParams msgRAMConfigParams;
MCAN_StdMsgIDFilterElement stdFiltelem;
MCAN_ExtMsgIDFilterElement extFiltelem; //QJ
MCAN_BitTimingParams bitTimes;
//
// Initializing all structs to zero to prevent stray values
//
memset(&initParams, 0, sizeof(initParams));
memset(&msgRAMConfigParams, 0, sizeof(msgRAMConfigParams));
memset(&stdFiltelem, 0, sizeof(stdFiltelem));
memset(&extFiltelem, 0, sizeof(extFiltelem)); //QJ
memset(&bitTimes, 0, sizeof(bitTimes));
//
// Configure MCAN initialization parameters
//
initParams.fdMode = 0x1U; // FD operation enabled.
initParams.brsEnable = 0x1U; // Bit rate switching enabled
//
// Transmitter Delay Compensation parameters.
//
// initParams.tdcConfig.tdcf = 0xAU;
// initParams.tdcConfig.tdco = 0x6U;
initParams.emulationEnable = 0x1U; //enable debug suspend, by QJ
// initParams.tdcEnable = 0x1U; //Transmitter Delay Compensation enabled
//
// 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;
// Standard ID Filter List Start Address.
msgRAMConfigParams.lse = MCAN_EXT_ID_FILTER_NUM;
// List Size: Standard ID.
msgRAMConfigParams.rxBufStartAddr = MCAN_RX_BUFF_START_ADDR;
// Rx Buffer Start Address.
msgRAMConfigParams.rxBufElemSize = MCAN_RX_BUFF_ELEM_SIZE;
// Rx Buffer Element Size.
//
// Initialize Rx Buffer Configuration parameters.
//
stdFiltelem.sfid2 = 0x0U; // Standard Filter ID 2.
// Configuring received frame to be stored in buffer element 0
stdFiltelem.sfid1 = 0x4U; // Standard Filter ID 1.
// Confifuring frames with msg ID = 0x4U to be accepted by filter element
stdFiltelem.sfec = 0x7U; // Store into Rx Buffer
// configuration of SFT[1:0] ignored
extFiltelem.efid2 = 0x0U;
extFiltelem.efid1 = 0xA5A5U;
extFiltelem.efec = 0x7U;
//
// Initialize bit timings.
//
bitTimes.nomRatePrescalar = 0x3U; // Nominal Baud Rate Pre-scaler; 40/4=10MHz, 500kbps
bitTimes.nomTimeSeg1 = 14U; // Nominal Time segment before SP
bitTimes.nomTimeSeg2 = 3U; // Nominal Time segment after SP
bitTimes.nomSynchJumpWidth = 3U; // Nominal SJW
bitTimes.dataRatePrescalar = 0x0U; // Data Baud Rate Pre-scaler; 40/1=40MHz, 2mbps
bitTimes.dataTimeSeg1 = 14U; // Data Time segment before SP
bitTimes.dataTimeSeg2 = 3U; // Data Time segment after SP
bitTimes.dataSynchJumpWidth = 3U; // Data SJW
//
// Wait for memory initialization to happen.
//
while(FALSE == MCAN_isMemInitDone(MCANA_DRIVER_BASE))
{
}
//
// Put MCAN in SW initialization mode.
//
MCAN_setOpMode(MCANA_DRIVER_BASE, MCAN_OPERATION_MODE_SW_INIT);
//
// Wait till MCAN is not initialized.
//
while (MCAN_OPERATION_MODE_SW_INIT != MCAN_getOpMode(MCANA_DRIVER_BASE))
{}
//
// Initialize MCAN module.
//
MCAN_init(MCANA_DRIVER_BASE, &initParams);
//
// Configure Bit timings.
//
MCAN_setBitTime(MCANA_DRIVER_BASE, &bitTimes);
//
// Configure Message RAM Sections
//
MCAN_msgRAMConfig(MCANA_DRIVER_BASE, &msgRAMConfigParams);
//
// Configure Standard ID filter element
//
MCAN_addStdMsgIDFilter(MCANA_DRIVER_BASE, 1U, &stdFiltelem); //RX buffer 1
//
// Configure Extended ID filter element
//
MCAN_addExtMsgIDFilter(MCANA_DRIVER_BASE, 0U, &extFiltelem); //RX buffer 0
//
// Take MCAN out of the SW initialization mode
//
MCAN_setOpMode(MCANA_DRIVER_BASE, MCAN_OPERATION_MODE_NORMAL);
while (MCAN_OPERATION_MODE_NORMAL != MCAN_getOpMode(MCANA_DRIVER_BASE))
{
}
}
//
// This function will configure X-BAR for MCAN interrupts.
//
static void MCANIntrConfig(void)
{
Interrupt_initModule();
Interrupt_initVectorTable();
Interrupt_register(INT_MCANA_1, &MCANIntr1ISR);
Interrupt_enable(INT_MCANA_1);
Interrupt_enableGlobal();
}
//
// This is Interrupt Service Routine for MCAN interrupt 1.
//
__interrupt void MCANIntr1ISR(void)
{
uint32_t intrStatus;
MCAN_RxNewDataStatus newData;
intrStatus = MCAN_getIntrStatus(MCANA_DRIVER_BASE);
//
// Clear the interrupt Status.
//
MCAN_clearIntrStatus(MCANA_DRIVER_BASE, intrStatus);
//
// Clearing the interrupt lineNum
//
MCAN_clearInterrupt(MCANA_DRIVER_BASE, 0x2);
//
// Check to see if the interrupt is caused by a message being
// received in dedicated RX Buffers
//
if((MCAN_INTR_SRC_DEDICATED_RX_BUFF_MSG & intrStatus) == MCAN_INTR_SRC_DEDICATED_RX_BUFF_MSG)
{
//
// Read the NewData registers
//
MCAN_getNewDataStatus(MCANA_DRIVER_BASE, &newData);
// If message is received in buffer element 0
if((newData.statusLow & (1UL << 0U)) != 0)
{
MCAN_readMsgRam(MCANA_DRIVER_BASE, MCAN_MEM_TYPE_BUF, 0U,
0, &rxMsg1);
rxMsg[loopCnt] = rxMsg1;
}
//
// Clearing the NewData registers
//
MCAN_clearNewDataStatus(MCANA_DRIVER_BASE, &newData);
}
else
{
error++;
//
// Interrupt handling for other interrupt sources goes here
//
}
//
// Acknowledge this interrupt located in group 9
//
Interrupt_clearACKGroup(INTERRUPT_ACK_GROUP9);
}
该示例已经过测试。它工作起来没有任何问题。
你调用下面的函数了吗?
//
// Configure Standard ID filter element
//
MCAN_addStdMsgIDFilter(MCANA_DRIVER_BASE, 1U, &stdFiltelem); //RX buffer 1
//
// Configure Extended ID filter element
//
MCAN_addExtMsgIDFilter(MCANA_DRIVER_BASE, 0U, &extFiltelem); //RX buffer 0