在线时间897 小时
UID3067179
注册时间2014-10-23
NXP金币2776
TA的每日心情 | 开心 昨天 08:27 |
---|
签到天数: 1510 天 连续签到: 12 天 [LV.Master]伴坛终老
版主
  
- 积分
- 8758
- 最后登录
- 2025-8-31
|
本帖最后由 TLLED 于 2022-8-26 11:32 编辑
测试下板子上的CAN通信部分,测试程序还是用原厂开发板的例程
一、电路部分
DIY的这块板子使用的和原厂接口有点不一样,我使用的接口如下:
二、程序部分
2.1、代码使用 MCUXpresso IDE软件导入SDK例程
2.2、主程序 - /*
- * Copyright (c) 2016, Freescale Semiconductor, Inc.
- * Copyright 2016-2021 NXP
- * All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
- #include "fsl_debug_console.h"
- #include "fsl_mcan.h"
- #include "pin_mux.h"
- #include "board.h"
- #include "stdlib.h"
- #include <stdbool.h>
- /*******************************************************************************
- * Definitions
- ******************************************************************************/
- #define USE_CANFD (1U)
- /*
- * CAN_DATASIZE DLC BYTES_IN_MB
- * 8 8 kMCAN_8ByteDatafield
- * 12 9 kMCAN_12ByteDatafield
- * 16 10 kMCAN_16ByteDatafield
- * 20 11 kMCAN_20ByteDatafield
- * 24 12 kMCAN_24ByteDatafield
- * 32 13 kMCAN_32ByteDatafield
- * 48 14 kMCAN_48ByteDatafield
- * 64 15 kMCAN_64ByteDatafield
- *
- * CAN data size (pay load size), DLC and Bytes in Message buffer must align.
- *
- */
- #define DLC (15)
- #define BYTES_IN_MB kMCAN_64ByteDatafield
- /* If not define USE_CANFD or define it 0, CAN_DATASIZE should be 8. */
- #define CAN_DATASIZE (64U)
- /* If user need to auto execute the improved timming configuration. */
- #define USE_IMPROVED_TIMING_CONFIG (1U)
- #define EXAMPLE_MCAN_IRQHandler CAN0_IRQ0_IRQHandler
- #define EXAMPLE_MCAN_IRQn CAN0_IRQ0_IRQn
- #define EXAMPLE_MCAN CAN0
- #define MCAN_CLK_FREQ CLOCK_GetMCanClkFreq()
- #define STDID_OFFSET (18U)
- #define MSG_RAM_BASE 0x04000000U
- #define STD_FILTER_OFS 0x0
- #define RX_FIFO0_OFS 0x10U
- #define TX_BUFFER_OFS 0x20U
- #define MSG_RAM_SIZE (TX_BUFFER_OFS + 8 + CAN_DATASIZE)
- /*******************************************************************************
- * Prototypes
- ******************************************************************************/
- /*******************************************************************************
- * Variables
- ******************************************************************************/
- volatile bool txComplete = false;
- volatile bool rxComplete = false;
- mcan_tx_buffer_frame_t txFrame;
- mcan_rx_buffer_frame_t rxFrame;
- uint8_t tx_data[CAN_DATASIZE];
- uint8_t rx_data[CAN_DATASIZE];
- mcan_handle_t mcanHandle;
- mcan_buffer_transfer_t txXfer;
- mcan_fifo_transfer_t rxXfer;
- uint32_t txIdentifier;
- uint32_t rxIdentifier;
- #ifndef MSG_RAM_BASE
- SDK_ALIGN(uint8_t msgRam[MSG_RAM_SIZE], 1U << CAN_MRBA_BA_SHIFT);
- #else
- #define msgRam MSG_RAM_BASE
- #endif
- /*******************************************************************************
- * Code
- ******************************************************************************/
- /*!
- * @brief MCAN Call Back function
- */
- static void mcan_callback(CAN_Type *base, mcan_handle_t *handle, status_t status, uint32_t result, void *userData)
- {
- switch (status)
- {
- case kStatus_MCAN_RxFifo0Idle:
- {
- rxComplete = true;
- }
- break;
- case kStatus_MCAN_TxIdle:
- {
- txComplete = true;
- }
- break;
- default:
- break;
- }
- }
- /*!
- * @brief Main function
- */
- int main(void)
- {
- mcan_config_t mcanConfig;
- mcan_frame_filter_config_t rxFilter;
- mcan_std_filter_element_config_t stdFilter;
- mcan_rx_fifo_config_t rxFifo0;
- mcan_tx_buffer_config_t txBuffer;
- uint8_t node_type;
- uint8_t numMessage = 0;
- uint8_t cnt = 0;
- /* Initialize board hardware. */
- /* attach 12 MHz clock to FLEXCOMM0 (debug console) */
- CLOCK_SetClkDiv(kCLOCK_DivFlexcom0Clk, 0u, false);
- CLOCK_SetClkDiv(kCLOCK_DivFlexcom0Clk, 1u, true);
- CLOCK_AttachClk(BOARD_DEBUG_UART_CLK_ATTACH);
- /* Set MCAN clock 100Mhz/5=20MHz. */
- CLOCK_SetClkDiv(kCLOCK_DivCanClk, 5U, true);
- CLOCK_AttachClk(kMCAN_DIV_to_MCAN);
- BOARD_InitPins();
- BOARD_BootClockPLL100M();
- BOARD_InitDebugConsole();
- do
- {
- PRINTF("Please select local node as A or B:\r\n");
- PRINTF("Note: Node B should start first.\r\n");
- PRINTF("Node:");
- node_type = GETCHAR();
- PRINTF("%c", node_type);
- PRINTF("\r\n");
- } while ((node_type != 'A') && (node_type != 'B') && (node_type != 'a') && (node_type != 'b'));
- /* Select mailbox ID. */
- if ((node_type == 'A') || (node_type == 'a'))
- {
- txIdentifier = 0x321U;
- rxIdentifier = 0x123U;
- }
- else
- {
- txIdentifier = 0x123U;
- rxIdentifier = 0x321U;
- }
- /* Get MCAN module default Configuration. */
- /*
- * mcanConfig.baudRate = 500000U;
- * mcanConfig.baudRateFD = 2000000U;
- * mcanConfig.enableCanfdNormal = false;
- * mcanConfig.enableCanfdSwitch = false;
- * mcanConfig.enableLoopBackInt = false;
- * mcanConfig.enableLoopBackExt = false;
- * mcanConfig.enableBusMon = false;
- */
- MCAN_GetDefaultConfig(&mcanConfig);
- #if (defined(USE_CANFD) && USE_CANFD)
- /* Enable Bit Rate Switch to make baudRateD make sense.*/
- mcanConfig.enableCanfdSwitch = true;
- #endif
- #if (defined(USE_IMPROVED_TIMING_CONFIG) && USE_IMPROVED_TIMING_CONFIG)
- mcan_timing_config_t timing_config;
- memset(&timing_config, 0, sizeof(timing_config));
- #if (defined(USE_CANFD) && USE_CANFD)
- if (MCAN_FDCalculateImprovedTimingValues(mcanConfig.baudRateA, mcanConfig.baudRateD, MCAN_CLK_FREQ, &timing_config))
- {
- /* Update the improved timing configuration*/
- memcpy(&(mcanConfig.timingConfig), &timing_config, sizeof(mcan_timing_config_t));
- }
- else
- {
- PRINTF("No found Improved Timing Configuration. Just used default configuration\r\n\r\n");
- }
- #else
- if (MCAN_CalculateImprovedTimingValues(mcanConfig.baudRateA, MCAN_CLK_FREQ, &timing_config))
- {
- /* Update the improved timing configuration*/
- memcpy(&(mcanConfig.timingConfig), &timing_config, sizeof(mcan_timing_config_t));
- }
- else
- {
- PRINTF("No found Improved Timing Configuration. Just used default configuration\r\n\r\n");
- }
- #endif
- #endif
- MCAN_Init(EXAMPLE_MCAN, &mcanConfig, MCAN_CLK_FREQ);
- /* Create MCAN handle structure and set call back function. */
- MCAN_TransferCreateHandle(EXAMPLE_MCAN, &mcanHandle, mcan_callback, NULL);
- /* Set Message RAM base address and clear to avoid BEU/BEC error. */
- MCAN_SetMsgRAMBase(EXAMPLE_MCAN, (uint32_t)msgRam);
- memset((void *)msgRam, 0, MSG_RAM_SIZE * sizeof(uint8_t));
- /* STD filter config. */
- rxFilter.address = STD_FILTER_OFS;
- rxFilter.idFormat = kMCAN_FrameIDStandard;
- rxFilter.listSize = 1U;
- rxFilter.nmFrame = kMCAN_reject0;
- rxFilter.remFrame = kMCAN_rejectFrame;
- MCAN_SetFilterConfig(EXAMPLE_MCAN, &rxFilter);
- stdFilter.sfec = kMCAN_storeinFifo0;
- /* Classic filter mode, only filter matching ID. */
- stdFilter.sft = kMCAN_classic;
- stdFilter.sfid1 = rxIdentifier;
- stdFilter.sfid2 = 0x7FFU;
- MCAN_SetSTDFilterElement(EXAMPLE_MCAN, &rxFilter, &stdFilter, 0);
- /* RX fifo0 config. */
- rxFifo0.address = RX_FIFO0_OFS;
- rxFifo0.elementSize = 1U;
- rxFifo0.watermark = 0;
- rxFifo0.opmode = kMCAN_FifoBlocking;
- rxFifo0.datafieldSize = kMCAN_8ByteDatafield;
- #if (defined(USE_CANFD) && USE_CANFD)
- rxFifo0.datafieldSize = BYTES_IN_MB;
- #endif
- MCAN_SetRxFifo0Config(EXAMPLE_MCAN, &rxFifo0);
- /* TX buffer config. */
- memset(&txBuffer, 0, sizeof(txBuffer));
- txBuffer.address = TX_BUFFER_OFS;
- txBuffer.dedicatedSize = 1U;
- txBuffer.fqSize = 0;
- txBuffer.datafieldSize = kMCAN_8ByteDatafield;
- #if (defined(USE_CANFD) && USE_CANFD)
- txBuffer.datafieldSize = BYTES_IN_MB;
- #endif
- MCAN_SetTxBufferConfig(EXAMPLE_MCAN, &txBuffer);
- /* Finish software initialization and enter normal mode, synchronizes to
- CAN bus, ready for communication */
- MCAN_EnterNormalMode(EXAMPLE_MCAN);
- if ((node_type == 'A') || (node_type == 'a'))
- {
- PRINTF("Press any key to trigger one-shot transmission\r\n\r\n");
- }
- else
- {
- PRINTF("Start to Wait data from Node A\r\n\r\n");
- }
- while (1)
- {
- if ((node_type == 'A') || (node_type == 'a'))
- {
- GETCHAR();
- /* Config TX frame data. */
- memset(tx_data, 0, sizeof(uint8_t) * CAN_DATASIZE);
- for (cnt = 0; cnt < CAN_DATASIZE; cnt++)
- {
- tx_data[cnt] = cnt;
- }
- tx_data[0] += numMessage++;
- txFrame.xtd = kMCAN_FrameIDStandard;
- txFrame.rtr = kMCAN_FrameTypeData;
- txFrame.fdf = 0;
- txFrame.brs = 0;
- txFrame.dlc = 8U;
- txFrame.id = txIdentifier << STDID_OFFSET;
- txFrame.data = tx_data;
- txFrame.size = CAN_DATASIZE;
- #if (defined(USE_CANFD) && USE_CANFD)
- txFrame.fdf = 1;
- txFrame.brs = 1;
- txFrame.dlc = DLC;
- #endif
- txXfer.frame = &txFrame;
- txXfer.bufferIdx = 0;
- MCAN_TransferSendNonBlocking(EXAMPLE_MCAN, &mcanHandle, &txXfer);
- while (!txComplete)
- {
- }
- txComplete = false;
- /* Start receive data through Rx FIFO 0. */
- memset(rx_data, 0, sizeof(uint8_t) * CAN_DATASIZE);
- /* the MCAN engine can't auto to get rx payload size, we need set it. */
- rxFrame.size = CAN_DATASIZE;
- rxXfer.frame = &rxFrame;
- MCAN_TransferReceiveFifoNonBlocking(EXAMPLE_MCAN, 0, &mcanHandle, &rxXfer);
- /* Wait until message received. */
- while (!rxComplete)
- {
- }
- rxComplete = false;
- /* After call the API of rMCAN_TransferReceiveFifoNonBlocking success, we can
- * only get a point (rxFrame.data) to the fifo reading entrance.
- * Copy the received frame data from the FIFO by the pointer(rxFrame.data). */
- memcpy(rx_data, rxFrame.data, rxFrame.size);
- PRINTF("Received Frame ID: 0x%x\r\n", rxFrame.id >> STDID_OFFSET);
- PRINTF("Received Frame DATA: ");
- cnt = 0;
- while (cnt < rxFrame.size)
- {
- PRINTF("0x%x ", rx_data[cnt++]);
- }
- PRINTF("\r\n");
- PRINTF("Press any key to trigger the next transmission!\r\n\r\n");
- }
- else
- {
- memset(rx_data, 0, sizeof(uint8_t) * CAN_DATASIZE);
- /* the MCAN engine can't auto to get rx payload size, we need set it. */
- rxFrame.size = CAN_DATASIZE;
- rxXfer.frame = &rxFrame;
- MCAN_TransferReceiveFifoNonBlocking(EXAMPLE_MCAN, 0, &mcanHandle, &rxXfer);
- while (!rxComplete)
- {
- }
- rxComplete = false;
- /* After call the API of rMCAN_TransferReceiveFifoNonBlocking success, we can
- * only get a point (rxFrame.data) to the fifo reading entrance.
- * Copy the received frame data from the FIFO by the pointer(rxFrame.data). */
- memcpy(rx_data, rxFrame.data, rxFrame.size);
- PRINTF("Received Frame ID: 0x%x\r\n", rxFrame.id >> STDID_OFFSET);
- PRINTF("Received Frame DATA: ");
- cnt = 0;
- while (cnt < rxFrame.size)
- {
- PRINTF("0x%x ", rx_data[cnt++]);
- }
- PRINTF("\r\n");
- /* Copy received frame data to tx frame. */
- memcpy(tx_data, rx_data, CAN_DATASIZE);
- txFrame.xtd = rxFrame.xtd;
- txFrame.rtr = rxFrame.rtr;
- txFrame.fdf = rxFrame.fdf;
- txFrame.brs = rxFrame.brs;
- txFrame.dlc = rxFrame.dlc;
- txFrame.id = txIdentifier << STDID_OFFSET;
- txFrame.data = tx_data;
- txFrame.size = rxFrame.size;
- txXfer.frame = &txFrame;
- txXfer.bufferIdx = 0;
- MCAN_TransferSendNonBlocking(EXAMPLE_MCAN, &mcanHandle, &txXfer);
- while (!txComplete)
- {
- }
- txComplete = false;
- PRINTF("Wait Node A to trigger the next transmission!\r\n\r\n");
- }
- }
- }
复制代码
2.3、程序修改部分
修改pinmux.c和pinmux.h代码,将CAN通信端口映射到DIY的板卡端口
pinmux.c
pinmux.h
三、测试程序
3.1、这个代码是需要两个板子之间CAN通信测试的例程
3.2、手里只焊接了一块板子,这先测试CAN端口收发功能,使用CAN卡和开发板之间通信,硬件连接
3.3、下载程序后运行
CAN通信波特率:500kbps
串口输出内容
CAN卡发送和接收的内容
通过上面的测试,CAN通信收发功能是正常的,数据和测试例程的数据格式不一致,数据没有参考性。
|
|