一、CAN的基本概念
1、FlexCAN:是一个通信控制器模块,它遵循ISO 11898-1标准、CAN 2.0B协议规范,并支持CAN FD(Flexible Data-Rate)模式。
2、CAN FD(Controller Area Network Flexible Data Rate):即灵活数据速率控制器局域网,是一种新一代的车载网络通信协议。它提供了比传统CAN协议更高的数据传输速率和更大的数据帧长度。
3、位时间采样点:在CAN FD通信中,位时间采样点是指在数据帧的位时间内,接收器对传输的
位信号进行采样的时间点。一次采样点通常是在位时间的中间位置进行采样,以确定该位的值是0
还是1。而二次采样点是在位时间的后半部分进行的额外采样,用于提高数据传输的可靠性。位时
间采样点的正确配置对于CAN FD通信的可靠性和稳定性至关重要。如果采样点位置不正确,可能
会导致数据传输错误或丢失。因此,在配置FlexCAN FD时,需要仔细调整位时序参数,以确保采
样点位于正确的位置。
4、FlexCAN 模块支持三种工作模式:回环模式、只听模式和正常工作模式。因为在回环模式下,FlexCAN 的传输帧并不会通过其收发引脚发送到 CAN 总线,所以通常用于测试单块芯片的 FlexCAN 模块是否工作正常。
5、MB:CAN(Controller Area Network)总线中的Message Buffer(消息缓冲区)是一个关键组件,用于管理CAN通信帧的发送和接收。Message Buffer是CAN总线通信协议引擎中的一个存储空间,用于临时存储待发送或已接收的CAN通信帧。这些通信帧包括数据负载、时间戳、消息ID等关键信息。
找到另一个有CAN模块的芯片并不容易,同时loopback(回环模式)模式可以在单块芯片运行,所以本文对CAN loopback模式(自发自收)进行测评。
二、CAN loopback模式解读
1、FLEXCAN Rx中断处理函数
使用FLEXCAN_ReadFDRxMb函数接收数据。
void EXAMPLE_FLEXCAN_IRQHandler(void) { if (0U != FLEXCAN_GetMbStatusFlags(EXAMPLE_CAN, (uint32_t)1U << RX_MESSAGE_BUFFER_NUM)) { FLEXCAN_ClearMbStatusFlags(EXAMPLE_CAN, (uint32_t)1U << RX_MESSAGE_BUFFER_NUM); rxComplete = true; } if (rxComplete) { (void)FLEXCAN_ReadFDRxMb(EXAMPLE_CAN, RX_MESSAGE_BUFFER_NUM, &rxFrame); } SDK_ISR_EXIT_BARRIER; }
2、flexcan配置参数
FLEXCAN_GetDefaultConfig(&flexcanConfig);
获得缺省配置,缺省配置为:
/* Init FlexCAN module. */ /* * flexcanConfig.clkSrc = kFLEXCAN_ClkSrc0; * flexcanConfig.bitRate = 1000000U; * flexcanConfig.bitRateFD = 2000000U; * flexcanConfig.maxMbNum = 16; * flexcanConfig.enableLoopBack = false; * flexcanConfig.enableSelfWakeup = false; * flexcanConfig.enableIndividMask = false; * flexcanConfig.disableSelfReception = false; * flexcanConfig.enableListenOnlyMode = false; * flexcanConfig.enableDoze = false; */
3、设置loopback(回环模式)模式
flexcanConfig.enableLoopBack = true;
4、计算FlexCAN FD的位时间的采样点
if (FLEXCAN_FDCalculateImprovedTimingValues(EXAMPLE_CAN, flexcanConfig.bitRate, flexcanConfig.bitRateFD, EXAMPLE_CAN_CLK_FREQ, &timing_config)) { /* Update the improved timing configuration*/ memcpy(&(flexcanConfig.timingConfig), &timing_config, sizeof(flexcan_timing_config_t)); } else { LOG_INFO("No found Improved Timing Configuration. Just used default configuration\r\n\r\n"); }
5、FLEXCAN初始化
FLEXCAN_FDInit(EXAMPLE_CAN, &flexcanConfig, EXAMPLE_CAN_CLK_FREQ, BYTES_IN_MB, true);
6、Setup Rx Message Buffer
FLEXCAN_SetFDRxMbConfig(EXAMPLE_CAN, RX_MESSAGE_BUFFER_NUM, &mbConfig, true);
7、Setup Tx Message Buffer
FLEXCAN_SetFDTxMbConfig(EXAMPLE_CAN, TX_MESSAGE_BUFFER_NUM, true);
8、使能Rx Message Buffer中断
FLEXCAN_EnableMbInterrupts(EXAMPLE_CAN, (uint32_t)1U << RX_MESSAGE_BUFFER_NUM); (void)EnableIRQ(EXAMPLE_FLEXCAN_IRQn);
9、polling方式发送数据
FLEXCAN_TransferFDSendBlocking(EXAMPLE_CAN, TX_MESSAGE_BUFFER_NUM, &txFrame);
10、中断rxComplete为true,打印接收的数据
while (!rxComplete) { } LOG_INFO("\r\nReceived message from MB%d\r\n", RX_MESSAGE_BUFFER_NUM); #if (defined(USE_CANFD) && USE_CANFD) for (i = 0; i < DWORD_IN_MB; i++) { LOG_INFO("rx word%d = 0x%x\r\n", i, rxFrame.dataWord[i]); }
三、运行效果