在线时间907 小时
UID349725
注册时间2012-3-27
NXP金币1631
TA的每日心情 | 慵懒 2024-5-23 06:13 |
---|
签到天数: 1082 天 连续签到: 1 天 [LV.10]以坛为家III
金牌会员
 
- 积分
- 6164
- 最后登录
- 2025-7-26
|
本帖最后由 SensorYoung 于 2024-4-1 19:54 编辑
之前论坛分享关于CAN的一个帖子,温故知新:好文分享-关于CAN通讯,你拎不清的几个概念
MCX-N系列有两路CAN,分别为CAN0和CAN1,其内部框图如下:
其工作模式有如下5种:
设置CAN0的时钟:
- /* attach FRO HF to FLEXCAN0 */
- CLOCK_SetClkDiv(kCLOCK_DivFlexcan0Clk, 1u);
- CLOCK_AttachClk(kFRO_HF_to_FLEXCAN0);
复制代码
设置工作模式为loopback,CAN速率 500K bps:
- flexcanConfig.enableLoopBack = true;
- flexcanConfig.bitRate = 500000U;
复制代码
设置RX message buffer:
- /* Setup Rx Message Buffer. */
- mbConfig.format = kFLEXCAN_FrameFormatStandard;
- mbConfig.type = kFLEXCAN_FrameTypeData;
- mbConfig.id = FLEXCAN_ID_STD(0x123);
- #if (defined(USE_CANFD) && USE_CANFD)
- FLEXCAN_SetFDRxMbConfig(EXAMPLE_CAN, RX_MESSAGE_BUFFER_NUM, &mbConfig, true);
- #else
- FLEXCAN_SetRxMbConfig(EXAMPLE_CAN, RX_MESSAGE_BUFFER_NUM, &mbConfig, true);
- #endif
复制代码
设置Tx message buffer以及tx frame的报文内容:
- /* Setup Tx Message Buffer. */
- #if (defined(USE_CANFD) && USE_CANFD)
- FLEXCAN_SetFDTxMbConfig(EXAMPLE_CAN, TX_MESSAGE_BUFFER_NUM, true);
- #else
- FLEXCAN_SetTxMbConfig(EXAMPLE_CAN, TX_MESSAGE_BUFFER_NUM, true);
- #endif
- /* Create FlexCAN handle structure and set call back function. */
- FLEXCAN_TransferCreateHandle(EXAMPLE_CAN, &flexcanHandle, flexcan_callback, NULL);
- /* Start receive data through Rx Message Buffer. */
- rxXfer.mbIdx = (uint8_t)RX_MESSAGE_BUFFER_NUM;
- #if (defined(USE_CANFD) && USE_CANFD)
- rxXfer.framefd = &rxFrame;
- (void)FLEXCAN_TransferFDReceiveNonBlocking(EXAMPLE_CAN, &flexcanHandle, &rxXfer);
- #else
- rxXfer.frame = &rxFrame;
- (void)FLEXCAN_TransferReceiveNonBlocking(EXAMPLE_CAN, &flexcanHandle, &rxXfer);
- #endif
- /* Prepare Tx Frame for sending. */
- txFrame.format = (uint8_t)kFLEXCAN_FrameFormatStandard;
- txFrame.type = (uint8_t)kFLEXCAN_FrameTypeData;
- txFrame.id = FLEXCAN_ID_STD(0x123);
- txFrame.length = (uint8_t)DLC;
- #if (defined(USE_CANFD) && USE_CANFD)
- txFrame.brs = 1U;
- #endif
- #if (defined(USE_CANFD) && USE_CANFD)
- uint8_t i = 0;
- for (i = 0; i < DWORD_IN_MB; i++)
- {
- txFrame.dataWord[i] = i;
- }
- #else
- txFrame.dataWord0 = CAN_WORD0_DATA_BYTE_0(0x11) | CAN_WORD0_DATA_BYTE_1(0x22) | CAN_WORD0_DATA_BYTE_2(0x33) |
- CAN_WORD0_DATA_BYTE_3(0x44);
- txFrame.dataWord1 = CAN_WORD1_DATA_BYTE_4(0x55) | CAN_WORD1_DATA_BYTE_5(0x66) | CAN_WORD1_DATA_BYTE_6(0x77) |
- CAN_WORD1_DATA_BYTE_7(0x88);
- #endif
- SEGGER_RTT_printf(0,"Send message from MB%d to MB%d\r\n", TX_MESSAGE_BUFFER_NUM, RX_MESSAGE_BUFFER_NUM);
- #if (defined(USE_CANFD) && USE_CANFD)
- for (i = 0; i < DWORD_IN_MB; i++)
- {
- SEGGER_RTT_printf(0,"tx word%d = 0x%x\r\n", i, txFrame.dataWord[i]);
- }
- #else
- SEGGER_RTT_printf(0,"tx word0 = 0x%x\r\n", txFrame.dataWord0);
- SEGGER_RTT_printf(0,"tx word1 = 0x%x\r\n", txFrame.dataWord1);
- #endif
- /* Send data through Tx Message Buffer. */
- txXfer.mbIdx = (uint8_t)TX_MESSAGE_BUFFER_NUM;
- #if (defined(USE_CANFD) && USE_CANFD)
- txXfer.framefd = &txFrame;
- (void)FLEXCAN_TransferFDSendNonBlocking(EXAMPLE_CAN, &flexcanHandle, &txXfer);
- #else
- txXfer.frame = &txFrame;
- (void)FLEXCAN_TransferSendNonBlocking(EXAMPLE_CAN, &flexcanHandle, &txXfer);
- #endif
复制代码
接下来等待发送/接收中断置位相应的Flag:
- /* Waiting for Rx Message finish. */
- while ((!rxComplete) || (!txComplete))
- {
- };
复制代码
接收到报文后,通过Segger Jlink Viewer打印相关的报文内容。
- SEGGER_RTT_printf(0,"EXAMPLE_CAN_CLK_FREQ = %u MHz, CAN BUS bitRate = %uk bps\r\n", EXAMPLE_CAN_CLK_FREQ/1000000, (flexcanConfig.bitRate)/1000);
- SEGGER_RTT_printf(0,"rx frame CanID = 0x%x\r\n", (rxFrame.id)>>18);
- SEGGER_RTT_printf(0,"rx word0 = 0x%x\r\n", rxFrame.dataWord0);
- SEGGER_RTT_printf(0,"rx word1 = 0x%x\r\n", rxFrame.dataWord1);
复制代码
实验结果:
遇到的问题:想要打印一下接收到的报文ID,发现需要进行移位操作后才能得到正确结果。如下所示:
- SEGGER_RTT_printf(0,"rx frame CanID = 0x%x\r\n", (rxFrame.id)>>18);
复制代码
后来在网上检索到类似的问题:NXP Community Decode/Revert CAN Frame ID,贴在这里,以供参考。
参考:
MCUXpresso SDK API Reference Manual https://mcuxpresso.nxp.com/api_doc/dev/71/group__flexcan__driver.html
|
|