KW45B41Z-EVK: CAN 变速器 恩智浦支持人员你好, 目前我正在开发恩智浦 KW45B41Z-EVK 板。我的目标是从 BLE 板上传输 CAN 帧。我曾尝试使用 SDK 示例,但它不能提供 CAN 的直接接口。 我无法传输 CAN 帧。仅供参考,我正在使用 Technica CAN 捕获模块。 期待您的及时帮助。 所以,我开发了一个自定义应用程序,以下是代码供你参考: #include"fsl_debug_console.h" #include"fsl_flexcan.h" #include "board.h" #include"app.h" /******************************************************************************* * 定义 ******************************************************************************/ /* 修正 MISRA_C-2012 第 17.7 条规则。*/ #define LOG_INFO (void)PRINTF #ifndef USE_CANFD #define USE_CANFD (1) #endif #ifndef EXAMPLE_CAN_BIT_RATE #define EXAMPLE_CAN_BIT_RATE (500000U) #endif #ifndef EXAMPLE_CAN_BIT_RATE_FD #define EXAMPLE_CAN_BIT_RATE_FD (2000000U) #endif #define USE_PHY_TJA1152 (1) #if (defined(USE_CANFD)&& USE_CANFD) /* * DWORD_IN_MB DLC BYTES_IN_MB 最大 MB 数 * 2 8 kFLEXCAN_8BperMB 32(1 个 RAM 块) 64(2 个 RAM 块) 96(3 个 RAM 块) * 4 10 kFLEXCAN_16BperMB 21(1 个 RAM 块) 42(2 个 RAM 块) 63(3 个 RAM 块) * 8 13 kFLEXCAN_32BperMB 12(1 个 RAM 块) 24(2 个 RAM 块) 36(3 个 RAM 块) * 16 15 kFLEXCAN_64BperMB 7(1 个 RAM 块) 14(2 个 RAM 块) 21(3 个 RAM 块) * * 每个消息缓冲区中的 Dword,以字节为单位的数据长度,有效负载大小必须一致, * 信息缓冲区的限制与每个有效载荷配置相对应: */ #define DWORD_IN_MB (16) #define DLC (15) #define BYTES_IN_MB kFLEXCAN_64BperMB #else #define DLC (8) #endif /******************************************************************************* * 原型 ******************************************************************************/ /******************************************************************************* * 变量 ******************************************************************************/ flexcan_handle_t flexcanHandle; volatile bool txComplete = false; flexcan_mb_transfer_t txXfer; #if (defined(USE_CANFD)&& USE_CANFD) flexcan_fd_frame_t frame; #else flexcan_frame_t frame; #endif static const uint32_t kFlexcanTxId = 0x123U; #if (defined(USE_CANFD)&& USE_CANFD) static const uint8_t kPayloadSize = 64U; static const uint8_t kFrameLength = (uint8_t)DLC; #else static const uint8_t kPayloadSize = 8U; static const uint8_t kFrameLength = (uint8_t)DLC; #endif /******************************************************************************* * 代码 ******************************************************************************/ /*! * CAN 收发器简要配置功能 */ static void FLEXCAN_PHY_Config(void) { /* 始终确保收发器待机引脚处于驱动状态。*/ GPIO_PortSet(EXAMPLE_STB_RGPIO, 1u<< EXAMPLE_STB_RGPIO_PIN); #if (defined(USE_PHY_TJA1152)&& USE_PHY_TJA1152) /* 初始化 TJA1152。*/ /* STB=H,配置 CAN 信息将通过 TXD 引脚从本地主机发送。*/ /* 必须传输带有标准标识符 0x555 的经典 CAN 报文 在 TJA1152 確認之前,本地主機控制器將 * 儲存在 TJA1152 中。 * 自动检测比特率。不要设置 frame.brs = 1U,以保持标称值 * CANFD 帧数据阶段的比特率。*/ frame.id = FLEXCAN_ID_STD(0x555); frame.format = (uint8_t)kFLEXCAN_FrameFormatStandard; frame.type = (uint8_t)kFLEXCAN_FrameTypeData; frame.length = 0U; txXfer.mbIdx = (uint8_t)TX_MESSAGE_BUFFER_NUM; #if (defined(USE_CANFD)&& USE_CANFD) txXfer.framefd =&frame; (void)FLEXCAN_TransferFDSendNonBlocking(EXAMPLE_CAN,&flexcanHandle,&txXfer); #else txXfer.frame =&frame; (void)FLEXCAN_TransferSendNonBlocking(EXAMPLE_CAN,&flexcanHandle,&txXfer); #endif while (!txComplete) { }; txComplete = false; /* 配置欺骗保护。*/ /* 在传输白名单中添加 0x321 和 0x123。*/ frame.id = FLEXCAN_ID_EXT(0x18DA00F1); frame.format = (uint8_t)kFLEXCAN_FrameFormatExtend; frame.type = (uint8_t)kFLEXCAN_FrameTypeData; frame.length = 6U; #if (defined(USE_CANFD)&& USE_CANFD) frame.dataWord[0]= CAN_WORD_DATA_BYTE_0(0x10) | CAN_WORD_DATA_BYTE_1(0x00) | CAN_WORD_DATA_BYTE_2(0x33) | CAN_WORD_DATA_1(0x00) | CAN_WORD_DATA_BYTE_2(0x33) CAN_WORD_DATA_BYTE_3(0x21); frame.dataWord[1]= CAN_WORD_DATA_BYTE_4(0x11) | CAN_WORD_DATA_BYTE_5(0x23); (void)FLEXCAN_TransferFDSendNonBlocking(EXAMPLE_CAN,&flexcanHandle,&txXfer); #else frame.dataWord0 = CAN_WORD0_DATA_BYTE_0(0x10) | CAN_WORD0_DATA_BYTE_1(0x00) | CAN_WORD0_DATA_BYTE_2(0x33) | CAN_WORD0_DATA_BYTE_2(0x33) | CAN_WORD0_DATA_BYTE_2(0x33) CAN_WORD0_DATA_BYTE_3(0x21); frame.dataWord1 = CAN_WORD1_DATA_BYTE_4(0x11) | CAN_WORD1_DATA_BYTE_5(0x23); (void)FLEXCAN_TransferSendNonBlocking(EXAMPLE_CAN,&flexcanHandle,&txXfer); #endif while (!txComplete) { }; txComplete = false; /* 配置命令信息 ID。*/ /* 只接受本地重新配置。保持 CONFIG_ID 为默认值 0x18DA00F1。*/ frame.length = 5U; #if (defined(USE_CANFD)&& USE_CANFD) frame.dataWord[0]= CAN_WORD_DATA_BYTE_0(0x60) | CAN_WORD_DATA_BYTE_1(0x98) | CAN_WORD_DATA_BYTE_2(0xDA) | CAN_WORD_DATA_1(0x98) | CAN_WORD_DATA_BYTE_2(0xDA) CAN_WORD_DATA_BYTE_3(0x00); frame.dataWord[1]= CAN_WORD_DATA_BYTE_4(0xF1); (void)FLEXCAN_TransferFDSendNonBlocking(EXAMPLE_CAN,&flexcanHandle,&txXfer); #else frame.dataWord0 = CAN_WORD0_DATA_BYTE_0(0x60) | CAN_WORD0_DATA_BYTE_1(0x98) | CAN_WORD0_DATA_BYTE_2(0xDA) | CAN_WORD0_DATA_BYTE_2(0xDA) CAN_WORD0_DATA_BYTE_3(0x00); frame.dataWord1 = CAN_WORD1_DATA_BYTE_4(0xF1); (void)FLEXCAN_TransferSendNonBlocking(EXAMPLE_CAN,&flexcanHandle,&txXfer); #endif while (!txComplete) { }; txComplete = false; /* 离开配置模式。*/ /* 仅配置到易失性存储器中。*/ frame.length = 8U; #if (defined(USE_CANFD)&& USE_CANFD) frame.dataWord[0]= CAN_WORD_DATA_BYTE_0(0x71) | CAN_WORD_DATA_BYTE_1(0x02) | CAN_WORD_DATA_BYTE_2(0x03) | CAN_WORD_DATA_2(0x03) CAN_WORD_DATA_BYTE_3(0x04); frame.dataWord[1]= CAN_WORD_DATA_BYTE_4(0x05) | CAN_WORD_DATA_BYTE_5(0x06) | CAN_WORD_DATA_BYTE_6(0x07) | CAN_WORD_DATA_BYTE_5(0x06) | CAN_WORD_DATA_BYTE_6(0x07) CAN_WORD_DATA_BYTE_7(0x08); (void)FLEXCAN_TransferFDSendNonBlocking(EXAMPLE_CAN,&flexcanHandle,&txXfer); #else frame.dataWord0 = CAN_WORD0_DATA_BYTE_0(0x71) | CAN_WORD0_DATA_BYTE_1(0x02) | CAN_WORD0_DATA_BYTE_2(0x03) | CAN_WORD0_DATA_BYTE_1(0x03) | CAN_WORD0_DATA_BYTE_2(0x03) CAN_WORD0_DATA_BYTE_3(0x04); frame.dataWord1 = CAN_WORD1_DATA_BYTE_4(0x05) | CAN_WORD1_DATA_BYTE_5(0x06) | CAN_WORD1_DATA_BYTE_6(0x07) | CAN_WORD1_DATA_6(0x07) CAN_WORD1_DATA_BYTE_7(0x08); (void)FLEXCAN_TransferSendNonBlocking(EXAMPLE_CAN,&flexcanHandle,&txXfer); #endif while (!txComplete) { }; txComplete = false; LOG_INFO("Initialize TJA1152 successfully!\r\n\rn"); /* 初始化 TJA1152 结束。*/ #endif /* 版本收发器待机状态以驱动 CANH/CANL。*/ GPIO_PortClear(EXAMPLE_STB_RGPIO, 1u<< EXAMPLE_STB_RGPIO_PIN); } /*! * 简短的 FlexCAN 回电功能 */ static FLEXCAN_CALLBACK(flexcan_callback) { LOG_INFO("status:%d\n", status); 开关 { 情况 kStatus_FLEXCAN_TxIdle: 如果 (TX_MESSAGE_BUFFER_NUM == result) { txComplete = true; } 打破; 默认: 打破; } } /*! * @brief 主要功能 */ int main(void) { flexcan_config_t flexcanConfig; uint8_t txCounter = 0U; /* 初始化板硬件。*/ BOARD_InitHardware(); LOG_INFO("********* FLEXCAN Continuous TX EXAMPLE *********\r\n"); LOG_INFO(" Message format:Standard (11 bit id)/r\n"); #if (defined(USE_CANFD)&& USE_CANFD) LOG_INFO(" Frame type : CAN FD with BRS\r\n"); LOG_INFO(" Nominal/Data bit rates:%u /%u bps\r\n", EXAMPLE_CAN_BIT_RATE, EXAMPLE_CAN_BIT_RATE_FD); LOG_INFO (" 有效负载长度:%u 字节\ r\n ", KPayloadSize); #else LOG_INFO(" Frame type : Classical CAN\r\n"); LOG_INFO(" Bit rate :%u bps\r\n", EXAMPLE_CAN_BIT_RATE); LOG_INFO (" 有效负载长度:%u 字节\ r\n ", KPayloadSize); #endif LOG_INFO(" Message buffer%d used for Tx.\r\n", TX_MESSAGE_BUFFER_NUM); LOG_INFO(" Interrupt Mode: Enabled\r\n"); LOG_INFO(" Operation Mode: Continuous transmit\r\n"); LOG_INFO("*********************************************\r\n\r\n"); LOG_INFO("Starting continuous CAN transmissions on ID 0x%3x\r\n\r\n", kFlexcanTxId); /* 获取 FlexCAN 模块默认配置。*/ /* * 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; */ FLEXCAN_GetDefaultConfig(&flexcanConfig); flexcanConfig.bitRate = EXAMPLE_CAN_BIT_RATE; flexcanConfig.disableSelfReception = true; #if (defined(USE_CANFD)&& USE_CANFD) flexcanConfig.bitRateFD = EXAMPLE_CAN_BIT_RATE_FD; #endif #if defined(EXAMPLE_CAN_CLK_SOURCE) flexcanConfig.clksrc=EXAMPLE_CAN_CLK_SOURCE; #endif /* 如果需要特殊的量子设置,请设置定时参数。*/ #if (defined(SET_CAN_QUANTUM)&& SET_CAN_QUANTUM) flexcanConfig.timingConfig.phaseSeg1 = PSEG1; flexcanConfig.timingConfig.phaseSeg2 = PSEG2; flexcanConfig.timingConfig.propSeg = PROPSEG; #if (defined(FSL_FEATURE_FLEXCAN_HAS_FLEXIBLE_DATA_RATE)&& FSL_FEATURE_FLEXCAN_HAS_FLEXIBLE_DATA_RATE) flexcanConfig.timingConfig.fphaseSeg1 = FPSEG1; flexcanConfig.timingConfig.fphaseSeg2 = FPSEG2; flexcanConfig.timingConfig.fpropSeg = FPROPSEG; #endif #endif #if (defined(USE_IMPROVED_TIMING_CONFIG)&& USE_IMPROVED_TIMING_CONFIG) flexcan_timing_config_t timing_config; memset(&timing_config, 0, sizeof(flexcan_timing_config_t)); #if (defined(USE_CANFD)&& USE_CANFD) 如果(FLEXCAN_FDCalculateImprovedTimingValues(EXAMPLE_CAN, flexcanConfig.bitRate、flexcanConfig.bitRateFD、 EXAMPLE_CAN_CLK_FREQ,&timing_config)) { /* 更新改进后的定时配置*/ memcpy(&(flexcanConfig.timingConfig),&timing_config, sizeof(flexcan_timing_config_t)); } 不然 { LOG_INFO("未找到改进的定时配置。只是使用了默认的 configuration\r\n\r\n" ); } #else 如果(FLEXCAN_CalculateImprovedTimingValues(EXAMPLE_CAN, flexcanConfig.bitRate、EXAMPLE_CAN_CLK_FREQ,&timing_config)) { /* 更新改进后的定时配置*/ memcpy(&(flexcanConfig.timingConfig),&timing_config, sizeof(flexcan_timing_config_t)); } 不然 { LOG_INFO("未找到改进的定时配置。只是使用了默认的 configuration\r\n\r\n" ); } #endif #endif #if (defined(USE_CANFD)&& USE_CANFD) FLEXCAN_FDInit(EXAMPLE_CAN,&flexcanConfig, EXAMPLE_CAN_CLK_FREQ, BYTES_IN_MB, true); #else FLEXCAN_Init(EXAMPLE_CAN,&flexcanConfig,EXAMPLE_CAN_CLK_FREQ); #endif /* 创建 FlexCAN 句柄结构并设置回调函数。*/ FLEXCAN_TransferCreateHandle(EXAMPLE_CAN,&flexcanHandle, flexcan_callback, NULL); /* 设置 Tx 信息缓冲区。*/ #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 /* 配置 CAN 收发器 */ FLEXCAN_PHY_Config(); 当(true)时 { frame.id = FLEXCAN_ID_STD(kFlexcanTxId); frame.format = (uint8_t)kFLEXCAN_FrameFormatStandard; frame.type = (uint8_t)kFLEXCAN_FrameTypeData; frame.length = kFrameLength; #if (defined(USE_CANFD)&& USE_CANFD) frame.brs = 1U; frame.edl = 1U; for (uint8_t wordIdx = 0U; wordIdx< DWORD_IN_MB; wordIdx++) { uint8_t baseValue = (uint8_t)(wordIdx * 4U); frame.dataWord[wordIdx] = CAN_WORD_DATA_BYTE_0((uint32_t)txCounter + baseValue)| CAN_WORD_DATA_BYTE_1(0x55U + baseValue) | CAN_WORD_DATA_BYTE_1(0x55U + baseValue) CAN_WORD_DATA_BYTE_2(0xAAU + baseValue) | CAN_WORD_DATA_BYTE_2(0xAAU + baseValue) | CAN_WORD_DATA_BYTE_3(0xFFU - baseValue); } #else frame.dataWord0 = CAN_WORD0_DATA_BYTE_0(txCounter) | CAN_WORD0_DATA_BYTE_1(0x55U) | CAN_WORD0_DATA_BYTE_1(0x55U) | CAN_WORD0_DATA_BYTE_1(0x55U) CAN_WORD0_DATA_BYTE_2(0xAAU) | CAN_WORD0_DATA_BYTE_3(0xFFU); frame.dataWord1 = CAN_WORD1_DATA_BYTE_4(0x11U) | CAN_WORD1_DATA_BYTE_5(0x22U) | CAN_WORD1_DATA_BYTE_5(0x22U) | CAN_WORD1_DATA_5(0x22U) CAN_WORD1_DATA_BYTE_6(0x33U) | CAN_WORD1_DATA_BYTE_7(0x44U); #endif txXfer.mbIdx = (uint8_t)TX_MESSAGE_BUFFER_NUM; #if (defined(USE_CANFD)&& USE_CANFD) txXfer.framefd =&frame; (void)FLEXCAN_TransferFDSendNonBlocking(EXAMPLE_CAN,&flexcanHandle,&txXfer); #else txXfer.frame =&frame; (void)FLEXCAN_TransferSendNonBlocking(EXAMPLE_CAN,&flexcanHandle,&txXfer); #endif while (!txComplete) { }; txComplete = false; txCounter++; } } Re: KW45B41Z-EVK: CAN Transmission 你好
希望你一切顺利。请说明"不提供与 CAN" 的直接接口是什么意思?
您能否尝试使用示波器或分析仪检查 J10 连接器。
我建议你看看你的板上的 flexcan_interrupt_transfer 示例。
请告诉我您的发现。
顺祝商祺!
里卡多
View full article