NXP RT1060学习总结 - CANFD功能

1、RT1060-CAN FD功能简介

这里使用RT1060系列的1064芯片进行开发,测试板是官方提供的开发板;RT1060系列支持3路CAN功能,CAN1和CAN2只能最为普通的CAN外设,支持CAN2.0,而CAN3支持CAN-FD功能;CAN-FD功能这里就不做详细介绍,百度上很多该方面资料,核心点是普通CAN只能传输8字节数据,而CAN-FD最大支持传输64字节数据。
注意事项:使用CANFD功能的时候,用于测试的CAN工具需要支持CANFD功能。

2、各类宏定义和全局变量

#define EXAMPLE_CAN CAN3								//使用的CAN外设 - CAN3
#define RX_MESSAGE_BUFFER_NUM (10)		//接收邮箱
#define TX_MESSAGE_BUFFER_NUM (9)			//发送邮箱

#define EXAMPLE_CAN_CLK_SOURCE (kFLEXCAN_ClkSrc1)	//CAN时钟

/* 选择60M时钟除以USB1 PLL (480mhz)作为flexcan主时钟源 */
#define FLEXCAN_CLOCK_SOURCE_SELECT (0U)
/* Clock divider for master flexcan clock source */
#define FLEXCAN_CLOCK_SOURCE_DIVIDER (2U)

#define DLC         (15)
#define BYTES_IN_MB kFLEXCAN_64BperMB	//每个消息区选择64字节数据
#define EXAMPLE_CAN_CLK_FREQ ((CLOCK_GetFreq(kCLOCK_Usb1PllClk) / 8) / (FLEXCAN_CLOCK_SOURCE_DIVIDER + 1U))	//时钟频率

flexcan_handle_t flexcanHandle;
volatile bool txComplete = false;			//发送完成标志
volatile bool rxComplete = false;			//接收完成标志
volatile bool wakenUp    = false;			//唤醒标识
flexcan_mb_transfer_t txXfer, rxXfer;	//邮箱
flexcan_fd_frame_t frame;

uint32_t txIdentifier;		//收发ID标识符
uint32_t rxIdentifier;

uint16_t t_Count = 0;	//用于测试

3、CAN FD IO初始化

static void can2_gpio_config(void)
{
	//设置GPIO的时钟
	CLOCK_EnableClock(kCLOCK_Iomuxc);
	
	 //配置IO的复用模式 设置为CAN3的TX和RX功能
	IOMUXC_SetPinMux(IOMUXC_GPIO_AD_B0_14_FLEXCAN3_TX, 1U); 
	IOMUXC_SetPinMux(IOMUXC_GPIO_AD_B0_15_FLEXCAN3_RX, 1U);

	//配置GPIO功能
	IOMUXC_SetPinConfig(IOMUXC_GPIO_AD_B0_14_FLEXCAN3_TX, 0x10B0U); 
	IOMUXC_SetPinConfig(IOMUXC_GPIO_AD_B0_15_FLEXCAN3_RX, 0x10B0U); 
}

4、CAN FD功能配置

void can2_function_config(void)
{
	flexcan_config_t flexcanConfig;					//CAN配置
    flexcan_rx_mb_config_t mbConfig;				//接收邮箱配置
	flexcan_timing_config_t timing_config;		//时间配置
	
	/* FLEXCAN时钟配置 */
    CLOCK_SetMux(kCLOCK_CanMux, FLEXCAN_CLOCK_SOURCE_SELECT);
    CLOCK_SetDiv(kCLOCK_CanDiv, FLEXCAN_CLOCK_SOURCE_DIVIDER);
	
	/* 设置发送和接收的帧ID */
	txIdentifier = 0x321;
    rxIdentifier = 0x123;
	
	/* Get FlexCAN module default Configuration. */
    /*
     * 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.clkSrc = EXAMPLE_CAN_CLK_SOURCE;
	flexcanConfig.bitRate = 500000U;			//这里使用的是**bitRate**,bit位的波特率
	
	memset(&timing_config, 0, sizeof(flexcan_timing_config_t));
	if (FLEXCAN_FDCalculateImprovedTimingValues(EXAMPLE_CAN, flexcanConfig.bitRate, flexcanConfig.bitRateFD,
                                                EXAMPLE_CAN_CLK_FREQ, &timing_config))
    {
        /* 更新修改后的定时配置 */
        memcpy(&(flexcanConfig.timingConfig), &timing_config, sizeof(flexcan_timing_config_t));
    }
	
	FLEXCAN_FDInit(EXAMPLE_CAN, &flexcanConfig, EXAMPLE_CAN_CLK_FREQ, BYTES_IN_MB, true);
	
	/* 创建CAN句柄 并建立回调函数 */
    FLEXCAN_TransferCreateHandle(EXAMPLE_CAN, &flexcanHandle, flexcan_callback, NULL);

    /* 设置接收屏蔽机制 后面来仔细研究一下该屏蔽机制 */
    FLEXCAN_SetRxMbGlobalMask(EXAMPLE_CAN, FLEXCAN_RX_MB_STD_MASK(rxIdentifier, 0, 0));
	
	/* 设置接收消息缓存 */
    mbConfig.format = kFLEXCAN_FrameFormatStandard;		//标准帧
    mbConfig.type   = kFLEXCAN_FrameTypeData;			//数据帧
    mbConfig.id     = FLEXCAN_ID_STD(rxIdentifier);		//设置帧ID
	FLEXCAN_SetFDRxMbConfig(EXAMPLE_CAN, RX_MESSAGE_BUFFER_NUM, &mbConfig, true);
	
	/* 设置发送消息缓存 */
	FLEXCAN_SetFDTxMbConfig(EXAMPLE_CAN, TX_MESSAGE_BUFFER_NUM, true);
}

流程与基础CAN功能类似,在波特率配置的时候使用的是bitRate ,这里需要注意以下;
从源码上看bitRate 和 baudRate的注释,好像也没有什么不同,如下图所示:(有了解的伙伴可以下面评论留言)
CAN外设文件源码中的配置结构体
配置的接收是轮询接收,中断接收后面再测试一下,配合官方SDK的例程探索,难度不大。
这里还配置了一个回调函数,用于判断接收和发送是否完成。

5、CAN FD收发

//发送数据
void can2_send_data(void)
{
	frame.id = FLEXCAN_ID_STD(txIdentifier);
	frame.format = (uint8_t)kFLEXCAN_FrameFormatStandard;
	frame.type   = (uint8_t)kFLEXCAN_FrameTypeData;
	frame.length = (uint8_t)DLC;
	frame.brs = 1U;	//灵活的数据率格式与比特率开关
    frame.edl = 1U;	//灵活的数据速率格式扩展数据长度
	
	frame.dataWord[0] = 0x12345678;
	frame.dataWord[2] = 0x12345678;
	frame.dataWord[15] = t_Count;
	txXfer.mbIdx = (uint8_t)TX_MESSAGE_BUFFER_NUM;	//用于传输消息的消息缓冲区的索引。
	txXfer.framefd = &frame;
	(void)FLEXCAN_TransferFDSendNonBlocking(EXAMPLE_CAN, &flexcanHandle, &txXfer);
	//FLEXCAN_WriteFDTxMb(EXAMPLE_CAN, TX_MESSAGE_BUFFER_NUM, &frame);
}

/*!
 * @brief FlexCAN Call Back function
 */
static FLEXCAN_CALLBACK(flexcan_callback)
{
    switch (status)
    {
        case kStatus_FLEXCAN_RxIdle:
            if (RX_MESSAGE_BUFFER_NUM == result)
            {
                rxComplete = true;
            }
            break;

        case kStatus_FLEXCAN_TxIdle:
            if (TX_MESSAGE_BUFFER_NUM == result)
            {
                txComplete = true;
            }
            break;

        case kStatus_FLEXCAN_WakeUp:
            wakenUp = true;
            break;

        default:
            break;
    }
}

//轮询接收
void can2_receive_data(void)
{
	rxXfer.mbIdx = (uint8_t)RX_MESSAGE_BUFFER_NUM;
	rxXfer.framefd = &frame;

	//无阻塞接收 利用回调函数进行接收数据
	(void)FLEXCAN_TransferFDReceiveNonBlocking(EXAMPLE_CAN, &flexcanHandle, &rxXfer);
	if (rxComplete == true)
	{
		t_Count++; 
		rxComplete = false;
	}
}

这里的接收和发送有一个联动的功能,就是CAN FD接收到正确的帧ID后,会将t_Count++;,然后再发送的地方frame.dataWord[15] = t_Count;这样就可以检测这个CAN FD的发送后接收是否都正确。
另外需要注意的是,使用CAN FD一定需要将flexcan_fd_frame_t 中的brs 、edl 置1;
CAN FD 发送配置

6、涉及的函数及标志位解释

6.1……

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/671001.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

数据库概念

本篇会加入个人的所谓鱼式疯言 ❤️❤️❤️鱼式疯言:❤️❤️❤️此疯言非彼疯言 而是理解过并总结出来通俗易懂的大白话, 小编会尽可能的在每个概念后插入鱼式疯言,帮助大家理解的. 🤭🤭🤭可能说的不是那么严谨.但小编初心是能让更多人能接…

Java学习Lambda表达式

Lambda表达式 有且只有一个未实现的方法叫做Lambda表达式,可以实现函数式编程 // 这个注解是用来检查你写的函数是否是函数式接口 FunctionalInterfaceinterface Myinterface {int sum(int a, int b);default String priteTitle(String name, int age, String sex)…

<Rust><iced>基于rust使用iced库构建GUI实例:动态改变主题色

前言 本专栏是Rust实例应用。 环境配置 平台:windows 软件:vscode 语言:rust 库:iced、iced_aw 概述 本篇构建了这样的一个实例,可以动态修改UI的主题,通过菜单栏来选择预设的自定义主题和官方主题&#…

1+X Web应用软件测试(中级) 考试失利教训

考证考试结束的第二天复盘 复盘时间:2024/6/2 9:45-10:00 考试名称:1X Web应用软件测试(中级) 电子书:Web应用软件测试(中级) 他人备考技巧 改进: [考前策略]自动化40性能40功能2个20 1.可以2人分工合作,完成一整套功能测试题目 2.制定阶段时间的学…

使用PyCharm 开发工具创建工程

一. 简介 前面学习了 安装 python解释器。如何安装python的一种开发工具 PyCharm。 本文来简单学习一下,如何使用 PyCharm 开发工具创建一个简单的 python工程。 二. PyCharm 开发工具创建一个工程 1. 首先,首先打开PyCharm 开发工具。选择 创建一…

社交媒体数据恢复:淘宝旺信

根据搜索结果,阿里旺旺聊天记录的恢复方法如下: 运行阿里旺旺在旺旺面板底部点击小喇叭图标在打开的消息管理器窗口右上角点击"搜索"点击"高级搜索"设置所需查找的时间段---"搜索" 此外,在阿里旺旺的云存储中…

xdp、dpdk、rdma能在同一网卡上同时使用吗?

文心一言 XDP、DPDK和RDMA是三种不同的技术,它们各自在Linux网络性能优化中扮演了不同的角色。关于它们能否在同一网卡上同时使用,我们需要考虑以下几个方面: XDP(eXpress Data Path): XDP是Linux内核提供…

搭建大型分布式服务(三十八)SpringBoot 整合多个kafka数据源-支持protobuf

系列文章目录 文章目录 系列文章目录前言一、本文要点二、开发环境三、原项目四、修改项目五、测试一下五、小结 前言 本插件稳定运行上百个kafka项目&#xff0c;每天处理上亿级的数据的精简小插件&#xff0c;快速上手。 <dependency><groupId>io.github.vipjo…

通过DLL方式链接glfw3.dll

主要是CMakeLists.txt文件变化 cmake_minimum_required(VERSION 3.10) project(glfwTest) set(CMAKE_CXX_STANDARD 11) aux_source_directory(. SRC_SOURCES) add_executable(glfwTest ${SRC_SOURCES}) target_link_libraries(glfwTest opengl32) # 链接库文件 target_inclu…

数据结构(C):从初识堆到堆排序的实现

&#x1f31e;0.前言 言C之言&#xff0c;聊C之识&#xff0c;以C会友&#xff0c;共向远方。各位博友的各位你们好啊&#xff0c;这里是持续分享数据结构知识的小赵同学&#xff0c;今天要分享的数据结构知识是堆&#xff0c;在这一章&#xff0c;小赵将会向大家展开聊聊堆的相…

年薪百万也难达财务自由?揭秘背后的真相!

谈及财务自由&#xff0c;人们往往会好奇&#xff1a;究竟需要多少资金才能跨越这道门槛&#xff1f;根据《胡润财富自由门槛》的调研&#xff0c;中国一线城市的财富自由标准从入门级的人民币1900万元到中级6500万到高级别的1.9亿元不等。然而&#xff0c;财务自由的核心并非仅…

ComfyUi安装OOTDiffusion插件的diffusers版本问题

OOTDiffusion换装 在github上有近5K的star了&#xff08;https://github.com/levihsu/OOTDiffusion&#xff09;。 diffusers版本问题 最新版是0.27.2&#xff0c;不能低于0.25&#xff0c;但是OOT换装需要0.24&#xff0c;否则会报错&#xff1a; ComfyUI\custom_nodes\Comf…

Android精通值Fragment的使用 —— 不含底层逻辑(五)

1. Fragment 使用Fragment的目标&#xff1a;根据列表动态显示内容&#xff0c;更简洁显示界面、查找界面 eg. 使用新闻列表动态显示新闻 1.1 Fragment的特性 具备生命周期 —— 可以动态地移除一些Fragment必须委托在Activity中使用可以在Activity中进行复用 1.2 Fragmen…

C#WPF数字大屏项目实战04--设备运行状态

1、引入Livecharts包 项目中&#xff0c;设备运行状态是用饼状图展示的&#xff0c;因此需要使用livechart控件&#xff0c;该控件提供丰富多彩的图形控件显示效果 窗体使用控件 2、设置饼状图的显示图例 通过<lvc:PieChart.Series>设置环状区域 3、设置饼状图资源样…

数据结构复习指导之交换排序(冒泡排序,快速排序)

目录 交换排序 复习提示 1.冒泡排序 1.1基本思想 1.2算法代码 1.3性能分析 2.快速排序 2.1基本思想 2.2算法代码 2.3性能分析 交换排序 复习提示 所谓交换&#xff0c;是指根据序列中两个元素关键字的比较结果来对换这两个记录在序列中的位置。 基于交换的排序算法很…

通过指针变量访问整型变量

有两个与指针变量有关的运算符&#xff1a; (1)&&#xff1a;取地址运算符。 (2)*&#xff1a;指针运算符&#xff08;或称间接访问运算符&#xff09;。 例如&#xff1a;&a为变量a的地址&#xff0c;*p为指针变量p所指向的存储单元。 编写程序&#xff1a; 运行结果…

第五十五周:文献阅读

目录 摘要 Abstract 文献阅读&#xff1a;基于VMD和深度学习的PM2.5浓度混合优化预测模型研究 一、现有问题 二、提出方法 三、方法论 1. 鲸优化算法&#xff08;WOA&#xff09; 2. 变分模式分解&#xff08;VMD&#xff09; 3.WOA-VMD优化方法 4. 双向长期记忆神经网…

V90PN伺服驱动器支持的标准报文介绍

1、V90 PN总线伺服通过FB285实现速度控制 V90 PN总线伺服通过FB285速度控制实现正弦位置轨迹运动(解析法和数值法对比测试)-CSDN博客文章浏览阅读448次。上面的位置函数有明确的解析函数&#xff0c;这里我们可以利用解析法求解其导数(微分),当然我们这里借助第三方数学软件求…

jrt落地deepin

经过昨天一晚上的努力&#xff0c;把deepin和win10的双系统安装好了。同时把jrt开发需要的svn&#xff0c;jdk,idea安装好里&#xff0c;代码也checkout里。 首先安装系统碰到安装deepin后启动时候无法选择win10,在宏伟兄帮助下找到资料执行sudo update-grub解决了。 然后程…

C++中的类

一&#xff0c;类的定义 class classname {//类体由成员函数和成员变量组成}; class为定义类的关键字&#xff0c;ClassName为类的名字&#xff0c;{}中为类的主体&#xff0c;注意类定义结束时后面分 号不能省略。 类的两种定义方式&#xff1a; 声明和定义全部放在类体中…