查看: 4983|回复: 5

[原创] 【DIY-LPC553X】+ CAN通信测试

[复制链接]
  • TA的每日心情
    开心
    昨天 08:27
  • 签到天数: 1510 天

    连续签到: 12 天

    [LV.Master]伴坛终老

    152

    主题

    3191

    帖子

    31

    版主

    Rank: 7Rank: 7Rank: 7

    积分
    8758
    最后登录
    2025-8-31
    发表于 2022-8-26 11:30:37 | 显示全部楼层 |阅读模式
    本帖最后由 TLLED 于 2022-8-26 11:32 编辑

        测试下板子上的CAN通信部分,测试程序还是用原厂开发板的例程

        一、电路部分


        DIY的这块板子使用的和原厂接口有点不一样,我使用的接口如下:


        001.png
       

       二、程序部分


        2.1、代码使用 MCUXpresso IDE软件导入SDK例程



        100.png
        101.png


        2.2、主程序   
    1. /*
    2. * Copyright (c) 2016, Freescale Semiconductor, Inc.
    3. * Copyright 2016-2021 NXP
    4. * All rights reserved.
    5. *
    6. * SPDX-License-Identifier: BSD-3-Clause
    7. */

    8. #include "fsl_debug_console.h"
    9. #include "fsl_mcan.h"
    10. #include "pin_mux.h"
    11. #include "board.h"
    12. #include "stdlib.h"

    13. #include <stdbool.h>
    14. /*******************************************************************************
    15. * Definitions
    16. ******************************************************************************/
    17. #define USE_CANFD (1U)
    18. /*
    19. *    CAN_DATASIZE   DLC    BYTES_IN_MB
    20. *    8              8      kMCAN_8ByteDatafield
    21. *    12             9      kMCAN_12ByteDatafield
    22. *    16             10     kMCAN_16ByteDatafield
    23. *    20             11     kMCAN_20ByteDatafield
    24. *    24             12     kMCAN_24ByteDatafield
    25. *    32             13     kMCAN_32ByteDatafield
    26. *    48             14     kMCAN_48ByteDatafield
    27. *    64             15     kMCAN_64ByteDatafield
    28. *
    29. *  CAN data size (pay load size), DLC and Bytes in Message buffer must align.
    30. *
    31. */
    32. #define DLC         (15)
    33. #define BYTES_IN_MB kMCAN_64ByteDatafield
    34. /* If not define USE_CANFD or define it 0, CAN_DATASIZE should be 8. */
    35. #define CAN_DATASIZE (64U)
    36. /* If user need to auto execute the improved timming configuration. */
    37. #define USE_IMPROVED_TIMING_CONFIG (1U)
    38. #define EXAMPLE_MCAN_IRQHandler    CAN0_IRQ0_IRQHandler
    39. #define EXAMPLE_MCAN_IRQn          CAN0_IRQ0_IRQn
    40. #define EXAMPLE_MCAN               CAN0
    41. #define MCAN_CLK_FREQ              CLOCK_GetMCanClkFreq()
    42. #define STDID_OFFSET               (18U)
    43. #define MSG_RAM_BASE               0x04000000U
    44. #define STD_FILTER_OFS 0x0
    45. #define RX_FIFO0_OFS   0x10U
    46. #define TX_BUFFER_OFS  0x20U
    47. #define MSG_RAM_SIZE   (TX_BUFFER_OFS + 8 + CAN_DATASIZE)

    48. /*******************************************************************************
    49. * Prototypes
    50. ******************************************************************************/

    51. /*******************************************************************************
    52. * Variables
    53. ******************************************************************************/
    54. volatile bool txComplete = false;
    55. volatile bool rxComplete = false;
    56. mcan_tx_buffer_frame_t txFrame;
    57. mcan_rx_buffer_frame_t rxFrame;
    58. uint8_t tx_data[CAN_DATASIZE];
    59. uint8_t rx_data[CAN_DATASIZE];
    60. mcan_handle_t mcanHandle;
    61. mcan_buffer_transfer_t txXfer;
    62. mcan_fifo_transfer_t rxXfer;
    63. uint32_t txIdentifier;
    64. uint32_t rxIdentifier;
    65. #ifndef MSG_RAM_BASE
    66. SDK_ALIGN(uint8_t msgRam[MSG_RAM_SIZE], 1U << CAN_MRBA_BA_SHIFT);
    67. #else
    68. #define msgRam MSG_RAM_BASE
    69. #endif

    70. /*******************************************************************************
    71. * Code
    72. ******************************************************************************/
    73. /*!
    74. * @brief MCAN Call Back function
    75. */
    76. static void mcan_callback(CAN_Type *base, mcan_handle_t *handle, status_t status, uint32_t result, void *userData)
    77. {
    78.     switch (status)
    79.     {
    80.         case kStatus_MCAN_RxFifo0Idle:
    81.         {
    82.             rxComplete = true;
    83.         }
    84.         break;

    85.         case kStatus_MCAN_TxIdle:
    86.         {
    87.             txComplete = true;
    88.         }
    89.         break;

    90.         default:
    91.             break;
    92.     }
    93. }

    94. /*!
    95. * @brief Main function
    96. */
    97. int main(void)
    98. {
    99.     mcan_config_t mcanConfig;
    100.     mcan_frame_filter_config_t rxFilter;
    101.     mcan_std_filter_element_config_t stdFilter;
    102.     mcan_rx_fifo_config_t rxFifo0;
    103.     mcan_tx_buffer_config_t txBuffer;
    104.     uint8_t node_type;
    105.     uint8_t numMessage = 0;
    106.     uint8_t cnt        = 0;

    107.     /* Initialize board hardware. */
    108.     /* attach 12 MHz clock to FLEXCOMM0 (debug console) */
    109.     CLOCK_SetClkDiv(kCLOCK_DivFlexcom0Clk, 0u, false);
    110.     CLOCK_SetClkDiv(kCLOCK_DivFlexcom0Clk, 1u, true);
    111.     CLOCK_AttachClk(BOARD_DEBUG_UART_CLK_ATTACH);

    112.     /* Set MCAN clock 100Mhz/5=20MHz. */
    113.     CLOCK_SetClkDiv(kCLOCK_DivCanClk, 5U, true);
    114.     CLOCK_AttachClk(kMCAN_DIV_to_MCAN);

    115.     BOARD_InitPins();
    116.     BOARD_BootClockPLL100M();
    117.     BOARD_InitDebugConsole();

    118.     do
    119.     {
    120.         PRINTF("Please select local node as A or B:\r\n");
    121.         PRINTF("Note: Node B should start first.\r\n");
    122.         PRINTF("Node:");
    123.         node_type = GETCHAR();
    124.         PRINTF("%c", node_type);
    125.         PRINTF("\r\n");
    126.     } while ((node_type != 'A') && (node_type != 'B') && (node_type != 'a') && (node_type != 'b'));

    127.     /* Select mailbox ID. */
    128.     if ((node_type == 'A') || (node_type == 'a'))
    129.     {
    130.         txIdentifier = 0x321U;
    131.         rxIdentifier = 0x123U;
    132.     }
    133.     else
    134.     {
    135.         txIdentifier = 0x123U;
    136.         rxIdentifier = 0x321U;
    137.     }

    138.     /* Get MCAN module default Configuration. */
    139.     /*
    140.      * mcanConfig.baudRate               = 500000U;
    141.      * mcanConfig.baudRateFD             = 2000000U;
    142.      * mcanConfig.enableCanfdNormal      = false;
    143.      * mcanConfig.enableCanfdSwitch      = false;
    144.      * mcanConfig.enableLoopBackInt      = false;
    145.      * mcanConfig.enableLoopBackExt      = false;
    146.      * mcanConfig.enableBusMon           = false;
    147.      */
    148.     MCAN_GetDefaultConfig(&mcanConfig);
    149. #if (defined(USE_CANFD) && USE_CANFD)
    150.     /* Enable Bit Rate Switch to make baudRateD make sense.*/
    151.     mcanConfig.enableCanfdSwitch = true;
    152. #endif

    153. #if (defined(USE_IMPROVED_TIMING_CONFIG) && USE_IMPROVED_TIMING_CONFIG)
    154.     mcan_timing_config_t timing_config;
    155.     memset(&timing_config, 0, sizeof(timing_config));
    156. #if (defined(USE_CANFD) && USE_CANFD)
    157.     if (MCAN_FDCalculateImprovedTimingValues(mcanConfig.baudRateA, mcanConfig.baudRateD, MCAN_CLK_FREQ, &timing_config))
    158.     {
    159.         /* Update the improved timing configuration*/
    160.         memcpy(&(mcanConfig.timingConfig), &timing_config, sizeof(mcan_timing_config_t));
    161.     }
    162.     else
    163.     {
    164.         PRINTF("No found Improved Timing Configuration. Just used default configuration\r\n\r\n");
    165.     }
    166. #else
    167.     if (MCAN_CalculateImprovedTimingValues(mcanConfig.baudRateA, MCAN_CLK_FREQ, &timing_config))
    168.     {
    169.         /* Update the improved timing configuration*/
    170.         memcpy(&(mcanConfig.timingConfig), &timing_config, sizeof(mcan_timing_config_t));
    171.     }
    172.     else
    173.     {
    174.         PRINTF("No found Improved Timing Configuration. Just used default configuration\r\n\r\n");
    175.     }
    176. #endif
    177. #endif

    178.     MCAN_Init(EXAMPLE_MCAN, &mcanConfig, MCAN_CLK_FREQ);

    179.     /* Create MCAN handle structure and set call back function. */
    180.     MCAN_TransferCreateHandle(EXAMPLE_MCAN, &mcanHandle, mcan_callback, NULL);

    181.     /* Set Message RAM base address and clear to avoid BEU/BEC error. */
    182.     MCAN_SetMsgRAMBase(EXAMPLE_MCAN, (uint32_t)msgRam);
    183.     memset((void *)msgRam, 0, MSG_RAM_SIZE * sizeof(uint8_t));

    184.     /* STD filter config. */
    185.     rxFilter.address  = STD_FILTER_OFS;
    186.     rxFilter.idFormat = kMCAN_FrameIDStandard;
    187.     rxFilter.listSize = 1U;
    188.     rxFilter.nmFrame  = kMCAN_reject0;
    189.     rxFilter.remFrame = kMCAN_rejectFrame;
    190.     MCAN_SetFilterConfig(EXAMPLE_MCAN, &rxFilter);

    191.     stdFilter.sfec = kMCAN_storeinFifo0;
    192.     /* Classic filter mode, only filter matching ID. */
    193.     stdFilter.sft   = kMCAN_classic;
    194.     stdFilter.sfid1 = rxIdentifier;
    195.     stdFilter.sfid2 = 0x7FFU;
    196.     MCAN_SetSTDFilterElement(EXAMPLE_MCAN, &rxFilter, &stdFilter, 0);

    197.     /* RX fifo0 config. */
    198.     rxFifo0.address       = RX_FIFO0_OFS;
    199.     rxFifo0.elementSize   = 1U;
    200.     rxFifo0.watermark     = 0;
    201.     rxFifo0.opmode        = kMCAN_FifoBlocking;
    202.     rxFifo0.datafieldSize = kMCAN_8ByteDatafield;
    203. #if (defined(USE_CANFD) && USE_CANFD)
    204.     rxFifo0.datafieldSize = BYTES_IN_MB;
    205. #endif
    206.     MCAN_SetRxFifo0Config(EXAMPLE_MCAN, &rxFifo0);

    207.     /* TX buffer config. */
    208.     memset(&txBuffer, 0, sizeof(txBuffer));
    209.     txBuffer.address       = TX_BUFFER_OFS;
    210.     txBuffer.dedicatedSize = 1U;
    211.     txBuffer.fqSize        = 0;
    212.     txBuffer.datafieldSize = kMCAN_8ByteDatafield;
    213. #if (defined(USE_CANFD) && USE_CANFD)
    214.     txBuffer.datafieldSize = BYTES_IN_MB;
    215. #endif
    216.     MCAN_SetTxBufferConfig(EXAMPLE_MCAN, &txBuffer);

    217.     /* Finish software initialization and enter normal mode, synchronizes to
    218.        CAN bus, ready for communication */
    219.     MCAN_EnterNormalMode(EXAMPLE_MCAN);

    220.     if ((node_type == 'A') || (node_type == 'a'))
    221.     {
    222.         PRINTF("Press any key to trigger one-shot transmission\r\n\r\n");
    223.     }
    224.     else
    225.     {
    226.         PRINTF("Start to Wait data from Node A\r\n\r\n");
    227.     }

    228.     while (1)
    229.     {
    230.         if ((node_type == 'A') || (node_type == 'a'))
    231.         {
    232.             GETCHAR();
    233.             /* Config TX frame data. */
    234.             memset(tx_data, 0, sizeof(uint8_t) * CAN_DATASIZE);
    235.             for (cnt = 0; cnt < CAN_DATASIZE; cnt++)
    236.             {
    237.                 tx_data[cnt] = cnt;
    238.             }
    239.             tx_data[0] += numMessage++;
    240.             txFrame.xtd  = kMCAN_FrameIDStandard;
    241.             txFrame.rtr  = kMCAN_FrameTypeData;
    242.             txFrame.fdf  = 0;
    243.             txFrame.brs  = 0;
    244.             txFrame.dlc  = 8U;
    245.             txFrame.id   = txIdentifier << STDID_OFFSET;
    246.             txFrame.data = tx_data;
    247.             txFrame.size = CAN_DATASIZE;
    248. #if (defined(USE_CANFD) && USE_CANFD)
    249.             txFrame.fdf = 1;
    250.             txFrame.brs = 1;
    251.             txFrame.dlc = DLC;
    252. #endif
    253.             txXfer.frame     = &txFrame;
    254.             txXfer.bufferIdx = 0;
    255.             MCAN_TransferSendNonBlocking(EXAMPLE_MCAN, &mcanHandle, &txXfer);

    256.             while (!txComplete)
    257.             {
    258.             }
    259.             txComplete = false;

    260.             /* Start receive data through Rx FIFO 0. */
    261.             memset(rx_data, 0, sizeof(uint8_t) * CAN_DATASIZE);
    262.             /* the MCAN engine can't auto to get rx payload size, we need set it. */
    263.             rxFrame.size = CAN_DATASIZE;
    264.             rxXfer.frame = &rxFrame;
    265.             MCAN_TransferReceiveFifoNonBlocking(EXAMPLE_MCAN, 0, &mcanHandle, &rxXfer);

    266.             /* Wait until message received. */
    267.             while (!rxComplete)
    268.             {
    269.             }
    270.             rxComplete = false;

    271.             /* After call the API of rMCAN_TransferReceiveFifoNonBlocking success, we can
    272.              * only get a point (rxFrame.data) to the fifo reading entrance.
    273.              * Copy the received frame data from the FIFO by the pointer(rxFrame.data). */
    274.             memcpy(rx_data, rxFrame.data, rxFrame.size);

    275.             PRINTF("Received Frame ID: 0x%x\r\n", rxFrame.id >> STDID_OFFSET);
    276.             PRINTF("Received Frame DATA: ");
    277.             cnt = 0;
    278.             while (cnt < rxFrame.size)
    279.             {
    280.                 PRINTF("0x%x ", rx_data[cnt++]);
    281.             }
    282.             PRINTF("\r\n");
    283.             PRINTF("Press any key to trigger the next transmission!\r\n\r\n");
    284.         }
    285.         else
    286.         {
    287.             memset(rx_data, 0, sizeof(uint8_t) * CAN_DATASIZE);
    288.             /* the MCAN engine can't auto to get rx payload size, we need set it. */
    289.             rxFrame.size = CAN_DATASIZE;
    290.             rxXfer.frame = &rxFrame;
    291.             MCAN_TransferReceiveFifoNonBlocking(EXAMPLE_MCAN, 0, &mcanHandle, &rxXfer);

    292.             while (!rxComplete)
    293.             {
    294.             }
    295.             rxComplete = false;

    296.             /* After call the API of rMCAN_TransferReceiveFifoNonBlocking success, we can
    297.              * only get a point (rxFrame.data) to the fifo reading entrance.
    298.              * Copy the received frame data from the FIFO by the pointer(rxFrame.data). */
    299.             memcpy(rx_data, rxFrame.data, rxFrame.size);

    300.             PRINTF("Received Frame ID: 0x%x\r\n", rxFrame.id >> STDID_OFFSET);
    301.             PRINTF("Received Frame DATA: ");

    302.             cnt = 0;
    303.             while (cnt < rxFrame.size)
    304.             {
    305.                 PRINTF("0x%x ", rx_data[cnt++]);
    306.             }
    307.             PRINTF("\r\n");

    308.             /* Copy received frame data to tx frame. */
    309.             memcpy(tx_data, rx_data, CAN_DATASIZE);

    310.             txFrame.xtd      = rxFrame.xtd;
    311.             txFrame.rtr      = rxFrame.rtr;
    312.             txFrame.fdf      = rxFrame.fdf;
    313.             txFrame.brs      = rxFrame.brs;
    314.             txFrame.dlc      = rxFrame.dlc;
    315.             txFrame.id       = txIdentifier << STDID_OFFSET;
    316.             txFrame.data     = tx_data;
    317.             txFrame.size     = rxFrame.size;
    318.             txXfer.frame     = &txFrame;
    319.             txXfer.bufferIdx = 0;

    320.             MCAN_TransferSendNonBlocking(EXAMPLE_MCAN, &mcanHandle, &txXfer);

    321.             while (!txComplete)
    322.             {
    323.             }
    324.             txComplete = false;
    325.             PRINTF("Wait Node A to trigger the next transmission!\r\n\r\n");
    326.         }
    327.     }
    328. }
    复制代码

        2.3、程序修改部分


        修改pinmux.c和pinmux.h代码,将CAN通信端口映射到DIY的板卡端口
        pinmux.c
        002.png
       
        pinmux.h
        003.png


        三、测试程序


        3.1、这个代码是需要两个板子之间CAN通信测试的例程
        004.png


        3.2、手里只焊接了一块板子,这先测试CAN端口收发功能,使用CAN卡和开发板之间通信,硬件连接
        300.jpg


        3.3、下载程序后运行


        CAN通信波特率:500kbps
        串口输出内容
        005.png
       
        CAN卡发送和接收的内容
        006.png
       
        通过上面的测试,CAN通信收发功能是正常的,数据和测试例程的数据格式不一致,数据没有参考性。

    哎...今天够累的,签到来了~
    回复

    使用道具 举报

  • TA的每日心情
    开心
    昨天 15:43
  • 签到天数: 1732 天

    连续签到: 25 天

    [LV.Master]伴坛终老

    23

    主题

    1万

    帖子

    1

    金牌会员

    Rank: 6Rank: 6

    积分
    15970
    最后登录
    2025-8-31
    发表于 2022-8-26 12:10:57 | 显示全部楼层
    553X带的can就是普通的can,不是can-fd吧?
    跟着日天混,三天饱九顿!
    回复 支持 反对

    使用道具 举报

  • TA的每日心情
    擦汗
    昨天 15:50
  • 签到天数: 1874 天

    连续签到: 5 天

    [LV.Master]伴坛终老

    203

    主题

    3万

    帖子

    64

    超级版主

    Rank: 8Rank: 8

    积分
    112714
    最后登录
    2025-8-31
    发表于 2022-8-26 17:39:01 | 显示全部楼层
    你把CANFD关闭,或者先检查一下DLC,即使是CAN2.0,payload的长度也可能是0-8
    该会员没有填写今日想说内容.
    回复 支持 反对

    使用道具 举报

  • TA的每日心情
    开心
    昨天 20:15
  • 签到天数: 733 天

    连续签到: 2 天

    [LV.9]以坛为家II

    14

    主题

    2696

    帖子

    0

    金牌会员

    Rank: 6Rank: 6

    积分
    4656
    最后登录
    2025-8-31
    发表于 2022-8-29 08:49:14 | 显示全部楼层
    楼主很强大,学习了,研究研究
    哎...今天够累的,签到来了~
    回复 支持 反对

    使用道具 举报

  • TA的每日心情
    慵懒
    2025-8-6 11:04
  • 签到天数: 541 天

    连续签到: 1 天

    [LV.9]以坛为家II

    80

    主题

    2595

    帖子

    0

    金牌会员

    Rank: 6Rank: 6

    积分
    8356
    最后登录
    2025-8-7
    发表于 2022-8-31 07:55:41 来自手机 | 显示全部楼层
    学习了     
    回复 支持 反对

    使用道具 举报

  • TA的每日心情
    开心
    2022-1-4 14:25
  • 签到天数: 1 天

    连续签到: 1 天

    [LV.1]初来乍到

    0

    主题

    176

    帖子

    0

    高级会员

    Rank: 4

    积分
    734
    最后登录
    2025-8-28
    发表于 2023-1-10 15:26:10 | 显示全部楼层
    学习了
    每天登陆学习一下
    回复

    使用道具 举报

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

    本版积分规则

    关闭

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

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

    GMT+8, 2025-9-1 02:08 , Processed in 0.094345 second(s), 24 queries , MemCache On.

    Powered by Discuz! X3.4

    Copyright © 2001-2024, Tencent Cloud.

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