在线时间1147 小时
UID3124330
注册时间2015-11-26
NXP金币849
TA的每日心情 | 开心 2019-3-5 08:47 |
---|
签到天数: 1 天 [LV.1]初来乍到
金牌会员
- 积分
- 7799
- 最后登录
- 2024-4-18
|
本帖最后由 jundao721 于 2023-6-3 20:05 编辑
今天测试了一下RT1176的FDCAN通讯,这种通讯方式应用挺多的。具体怎么配置波特率参考使用手册即可,默认帧波特率为1Mbps,数据波特率为2Mbps,这里暂时不讨论,以测试为主。板子上使用的是TJA1044GT/3,原理图如图1所示:
图1
本来重新做板以后,想着不用飞线了,测试的时候才发现采购的器件跟原理图的器件不一样,所以还是得飞一下到3.3V。如图2所示:
图2
官方的SDK使用的是Callback方式,源程序不太符合本人的读代码方式,对源程序进行了部分修改,主要配置如下:
我使用的是CAN2,官方是CAN3,所以引脚和宏定义都需要修改,引脚修改如下:
- IOMUXC_SetPinMux(
- IOMUXC_GPIO_AD_00_FLEXCAN2_TX, /* IOMUXC_GPIO_AD_00 is configured as FLEXCAN2_TX */
- 1U);
- IOMUXC_SetPinMux(
- IOMUXC_GPIO_AD_01_FLEXCAN2_RX, /* IOMUXC_GPIO_AD_01 is configured as FLEXCAN2_RX */
- 1U);
- IOMUXC_SetPinConfig(
- IOMUXC_GPIO_AD_00_FLEXCAN2_TX,
- 0x02U);
- IOMUXC_SetPinConfig(
- IOMUXC_GPIO_AD_01_FLEXCAN2_RX,
- 0x02U);
复制代码- #define EXAMPLE_CAN CAN2
- #define EXAMPLE_FLEXCAN_IRQn CAN2_IRQn
- #define EXAMPLE_FLEXCAN_IRQHandler CAN2_IRQHandler
复制代码- #define EXAMPLE_CAN_CLK_FREQ ((CLOCK_GetRootClockFreq(kCLOCK_Root_Can2) / 100000U) * 100000U)
复制代码
其中需要创建callback函数
- /* Create FlexCAN handle structure and set call back function. */
- FLEXCAN_TransferCreateHandle(EXAMPLE_CAN, &flexcanHandle, flexcan_callback, NULL); //使能回调函数
复制代码
要实现的功能是每隔1S发送一帧数据,发送部分:
- frame.id = FLEXCAN_ID_STD(txIdentifier);
- frame.format = (uint8_t)kFLEXCAN_FrameFormatStandard;
- frame.type = (uint8_t)kFLEXCAN_FrameTypeData;
复制代码
接收部分callback函数不用修改,处理部分修改一下:
- /* Start receive data through Rx Message Buffer. */
- rxXfer.mbIdx = (uint8_t)RX_MESSAGE_BUFFER_NUM;
- #if (defined(USE_CANFD) && USE_CANFD)
- rxXfer.framefd = &frame;
- (void)FLEXCAN_TransferFDReceiveNonBlocking(EXAMPLE_CAN, &flexcanHandle, &rxXfer);
- #else
- rxXfer.frame = &frame;
- (void)FLEXCAN_TransferReceiveNonBlocking(EXAMPLE_CAN, &flexcanHandle, &rxXfer);
- #endif
- (void)FLEXCAN_ReadFDRxMb(EXAMPLE_CAN, RX_MESSAGE_BUFFER_NUM, &rxFrame);
- /* Wait until Rx MB full. */
- <blockquote>while (!rxComplete)
复制代码
OK,回调函数方式基本上就修改完了,测试结果如图3和图4所示
图3
图3
图4
图4
传统的是中断方式,接收中断,每隔1S发送一帧数据。这部分就得自己写中断函数了。首先注释掉创建callback函数,使能中断:
- FLEXCAN_EnableMbInterrupts(EXAMPLE_CAN, flag << RX_MESSAGE_BUFFER_NUM);
- (void)EnableIRQ(EXAMPLE_FLEXCAN_IRQn);
复制代码
中断函数参考是这样的:
- void EXAMPLE_FLEXCAN_IRQHandler(void)
- {
- #if (defined(FSL_FEATURE_FLEXCAN_HAS_EXTENDED_FLAG_REGISTER)) && (FSL_FEATURE_FLEXCAN_HAS_EXTENDED_FLAG_REGISTER > 0)
- uint64_t flag = 1U;
- #else
- uint32_t flag = 1U;
- #endif
- /* If new data arrived. */
- if (0U != FLEXCAN_GetMbStatusFlags(EXAMPLE_CAN, flag << RX_MESSAGE_BUFFER_NUM))
- {
- FLEXCAN_ClearMbStatusFlags(EXAMPLE_CAN, flag << RX_MESSAGE_BUFFER_NUM);
- #if (defined(USE_CANFD) && USE_CANFD)
- (void)FLEXCAN_ReadFDRxMb(EXAMPLE_CAN, RX_MESSAGE_BUFFER_NUM, &rxFrame);
- #else
- (void)FLEXCAN_ReadRxMb(EXAMPLE_CAN, RX_MESSAGE_BUFFER_NUM, &rxFrame);
- #endif
- rxComplete = true;
- }
- SDK_ISR_EXIT_BARRIER;
- }
复制代码
发送函数需要修改一下:
- (void)FLEXCAN_TransferFDSendBlocking(EXAMPLE_CAN, TX_MESSAGE_BUFFER_NUM, &frame);
复制代码
接收处理部分:
- if(rxComplete==true)
- {
- for ( i = 0; i < DWORD_IN_MB; i++)
- {
- rx_data[i]= rxFrame.dataWord[i];
- }
- rxComplete = false;
- }
复制代码
测试结果如图5和图6所示:
图5
图5
图6
图6
OK,两种方式测试完成。
|
|