CAN - aman396271/Flagchip_Study GitHub Wiki

1、概览

image

初始化步骤

image

发送步骤

image

仲裁过程

触发仲裁

image

仲裁标准

1.低编号者优先(CTRL1[LBUF]) image 优先级失能时仲裁值组成 image

2.高优先级者优先(MCR[LPRIOEN]) image 优先级使能时仲裁值组成 image PRIO值越小,优先级越高 image

仲裁完成

image

接收步骤

详见RM 要注意的点:要通过读取IFLAG来查看接收情况,而不是邮箱的CODE字段,也不要在读取后强制写邮箱的C/S字段 image 当邮箱接收到一个帧后,会置位IFLAG1[BIT5],而不会产生DMA请求

掩码

当CAN控制器接收到一个报文时,它会执行以下步骤来决定是否接收该报文:
逐位比较: 接收到的报文ID的每一位都会与配置的滤波器ID的相应位进行比较。
掩码作用: 只有当掩码位为“1”时,比较结果才会被考虑。如果掩码位为“0”,则无论报文ID的该位是什么,都视为匹配。
匹配判断: 如果所有掩码位为“1”的ID位都与滤波器匹配,则该报文被视为通过滤波器,并被接收到CAN控制器的接收缓冲区中进行进一步处理。否则,报文被丢弃。

MB

根据RM中MB所在RAM的描述,其实质为映射在0x80-0x280(0x80+3244)的一块RAM,每个MB的大小为16字节。 image

image FC4150系列有6个FlexCAN,每个CAN有32个MB The FLEXCAN module is a CAN protocol engine with a very flexible mailbox system for transmitting and receiving CAN frames.The mailbox system is composed of a set of message buffers (MB) that store configuration and control data, time stamp,message ID, and data.Mailbox即由MB组成,其内容有配置、控制字、时间戳、信号ID、数据

FIFO

在RM中对于Legacy FIFO的描述为The Legacy Rx FIFO is 6-message deep. The memory region is occupied by the Legacy Rx FIFO structure (both message buffers and Legacy Rx FIFO engine). The CPU can read the received messages sequentially, in the order they were received,by repeatedly reading a message buffer structure at the output of the Legacy Rx FIFO可见FIFO其深度为6-message image FIFO最多支持32个过滤,要注意的是,在配置FLEXCAN_FifoFilterType aFifoList[n]时,n的数目必须为8的倍数(SDK中有在ErrorReport中写)。 三种FIFO过滤机制如下表 image FIFO过滤机制的调节通过MCR[IDAM] image

可通过寄存器CTRL2[RFFN]调整FIFO的过滤器个数的调整 image FIFO掩码寄存器 image

MB与FIFO的理解

MB是CAN的最小收发单元,可通过配置ID即掩码接收所需的内容,一般配置为过滤单个ID或一组相关性较高的ID(如:ID=0x111,IdMask=0x110,接收0x110-0x11F的帧)

FIFO是MB组成的接收缓冲空间(在FC4150中是MB0-MB5),占用MB的同时,能够实现至多32个(必须为8的倍数)的独立ID过滤,也可以实现MB具备的过滤方式,并且比单个MB更能应对高密度数据接收

FIFO

Todo:55.6.7

2、CAN收发的代码实现

时钟配置

PCC_DIVH/CoreClik image

引脚配置

对于Demo板的收发器TJA1042,其CAN0配置为:

	/****************** CAN *******************/
	/* PortE 2, CAN0_STB */
	g_tPortHandle.eInstance = PORT_E;
	tInitStruct.u32PortPins = PORT_PIN_2;
	tInitStruct.uPortPinMux.u32PortPinMode = PORT_GPIO_MODE;
	tInitStruct.ePortGpioDir = PORT_GPIO_OUT;
	tInitStruct.ePortGpioLevel = PORT_GPIO_LOW;
	PORT_InitPins(&g_tPortHandle,&tInitStruct);

    /* Port A28: MUX = ALT5, CAN0_RX */
	g_tPortHandle.eInstance = PORT_A;
    tInitStruct.u32PortPins = PORT_PIN_28;
    tInitStruct.uPortPinMux.u32PortPinMode = PORTA_28_FLEXCAN0_RX;
    tInitStruct.ePortGpioDir = PORT_GPIO_IN;
    tInitStruct.bPullEn = false;
    tInitStruct.ePullSel = PORT_PULL_UP;
    PORT_InitPins(&g_tPortHandle,&tInitStruct);

    /* Port A27: MUX = ALT5, CAN0_TX */
	g_tPortHandle.eInstance = PORT_A;
    tInitStruct.u32PortPins = PORT_PIN_27;
    tInitStruct.uPortPinMux.u32PortPinMode = PORTA_27_FLEXCAN0_TX;
    tInitStruct.ePortGpioDir = PORT_GPIO_OUT;
    tInitStruct.ePortGpioLevel = PORT_GPIO_HIGH;
    PORT_InitPins(&g_tPortHandle, &tInitStruct);

CAN配置

Bsp_CAN_LL_Init

void Bsp_CAN0_LL_Init(void)
{
	FLEXCAN_InitType tCanCfg;
	FLEXCAN_InitType *pCfg = &tCanCfg;

	pCfg->eClkSrcSel 	= 	FLEXCAN_CLOCK_CANPE;	// PCC
	pCfg->bListenOnly	=	0U;						// Listen Only Mode

	/*
	 * Normal Baud Rate
	 * Bit Time = Sync_Seg + Prop_Seg + Phase_Seg1 + Phase_Seg2
	 * TQ_total = Prescaler × Bit_Time
	 * Bitrate = CAN_Clock / (Prescaler × TQ_total)
	 * Sample Point % = (Sync_Seg + Prop_Seg + Phase_Seg1) / TQ_total
	 * Clk	PCC FOSC 24MHz DIVH 24MHz 24/4/(1(Sync)+5+4+2) = 500k
	 * */
	pCfg->tNormalBaud.u32Presdiv	= 4;
	pCfg->tNormalBaud.u32Propseg	= 5;
	pCfg->tNormalBaud.u32Pseg1		= 3;
	pCfg->tNormalBaud.u32Pseg2		= 3;
	pCfg->tNormalBaud.u32Rjw		= 1;

	/*
	 * FD Baud Rate
	 * Clk	PCC FOSC 24MHz DIVM 8MHz
	 * */
	pCfg->bEnFd						= 0;
	pCfg->tFdBaud.u32Presdiv		= 0;
	pCfg->tFdBaud.u32Propseg		= 0;
	pCfg->tFdBaud.u32Pseg1			= 0;
	pCfg->tFdBaud.u32Pseg2			= 0;
	pCfg->tFdBaud.u32Rjw			= 0;

	/* Interrupt Configuration */
	pCfg->bEnErrInt			= 0;
	pCfg->bEnBusOffInt		= 0;
	pCfg->bEnBusOffDoneInt	= 0;
	pCfg->bEnWarningInt		= 0;
	pCfg->bEnSsp			= 0;
	pCfg->bEnAutoRec		= 0;

	/* MB Configuration */
	FLEXCAN_MbSettingType   aMbList[11];
	FLEXCAN_MbSettingType   *pMb;
	/* tx occupy 7 mbs */
	pMb = &aMbList[0];
	pMb->bIsTxMB = 1U;
	pMb->bEnMBInt = 0U;  /* tx polling */
	pMb = &aMbList[1];
	pMb->bIsTxMB = 1U;
	pMb->bEnMBInt = 1U;  /* tx interrupt */
	pMb = &aMbList[2];
	pMb->bIsTxMB = 1U;
	pMb->bEnMBInt = 0U;  /* tx polling */
	pMb = &aMbList[3];
	pMb->bIsTxMB = 1U;
	pMb->bEnMBInt = 1U;  /* tx interrupt */
	pMb = &aMbList[4];
	pMb->bIsTxMB = 1U;
	pMb->bEnMBInt = 0U;  /* tx polling */
	pMb = &aMbList[5];
	pMb->bIsTxMB = 1U;
	pMb->bEnMBInt = 1U;  /* tx interrupt */
	pMb = &aMbList[6];
	pMb->bIsTxMB = 1U;
	pMb->bEnMBInt = 0U;  /* tx polling */

	/* Rx MB config */
	pMb = &aMbList[7];
	pMb->bIsTxMB = 0U;
	pMb->bEnMBInt = 1U;  /* rx interrupt */
	pMb->eRxFrameType = FLEXCAN_ID_STD;
	pMb->u32RxCanId = (uint32_t)(0x123);
	pMb->u32RxCanIdMask = 0x7FF;

	pMb = &aMbList[8];
	pMb->bIsTxMB = 0U;
	pMb->bEnMBInt = 0U;  /* rx polling */
	pMb->eRxFrameType = FLEXCAN_ID_STD;
	pMb->u32RxCanId = (uint32_t)(0x234);
	pMb->u32RxCanIdMask = 0x7FF;

	pMb = &aMbList[9];
	pMb->bIsTxMB = 0U;
	pMb->bEnMBInt = 1U;  /* rx interrupt */
	pMb->eRxFrameType = FLEXCAN_ID_STD;
	pMb->u32RxCanId = (uint32_t)(0x345);
	pMb->u32RxCanIdMask = 0x7FF;

	pMb = &aMbList[10];
	pMb->bIsTxMB = 0U;
	pMb->bEnMBInt = 0U;  /* rx polling */
	pMb->eRxFrameType = FLEXCAN_ID_STD;
	pMb->u32RxCanId = (uint32_t)(0x456);
	pMb->u32RxCanIdMask = 0x7FF;
	// Apply
    pCfg->tMbCfg.pMBList = aMbList;
    pCfg->tMbCfg.u8MBCnt = sizeof(aMbList) / sizeof(aMbList[0]);

	/* FIFO */
    FLEXCAN_FifoFilterType  aFifoList[8];
    FLEXCAN_FifoFilterType  *pFifo;

    pFifo = &aFifoList[0];
    pFifo->eRxFrameType = FLEXCAN_ID_STD;
    pFifo->u32RxCanId = (uint32_t)(0x500U);
    pFifo->u32RxCanIdMask = 0x7FFU;
    pFifo = &aFifoList[1];
    pFifo->eRxFrameType = FLEXCAN_ID_STD;
    pFifo->u32RxCanId = (uint32_t)(0x510U);
    pFifo->u32RxCanIdMask = 0x7FFU;
    pFifo = &aFifoList[2];
    pFifo->eRxFrameType = FLEXCAN_ID_STD;
    pFifo->u32RxCanId = (uint32_t)(0x520U);
    pFifo->u32RxCanIdMask = 0x7FFU;
    pFifo = &aFifoList[3];
    pFifo->eRxFrameType = FLEXCAN_ID_STD;
    pFifo->u32RxCanId = (uint32_t)(0x530U);
    pFifo->u32RxCanIdMask = 0x7FFU;
    pFifo = &aFifoList[4];
    pFifo->eRxFrameType = FLEXCAN_ID_STD;
    pFifo->u32RxCanId = (uint32_t)(0x540U);
    pFifo->u32RxCanIdMask = 0x7FFU;
    pFifo = &aFifoList[5];
    pFifo->eRxFrameType = FLEXCAN_ID_STD;
    pFifo->u32RxCanId = (uint32_t)(0x550U);
    pFifo->u32RxCanIdMask = 0x7FFU;
    pFifo = &aFifoList[6];
    pFifo->eRxFrameType = FLEXCAN_ID_STD;
    pFifo->u32RxCanId = (uint32_t)(0x560U);
    pFifo->u32RxCanIdMask = 0x7FFU;
    pFifo = &aFifoList[7];
    pFifo->eRxFrameType = FLEXCAN_ID_STD;
    pFifo->u32RxCanId = (uint32_t)(0x570U);
    pFifo->u32RxCanIdMask = 0x7FFU;

    pCfg->tRxFifoFilterCfg.bEnFifo = 1U;
    pCfg->tRxFifoFilterCfg.eFifoType = FLEXCAN_LEGACY_FIFO;
    pCfg->tRxFifoFilterCfg.tLegacyFifoCfg.bEnFifoDMA = 0U;
    pCfg->tRxFifoFilterCfg.tLegacyFifoCfg.bDataAvaliableInt = 1U;
    pCfg->tRxFifoFilterCfg.tLegacyFifoCfg.bWarningInt = 0U;
    pCfg->tRxFifoFilterCfg.tLegacyFifoCfg.bOverflowInt = 1U;
    pCfg->tRxFifoFilterCfg.tLegacyFifoCfg.u8RxFilterFifoCnt = sizeof(aFifoList) / sizeof(aFifoList[0]);
    pCfg->tRxFifoFilterCfg.tLegacyFifoCfg.pRxFilterFifoList = (FLEXCAN_FifoFilterType *)aFifoList;

    pCfg->tRxFifoFilterCfg.tEnhancedFifoCfg.bEnFifoDMA = 0U;
    pCfg->tRxFifoFilterCfg.tEnhancedFifoCfg.bDataAvaliableInt = 0U;
    pCfg->tRxFifoFilterCfg.tEnhancedFifoCfg.u8FifoWaterMark = 0U;
    pCfg->tRxFifoFilterCfg.tEnhancedFifoCfg.bWaterMarkInt = 0U;
    pCfg->tRxFifoFilterCfg.tEnhancedFifoCfg.bOverflowInt = 0U;
    pCfg->tRxFifoFilterCfg.tEnhancedFifoCfg.bUnderflowInt = 0U;
    pCfg->tRxFifoFilterCfg.tEnhancedFifoCfg.eFifoDataLength = FLEXCAN_DATAWIDTH_64;
    pCfg->tRxFifoFilterCfg.tEnhancedFifoCfg.u8RxFilterFifoCnt = 0U;
    pCfg->tRxFifoFilterCfg.tEnhancedFifoCfg.pRxFilterFifoList = NULL;
    pCfg->tPnetCfg.bPNetEnable = 0U;

    FLEXCAN_Init(&g_tCan0, pCfg);
    FLEXCAN_Start(&g_tCan0);
}

波特率及采样点

外设时钟/预分频/采样时间=波特率 (Sync_Seg + Prop_Seg + Phase_Seg1)/(Sync_Seg + Prop_Seg + Phase_Seg1 + Phase_Seg2) = 采样点%

	/*
	 * Normal Baud Rate
	 * Bit Time = Sync_Seg + Prop_Seg + Phase_Seg1 + Phase_Seg2
	 * TQ_total = Prescaler × Bit_Time
	 * Bitrate = CAN_Clock / (Prescaler × TQ_total)
	 * Sample Point % = (Sync_Seg + Prop_Seg + Phase_Seg1) / TQ_total
	 * Clk	PCC FOSC 24MHz DIVH 24MHz 24/4/(1(Sync)+5+4+2) = 500k
	 * */
	pCfg->tNormalBaud.u32Presdiv	= 4;
	pCfg->tNormalBaud.u32Propseg	= 5;
	pCfg->tNormalBaud.u32Pseg1		= 3;
	pCfg->tNormalBaud.u32Pseg2		= 3;
	pCfg->tNormalBaud.u32Rjw		= 1;

中断配置

在句柄处映射中断函数名

FLEXCAN_HandleType  g_tCan0 =
{
    .eInstance = FLEXCAN_INSTANCE_0,
    {
        .eStatusSeq = FLEXCAN_SEQUENCE_DEINIT
    },
    {
        .pRxBuf = (FLEXCAN_RxMsgType *) &s_aaRxDataBuf[0]
        , .pWakeMsg = NULL
		, .pErrorNotify = CAN_Error_CallBack
		, .pFifoIssueNotify = CAN_FifoIssue_CallBack
		, .pTxNotify = CAN_Tx_CallBack
		, .pRxNotify = CAN_Rx_CallBack
		, .pWakeNotify = NULL
    }
};

MB开启中断

	FLEXCAN_MbSettingType   aMbList[11];
	FLEXCAN_MbSettingType   *pMb;
	pMb = &aMbList[0];
	pMb->bIsTxMB = 1U;
	pMb->bEnMBInt = 0U;  /* tx polling */
	pMb = &aMbList[1];
	pMb->bIsTxMB = 1U;
	pMb->bEnMBInt = 1U;  /* tx interrupt */
	// Apply
        pCfg->tMbCfg.pMBList = aMbList;
        pCfg->tMbCfg.u8MBCnt = sizeof(aMbList) / sizeof(aMbList[0]);

2 基于SDK的CAN收发代码解析

初始化

PIN初始化(以CAN0为例)

首先是关于引脚复用初始化,如CAN0使用了FC4150的PTA27(CAN0_TX),PTA28(CAN0_RX)

    /* Port A28: MUX = ALT5, CAN0_RX */
    tInitStruct.u32PortPins = PORT_PIN_28;
    tInitStruct.uPortPinMux.u32PortPinMode = PORTA_28_FLEXCAN0_RX;
    tInitStruct.ePortGpioDir = PORT_GPIO_IN;
    tInitStruct.bPullEn = false;
    tInitStruct.ePullSel = PORT_PULL_UP;
    PORT_InitPins(&g_tPORT_A,&tInitStruct);

    /* Port A27: MUX = ALT5, CAN0_TX */
    tInitStruct.u32PortPins = PORT_PIN_27;
    tInitStruct.uPortPinMux.u32PortPinMode = PORTA_27_FLEXCAN0_TX;
    tInitStruct.ePortGpioDir = PORT_GPIO_OUT;
    tInitStruct.ePortGpioLevel = PORT_GPIO_HIGH;
    PORT_InitPins(&g_tPORT_A, &tInitStruct);

句柄配置,注意,句柄的回调函数不能空着,不然会有空指针报错

FLEXCAN_HandleType  g_tCan0 =
{
    .eInstance = FLEXCAN_INSTANCE_0,
    {
        .eStatusSeq = FLEXCAN_SEQUENCE_DEINIT//初始化CAN控制器的状态
    },
    {
        .pRxBuf = (FLEXCAN_RxMsgType *) &s_aaRxDataBuf[0]//接收buffer
        , .pWakeMsg = NULL
                //各类回调函数声明
		, .pErrorNotify = CAN_Error_CallBack
		, .pFifoIssueNotify = CAN_FifoIssue_CallBack
		, .pTxNotify = CAN_Tx_CallBack
		, .pRxNotify = CAN_Rx_CallBack
		, .pWakeNotify = NULL
    }
};

配置初始化

1.MessagreBuffer的初始化

    FLEXCAN_MbSettingType   aMbList[11];
    FLEXCAN_MbSettingType   *pMb;
    /* tx occupy 7 mbs */
    pMb = &aMbList[0];
    pMb->bIsTxMB = 1U;
    pMb->bEnMBInt = 0U;  /* tx polling */
    pMb = &aMbList[1];
    pMb->bIsTxMB = 1U;
    pMb->bEnMBInt = 1U;  /* tx interrupt */
    pMb = &aMbList[2];
    pMb->bIsTxMB = 1U;
    pMb->bEnMBInt = 0U;  /* tx polling */
    pMb = &aMbList[3];
    pMb->bIsTxMB = 1U;
    pMb->bEnMBInt = 1U;  /* tx interrupt */
    pMb = &aMbList[4];
    pMb->bIsTxMB = 1U;
    pMb->bEnMBInt = 0U;  /* tx polling */
    pMb = &aMbList[5];
    pMb->bIsTxMB = 1U;
    pMb->bEnMBInt = 1U;  /* tx interrupt */
    pMb = &aMbList[6];
    pMb->bIsTxMB = 1U;
    pMb->bEnMBInt = 0U;  /* tx polling */

    /* Rx MB config */
    pMb = &aMbList[7];
    pMb->bIsTxMB = 0U;
    pMb->bEnMBInt = 1U;  /* rx interrupt */
    pMb->eRxFrameType = FLEXCAN_ID_STD;
    pMb->u32RxCanId = (uint32_t)(0x123 + pCanHandle->eInstance);
    pMb->u32RxCanIdMask = 0x7FF;

    pMb = &aMbList[8];
    pMb->bIsTxMB = 0U;
    pMb->bEnMBInt = 0U;  /* rx polling */
    pMb->eRxFrameType = FLEXCAN_ID_STD;
    pMb->u32RxCanId = (uint32_t)(0x234 + pCanHandle->eInstance);
    pMb->u32RxCanIdMask = 0x7FF;

    pMb = &aMbList[9];
    pMb->bIsTxMB = 0U;
    pMb->bEnMBInt = 1U;  /* rx interrupt */
    pMb->eRxFrameType = FLEXCAN_ID_STD;
    pMb->u32RxCanId = (uint32_t)(0x345 + pCanHandle->eInstance);
    pMb->u32RxCanIdMask = 0x7FF;

    pMb = &aMbList[10];
    pMb->bIsTxMB = 0U;
    pMb->bEnMBInt = 0U;  /* rx polling */
    pMb->eRxFrameType = FLEXCAN_ID_STD;
    pMb->u32RxCanId = (uint32_t)(0x456 + pCanHandle->eInstance);
    pMb->u32RxCanIdMask = 0x7FF;
    /* MB配置应用 */
    tInitCfg.tMbCfg.pMBList = aMbList;
    tInitCfg.tMbCfg.u8MBCnt = sizeof(aMbList)/sizeof(aMbList[0]);

  • FIFO配置 *
    FLEXCAN_FifoFilterType  aFifoList[8];
    FLEXCAN_FifoFilterType  *pFifo;
    tInitCfg.tRxFifoFilterCfg.bEnFifo = 1U;
    /* legacy fifo */
    tInitCfg.tRxFifoFilterCfg.eFifoType = FLEXCAN_LEGACY_FIFO;
    tInitCfg.tRxFifoFilterCfg.tLegacyFifoCfg.bEnFifoDMA = 0U;

    tInitCfg.tRxFifoFilterCfg.tLegacyFifoCfg.bDataAvaliableInt = 0U;  /* legacy fifo data interrupt */
    tInitCfg.tRxFifoFilterCfg.tLegacyFifoCfg.bOverflowInt = 1U;       /* legacy fifo full interrupt */
    tInitCfg.tRxFifoFilterCfg.tLegacyFifoCfg.bWarningInt = 1U;      /* enhanced fifo will be full interrupt */

    pFifo = &aFifoList[0];
    pFifo->eRxFrameType = FLEXCAN_ID_STD;
    pFifo->u32RxCanId = (uint32_t)(0x500U + pCanHandle->eInstance);
    pFifo->u32RxCanIdMask = 0x7FFU;
    pFifo = &aFifoList[1];
    pFifo->eRxFrameType = FLEXCAN_ID_STD;
    pFifo->u32RxCanId = (uint32_t)(0x510U + pCanHandle->eInstance);
    pFifo->u32RxCanIdMask = 0x7FFU;
    pFifo = &aFifoList[2];
    pFifo->eRxFrameType = FLEXCAN_ID_STD;
    pFifo->u32RxCanId = (uint32_t)(0x520U + pCanHandle->eInstance);
    pFifo->u32RxCanIdMask = 0x7FFU;
    pFifo = &aFifoList[3];
    pFifo->eRxFrameType = FLEXCAN_ID_STD;
    pFifo->u32RxCanId = (uint32_t)(0x530U + pCanHandle->eInstance);
    pFifo->u32RxCanIdMask = 0x7FFU;
    pFifo = &aFifoList[4];
    pFifo->eRxFrameType = FLEXCAN_ID_STD;
    pFifo->u32RxCanId = (uint32_t)(0x540U + pCanHandle->eInstance);
    pFifo->u32RxCanIdMask = 0x7FFU;
    pFifo = &aFifoList[5];
    pFifo->eRxFrameType = FLEXCAN_ID_STD;
    pFifo->u32RxCanId = (uint32_t)(0x550U + pCanHandle->eInstance);
    pFifo->u32RxCanIdMask = 0x7FFU;
    pFifo = &aFifoList[6];
    pFifo->eRxFrameType = FLEXCAN_ID_STD;
    pFifo->u32RxCanId = (uint32_t)(0x560U + pCanHandle->eInstance);
    pFifo->u32RxCanIdMask = 0x7FFU;
    pFifo = &aFifoList[7];
    pFifo->eRxFrameType = FLEXCAN_ID_STD;
    pFifo->u32RxCanId = (uint32_t)(0x570U + pCanHandle->eInstance);
    pFifo->u32RxCanIdMask = 0x7FFU;

    tInitCfg.tRxFifoFilterCfg.tLegacyFifoCfg.pRxFilterFifoList = (FLEXCAN_FifoFilterType *)aFifoList;
    tInitCfg.tRxFifoFilterCfg.tLegacyFifoCfg.u8RxFilterFifoCnt = (sizeof(aFifoList) / sizeof(aFifoList[0]));

  • 波特率配置 *
    static uint32_t         u32ClkHz;
    u32ClkHz = PCC_GetPccFunctionClock(PCC_CLK_CAN0); //得知CAN0时钟
    /* 在CAN0时钟频率在16M,如果要设置500kHz,计算公式16M/2/(1+8+4+3)*/
    tInitCfg.tNormalBaud.u32Presdiv = 2;
    tInitCfg.tNormalBaud.u32Propseg = 8;
    tInitCfg.tNormalBaud.u32Pseg1 = 4;
    tInitCfg.tNormalBaud.u32Pseg2 = 3;
    tInitCfg.tNormalBaud.u32Rjw = 2;
  • CANFD及PretendedNetwork配置 *
tInitCfg.bEnFd = FALSE;
tInitCfg.tPnetCfg.bPNetEnable = 0U;

初始化配置并开启CAN0

FLEXCAN_Init(pCanHandle, &tInitCfg);
FLEXCAN_Start(pCanHandle); /* Start CAN */

阻塞发送+中断接收

Polling

    FLEXCAN_PollingProcess(&g_tCan0);//
    /* Tx Message定义 */
    FLEXCAN_TxMsgType tTxMsg = {0};
    FLEXCAN_ErrorType tRetval;
    uint8_t aData[8] = {1,2,3,4,5,6,7,8};//发送内容
    FCFUNC_FcOwnMemcpy(tTxMsg.aData, aData, sizeof(aData), NULL);//赋值到tTxMsg.aData
    tTxMsg.u32CanId = 0x111U + pCanHandle->eInstance;//CanID
    tTxMsg.u8TxHandle = 0U;//
    tTxMsg.bEnFd = FALSE;//CANFD使能
    tTxMsg.bEnBrs = FALSE;//CANFD bit switch使能
    tTxMsg.u32DataLen = 8;//数据长度
    tTxMsg.eDataType = FLEXCAN_FRAME_DATA;//数据类型
    tTxMsg.eFrameType = FLEXCAN_ID_STD;//帧类型
    tRetval = FLEXCAN_TransmitData(pCanHandle, &tTxMsg);//发送

关于FLEXCAN_PollingProcess,其有关于发送的操作是函数FLEXCAN_LL_PollingTx

static void FLEXCAN_LL_PollingTx(FLEXCAN_HandleType *pCanHandle)
{
    uint8_t             u8MbIndex;
    FLEXCAN_Type        *pCan;
    uint32_t            u32Iflag;

    pCan = (FLEXCAN_Type *)s_aFlexCan_InstanceTable[pCanHandle->eInstance];
    u32Iflag = FLEXCAN_HWA_GetFlag1(pCan) & (pCanHandle->tStatus.aTxPollingMask[0]);
    if(u32Iflag)
    {
        u8MbIndex = 0U;
        while ((u32Iflag != 0U))
        {
            if ((u32Iflag & 0x01U) == 0x01U)
            {
                pCanHandle->tSettings.pTxNotify(pCanHandle, FLEXCAN_LL_GetTxHandleByMbIndex(pCanHandle, u8MbIndex));
                //FLEXCAN_LL_GetTxHandleByMbIndex启用邮箱
                FLEXCAN_HWA_SetFlag1(pCan, 1U<<u8MbIndex);//设置TX发送完成标志位,触发硬件操作
            }

            u8MbIndex++;
            u32Iflag = u32Iflag >> 1;
        }
    }

##11