查看: 1869|回复: 0

[原创] 【MCX-N947-BRK板卡试用】-1-CAN回环模式测试

[复制链接]
  • TA的每日心情
    慵懒
    2024-5-23 06:13
  • 签到天数: 1082 天

    连续签到: 1 天

    [LV.10]以坛为家III

    18

    主题

    1974

    帖子

    0

    金牌会员

    Rank: 6Rank: 6

    积分
    6164
    最后登录
    2025-7-26
    发表于 2024-4-1 19:46:12 | 显示全部楼层 |阅读模式
    本帖最后由 SensorYoung 于 2024-4-1 19:54 编辑

    之前论坛分享关于CAN的一个帖子,温故知新:好文分享-关于CAN通讯,你拎不清的几个概念


    MCX-N系列有两路CAN,分别为CAN0和CAN1,其内部框图如下:
    1.jpg

    其工作模式有如下5种:
    2.jpg

    设置CAN0的时钟:
    1.     /* attach FRO HF to FLEXCAN0 */
    2.     CLOCK_SetClkDiv(kCLOCK_DivFlexcan0Clk, 1u);
    3.     CLOCK_AttachClk(kFRO_HF_to_FLEXCAN0);
    复制代码


    设置工作模式为loopback,CAN速率 500K bps:
    1. flexcanConfig.enableLoopBack = true;
    2. flexcanConfig.bitRate = 500000U;
    复制代码


    设置RX message buffer:
    1. /* Setup Rx Message Buffer. */
    2.     mbConfig.format = kFLEXCAN_FrameFormatStandard;
    3.     mbConfig.type   = kFLEXCAN_FrameTypeData;
    4.     mbConfig.id     = FLEXCAN_ID_STD(0x123);
    5. #if (defined(USE_CANFD) && USE_CANFD)
    6.     FLEXCAN_SetFDRxMbConfig(EXAMPLE_CAN, RX_MESSAGE_BUFFER_NUM, &mbConfig, true);
    7. #else
    8.     FLEXCAN_SetRxMbConfig(EXAMPLE_CAN, RX_MESSAGE_BUFFER_NUM, &mbConfig, true);
    9. #endif
    复制代码


    设置Tx message buffer以及tx frame的报文内容:
    1. /* Setup Tx Message Buffer. */
    2. #if (defined(USE_CANFD) && USE_CANFD)
    3.     FLEXCAN_SetFDTxMbConfig(EXAMPLE_CAN, TX_MESSAGE_BUFFER_NUM, true);
    4. #else
    5.     FLEXCAN_SetTxMbConfig(EXAMPLE_CAN, TX_MESSAGE_BUFFER_NUM, true);
    6. #endif

    7.     /* Create FlexCAN handle structure and set call back function. */
    8.     FLEXCAN_TransferCreateHandle(EXAMPLE_CAN, &flexcanHandle, flexcan_callback, NULL);

    9.     /* Start receive data through Rx Message Buffer. */
    10.     rxXfer.mbIdx = (uint8_t)RX_MESSAGE_BUFFER_NUM;
    11. #if (defined(USE_CANFD) && USE_CANFD)
    12.     rxXfer.framefd = &rxFrame;
    13.     (void)FLEXCAN_TransferFDReceiveNonBlocking(EXAMPLE_CAN, &flexcanHandle, &rxXfer);
    14. #else
    15.     rxXfer.frame = &rxFrame;
    16.     (void)FLEXCAN_TransferReceiveNonBlocking(EXAMPLE_CAN, &flexcanHandle, &rxXfer);
    17. #endif

    18.     /* Prepare Tx Frame for sending. */
    19.     txFrame.format = (uint8_t)kFLEXCAN_FrameFormatStandard;
    20.     txFrame.type   = (uint8_t)kFLEXCAN_FrameTypeData;
    21.     txFrame.id     = FLEXCAN_ID_STD(0x123);
    22.     txFrame.length = (uint8_t)DLC;
    23. #if (defined(USE_CANFD) && USE_CANFD)
    24.     txFrame.brs = 1U;
    25. #endif
    26. #if (defined(USE_CANFD) && USE_CANFD)
    27.     uint8_t i = 0;
    28.     for (i = 0; i < DWORD_IN_MB; i++)
    29.     {
    30.         txFrame.dataWord[i] = i;
    31.     }
    32. #else
    33.     txFrame.dataWord0 = CAN_WORD0_DATA_BYTE_0(0x11) | CAN_WORD0_DATA_BYTE_1(0x22) | CAN_WORD0_DATA_BYTE_2(0x33) |
    34.                         CAN_WORD0_DATA_BYTE_3(0x44);
    35.     txFrame.dataWord1 = CAN_WORD1_DATA_BYTE_4(0x55) | CAN_WORD1_DATA_BYTE_5(0x66) | CAN_WORD1_DATA_BYTE_6(0x77) |
    36.                         CAN_WORD1_DATA_BYTE_7(0x88);
    37. #endif

    38.     SEGGER_RTT_printf(0,"Send message from MB%d to MB%d\r\n", TX_MESSAGE_BUFFER_NUM, RX_MESSAGE_BUFFER_NUM);
    39. #if (defined(USE_CANFD) && USE_CANFD)
    40.     for (i = 0; i < DWORD_IN_MB; i++)
    41.     {
    42.         SEGGER_RTT_printf(0,"tx word%d = 0x%x\r\n", i, txFrame.dataWord[i]);
    43.     }
    44. #else
    45.     SEGGER_RTT_printf(0,"tx word0 = 0x%x\r\n", txFrame.dataWord0);
    46.     SEGGER_RTT_printf(0,"tx word1 = 0x%x\r\n", txFrame.dataWord1);
    47. #endif

    48.     /* Send data through Tx Message Buffer. */
    49.     txXfer.mbIdx = (uint8_t)TX_MESSAGE_BUFFER_NUM;
    50. #if (defined(USE_CANFD) && USE_CANFD)
    51.     txXfer.framefd = &txFrame;
    52.     (void)FLEXCAN_TransferFDSendNonBlocking(EXAMPLE_CAN, &flexcanHandle, &txXfer);
    53. #else
    54.     txXfer.frame = &txFrame;
    55.     (void)FLEXCAN_TransferSendNonBlocking(EXAMPLE_CAN, &flexcanHandle, &txXfer);
    56. #endif
    复制代码


    接下来等待发送/接收中断置位相应的Flag:
    1.     /* Waiting for Rx Message finish. */
    2.     while ((!rxComplete) || (!txComplete))
    3.     {
    4.     };
    复制代码


    接收到报文后,通过Segger Jlink Viewer打印相关的报文内容。
    1.   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);
    2.                 SEGGER_RTT_printf(0,"rx frame CanID = 0x%x\r\n", (rxFrame.id)>>18);
    3.     SEGGER_RTT_printf(0,"rx word0 = 0x%x\r\n", rxFrame.dataWord0);
    4.     SEGGER_RTT_printf(0,"rx word1 = 0x%x\r\n", rxFrame.dataWord1);
    复制代码


    实验结果:
    3.jpg

    遇到的问题:想要打印一下接收到的报文ID,发现需要进行移位操作后才能得到正确结果。如下所示:
    1. SEGGER_RTT_printf(0,"rx frame CanID = 0x%x\r\n", (rxFrame.id)>>18);
    复制代码

    后来在网上检索到类似的问题:NXP Community Decode/Revert CAN Frame ID,贴在这里,以供参考。
    4.jpg


    参考:
    MCUXpresso SDK API Reference Manual https://mcuxpresso.nxp.com/api_doc/dev/71/group__flexcan__driver.html
    回复

    使用道具 举报

    您需要登录后才可以回帖 注册/登录

    本版积分规则

    关闭

    站长推荐上一条 /3 下一条

    Archiver|手机版|小黑屋|恩智浦技术社区

    GMT+8, 2025-7-27 12:24 , Processed in 0.079124 second(s), 20 queries , MemCache On.

    Powered by Discuz! X3.4

    Copyright © 2001-2024, Tencent Cloud.

    快速回复 返回顶部 返回列表