基于 MCXN947 微控制器的 USB 至 CAN-FD 适配器
本应用笔记旨在构建一个 USB 转 CAN-FD 或传统 CAN 适配器,使 USB 数据能够重新传输到 CAN 总线,反之亦然。恩智浦 MCXN 设备具有高速 USB 端口和 CAN-FD 控制器。HS USB 的传输速度最高可达 480 Mbit/s,足以在 MCXN 8Mbit/s 的 CAN 总线上以最高 CAN 波特率传输 CAN-FD 帧。
为了使系统易于使用并与其他设备兼容,我们使用 USB CDC 虚拟 COM 端口进行通信。使用 Python 接口以 ASCII 格式可视化 CAN-FD 信息。
主板:FRDM-MCXN947、MCX-N9XX-EVK
类别:工业
外设:USB、CAN
工具链:MCUXpresso IDE
目录
1.软件
此代码使用 MCUXpresso IDE 版本 11.8.0 和 MCUXpresso SDK 版本 2.13.1 实现。Python GUI 使用的是 Python 版本 3.10.10,其中包含 Tkinter 模块和 pySerial 库。Windows 系统使用 pyinstaller 创建 exe 文件。
2.硬件
- 购买支持的主板:
3. CAN-FD
CAN-FD 的定义见国际标准 ISO 11898-1:2015。为了帮助您快速上手使用 CAN-FD,本节将介绍 CAN-FD 的一些主要特性,面向熟悉 CAN 的用户。如果您是 CAN 新手,请访问community.nxp.com/CAN。
3.1 CAN和CAN-FD之间的区别
传统 CAN 和 CAN-FD 之间有两个主要区别。首先,CAN-FD 可以使用比传统 CAN 高得多的比特率。传统 CAN 的速率限制为 1 Mbit/s。CAN-FD 没有理论限制,但在实际应用中受收发器的限制。第二个主要区别是每个 CAN 消息的数据量增加。传统 CAN 的速率限制为 8 个数据字节。CAN-FD 的限制增加了八倍,达到每个消息 64 个数据字节。随着每个 CAN 消息数据量的增加,CAN-FD 帧需要更高的比特率来减少通信延迟时间并提高实时性能。CAN-FD 帧可以通过启用比特率切换功能达到更高的比特率。另一方面,比特率越高,比特时间越短。为了使数据阶段的比特时间甚至比发射器延迟更短,需要引入延迟补偿。如果没有发射器延迟补偿,CAN-FD 帧数据阶段的比特率将受到发射器延迟的限制。
图 1. CAN-FD 与 CAN 帧
4. USB CDC 类驱动程序
USB 通信设备类(或 USB CDC)是一种复合通用串行总线设备类。该类可能包含多个接口,例如自定义控制接口、数据接口、音频接口或大容量存储相关接口。在这种情况下,可以使用 USB 接口实现虚拟 COM 端口 (VCOM) 的功能,以便 PC 和嵌入式系统可以通过 VCOM 进行通信。要了解有关 USB 的一般信息,请访问以下链接:USB 基础培训
5.实施
5.1 概述
USB CDC 使用两个 USB 物理降压端点在 PC 和 MCU 之间传输数据。每个端点负责单向数据传输。
本示例将为每个管道使用两个缓冲区,一个用于 USB -> CAN-FD 总线,另一个用于 CAN-FD 总线 -> USB。数据到达 MCU 后,MCU 将负责使用获取的信息创建 CAN-FD 帧并发送;反之,MCU 将接收 CAN-FD 帧,并从中提取数据,然后使用 USB CDC 将其发送到 PC。
5.2 相关SDK示例
在继续任务之前,我们需要了解 USB CDC 和 CAN-FD 的使用背景知识。这两个示例都可以在 MCXN SDK 中找到:
- “mcxn9xxevkflexcaninterrupt_transfer”示例:
flexcan 中断示例展示了如何以非阻塞中断方式使用 FlexCAN 驱动程序。
本例中,两块开发板通过 CAN 总线连接。端点 A(开发板 A)向
当用户按下终端上的任意键时,端点 B(板 B)会收到该消息,并将消息内容打印到终端并回显该消息。端点 A 会增加收到的消息,并等待用户发起下一次传输。
- “mcxn9xxevkdevcdcvcombm”示例:
虚拟 COM 项目是一个基于 SDK 的简单演示程序。它被枚举为一个 COM 端口,用户可以使用终端工具(例如 TeraTerm)打开它。该演示程序会回显接收到的任何字符。此演示程序旨在展示如何构建 USB CDC 类设备,并为后续开发提供一个简单的项目。
这两个示例都可以从欢迎 | MCUXpresso SDK 构建器 (nxp.com)中提供的 MCXN SDK 导入
在继续阅读之前,请先熟悉以上两个示例。这两个示例是 USB-CAN 适配器设计的基础。
5.3 硬件实现
该示例是为 MCXN9XXEVK 和 FRDM-MCXN947 开发板创建的,这些开发板带有 USB PHY 和 CAN 收发器,无需对开发板进行任何硬件返工即可使用。必须在 board.h 文件中使用以下宏选择要使用的硬件:
MCX-N9XX-EVK 板
| 功能 | 通用输入输出 | 描述 |
| :--------------: | :----------------------: | :---------------: |
| CAN0TX | P118 | CAN总线传输信号 |
| CAN0RX | P119 | CAN总线接收信号 |
| USB1DM | USB1DM | HS USB DM |
| USB1DP | USB1DP | 高速USB DP |
| UARTRXD | P18 | 调试 UART RXD |
| UARTTXD | P19 | 调试 UART TXD |
FRDM-MCXN947板
FRDM 上的 USB-CAN 适配器使用的 GPIO 引脚
| 功能 | 通用输入输出 | 描述 |
| :--------------: | :----------------------: | :---------------: |
| CAN0TX | P110 | CAN总线传输信号 |
| CAN0RX | P111 | CAN总线接收信号 |
| USB1DM | USB1DM | HS USB DM |
| USB1DP | USB1DP | 高速USB DP |
| UARTRXD | P18 | 调试 UART RXD |
| UARTTXD | P19 | 调试 UART TXD |
5.4 软件实现
该软件基于两个裸机 SDK 示例创建:USB 设备 CDC VCOM 和 FlexCAN 中断。两者集成后,应用程序中会基于它们调整一个简单的串行协议,以便能够将 CAN 消息转换为 ASCII 串行消息,这些消息将通过 USB 设备 CDC(在本例中为 CDC)发送到 Python 接口,反之亦然。
接下来的步骤概述了如何创建 USB 至 CAN 项目示例:
- 使用 mcxn9xxevkdevcdcvcombm 作为基线。
- 集成mcxn9xxevkflexcaninterrupttransfer演示
- 将 CAN TxD 和 RxD 引脚配置复制到 pin
mux.c 文件中
- 将 fls_flexcan 驱动程序集成到 drivers 文件夹中的项目中
- 集成flexcaninterrupttransfer.c中的函数
- 创建适配层,将 CAN 消息转换为串行消息,反之亦然
- 在 USB 回调(USB_DeviceCdcVcomCallback)中确定在何处处理接收到的消息以转换为 CAN 消息并发送。
- 在 CAN 回调中识别接收完成,以了解何时将 CAN 帧转换为串行消息并使用 USB CDC 发送。
完整的 MCXN 软件示例可在此存储库中找到。
下图显示了此示例的高级框图设计。
这是项目中的流程图,首先初始化模块,然后 USB 初始化完成后,将启动并行操作,等待 USB 连接,然后进行枚举。PC 识别到开发板的 COM 后,代码将等待用户将 COM 连接到 GUI 或终端,并发送 CAN 的重新初始化序列,以重新配置所选的 CAN 选项、波特率、传统 CAN 或 CAN FD 以及扩展 ID。连接 GUI 终端后,代码将等待 CAN 帧或串行帧。
该应用程序的主要功能位于以下文件中:
可以接口.c
包含所有 CAN 相关函数的文件。CAN 发送、CAN 接收和 FlexCAN 初始化函数
usb_cdc_vcom.c
包含所有 USB 相关功能的文件。USB CDC 发送、USB CDC 接收和 USB 初始化功能。
usb_to_can.c
文件支持串行协议,具有接收输入功能来解析消息。
usb_can_适配器.c
包含用于调用初始化的主函数的文件。
5.5 串行命令帧
USB-CAN 适配器在主机上注册为虚拟串行端口,为了与接口轻松进行人机交互,CAN 命令将以 ASCII 字符的形式在 python 接口中接收,同样,接口将发送 ASCII 命令,这些命令将被转换为先前要发送的 CAN 命令。
为此,应按照以下特定格式创建框架:
| FD ID | 帧开始 | CAN ID | 扩展内容 | 数据 |
| :---------------: | :----------------: | :----------------: | :------------------: | :-----------------------------: |
| 2 个字符 | 1 个字符 | 3 个字符 | 1 个字符 | 2 至 128 个字符(取决于 DLC) |
- FD ID :字符“FD”用于识别该帧是否为 CAN-FD。
- 帧开始:ACII 字符“s”或“S”用于标识 CAN 帧的开始。
- CAN ID:3 个字符,有效值为“0 至 9”或“A 至 F”,与真实 CAN ID 的十六进制值相对应。
- DCL:有效的 DLC 选项:
| DLC 价值 | 字节长度 | 字符数 |
| :------------------: | :------------------: | :----------------: |
| 1 | 1 | 2 |
| 2 | 2 | 4 |
| 3 | 3 | 6 |
| 4 | 4 | 8 |
| 5 | 5 | 10 |
| 6 | 6 | 12 |
| 7 | 7 | 14 |
| 8 | 8 | 16 |
| 10 | 16 | 三十二 |
| 十三 | 三十二 | 64 |
| 15 | 64 | 128 |
- 数据:2 至 128 个字符,有效值为“0 至 9”或“A 至 F”,与 CAN 帧中的十六进制值相对应。
例子 :
FDs12381122334455667788
| FD ID | 帧开始 | CAN ID | 扩展内容 | 数据 |
| :---------------: | :----------------: | :----------------: | :------------------: | :----------------: |
| FD | 秒 | 123 | 8 | 1122334455667788 |
5.6 Python GUI 界面
Python 是近年来最热门的编程语言之一。社区开发了一些非常有用的库和工具,使我们能够自动化流程,或者像本文中提到的那样开发接口。
本例中的 Python 接口是使用 Python 修订版 3.10.10 和 Tkinter 模块和 pySerial 库创建的,所有这些工具在网络上都有广泛的记录,并且有许多很好的例子可以作为基准。
此示例的代码包含在 pythongui 文件夹中的项目中。如果您对此主题不感兴趣,也可以使用位于 pythonguidist 目录下的 MCXUSBtoCAN_GUI.exe Windows 可执行文件。
5.7 接口说明
接口支持以下:
- 端口选择:允许您为 USB CDC 板选择 COM。
- CAN 波特率:将选择仲裁阶段波特率。
- CAN-FD 波特率:将选择数据阶段波特率。
- 连接:选择端口和波特率后必须点击此按钮。这将启动与我们设备的串行通信。
- 在中间的窗口中,我们将能够看到接收和发送的 CAN 消息
- FD:此复选框用于选择使用传统 CAN 或 CAN-FD 来以所选格式传输和接收帧。
- CAN ID:选择发送消息的 CAN ID
- 例如:此复选框用于激活扩展 ID 支持
- DLC:指示长度数据的DLC。如果数据长度不允许,则会显示错误。
- 数据:待传输的消息。长度必须为 2 到 16、32、64 或 128 个字符之间的偶数,具体取决于 DLC 描述。
6. 动手
在下一个示例中,USB 转 CAN 适配器将用于与 CAN 设备通信或监控 CAN 网络中的通信。
6.1 直接沟通
此示例需要两块开发板。一块开发板将运行 USB 转 CAN 适配器代码,另一块开发板将运行 frdmmcxn947flexcaninterrupt_transfer 演示。
准备示例:
- 将 USB 电缆连接到两块板上的 J17 调试 USB 端口和 PC 主机。
- 使用 USB 电缆连接 PC 主机和将运行 USB 转 CAN 代码的开发板上的 J11 USB 设备端口。
- 板对板 CAN 连接需要如下:
| 节点A USBtoCAN | Node B CAN中断演示 | | |
| :------------------------: | :----------------------------: | :----------- | :----------- |
| 信号名称 | 董事会位置 | 信号名称 | 董事会位置 |
| 加勒比海 | J10-1 | 加勒比海 | J10-1 |
| 加拿大航空 | J10-2 | 加拿大航空 | J10-2 |
| 接地 | J10-4 | 接地 | J10-4 |
- 将示例代码下载到开发板上。一块开??发板需要使用本应用笔记附带的 USB 转 CAN 适配器源代码进行编程,另一块开发板需要使用直接从 MCXN9 SDK 导入的 flexcaninterrupttransfer 演示程序进行编程。
- 从带有 mcxn9xxevkflexcaninterrupt_transfer 演示的电路板上打开 PC 上的串行终端,并使用以下设置:
- 115200波特率
- 8个数据位
- 无奇偶校验
- 一个停止位
- 无流量控制
- 按下开发板上的重置按钮或在 IDE 中启动调试器即可开始运行演示。
运行示例:
- 使用 MCXUSBtoCANGUI.py 或 MCXUSBtoCANGUI.exe 打开 Python 接口
- 选择与USB CDC对应的COM。
- 在此示例中,CAN 波特率为 500000,CAN-FD 波特率为 2000000。
- 单击“连接”按钮。
- 设置 FD 复选框。
- 在 frdmmcxn947flexcaninterrupt_transfer 演示中选择节点 A 作为选项。
- 按下串行终端上的任意键即可发送 CAN 消息。
- 现在在 GUI 界面上在数据部分写入值 01 并单击发送按钮。
- 现在您可以重复步骤 7 和 8。只需记住,frdmmcxn947flexcaninterrupt_transfer 演示在发送 CAN 消息后处于循环等待接收消息,并且在接收消息后将等待直到使用终端发送 CAN 消息。
运行演示后的串行终端
运行demo后的Python GUI界面
6.2 使用 Python GUI 测试不同的配置
此示例需要两块开发板。这两块开发板将运行 USB 转 CAN 适配器代码。将代码加载到开发板后,无需将 USB 线缆连接到 MCU Link J17 连接器,开发板仅需连接到 USB 连接器 J11。
准备示例:
- 板对板 CAN 连接需要如下:
| 节点A USBtoCAN | Node B CAN中断演示 | | |
| :------------------------: | :----------------------------: | :----------- | :----------- |
| 信号名称 | 董事会位置 | 信号名称 | 董事会位置 |
| 加勒比海 | J10-1 | 加勒比海 | J10-1 |
| 加拿大航空 | J10-2 | 加拿大航空 | J10-2 |
| 接地 | J10-4 | 接地 | J10-4 |
- 下载本应用说明附带的 USB 至 CAN 适配器源代码,加载代码后,将 USB 电缆连接到 USB 连接器 J11。
运行示例:
- 使用 MCXUSBtoCANGUI.py 或 MCXUSBtoCANGUI.exe 打开两个 Python 接口
- 选择与USB CDC对应的COM。
- 保留所有参数为默认值并单击“连接”按钮。
- 修改 CAN ID 来识别帧,我将使用 COM 号仅供参考。
- 在数据部分写入不同的消息,我们也可以尝试不同的长度。
- 在两个界面中点击发送按钮。
- 消息将在 GUI 窗口中显示为 Rx 或 Tx。
- 单击两者中的“断开连接”按钮。
- 在两个 GUI 中勾选“Ex”复选框,并选择不同的波特率。注意,现在您可以写入一个 29 位 ID,但高于此值的 3 位将被忽略。
- 再次单击“连接”。
- 改变数据和ID来传输不同的帧。
- 点击发送按钮。注意此时的ID是扩展ID,长度为29位。
- 再次点击断开按钮即可修改参数。
- 更改波特率并设置 FD 复选框。注意,现在数据可以是 1 - 8、16、32 或 64 字节,其他长度将被标记为错误。
- 单击“连接”
- 现在写入任意数据,如果需要的话可以更改 CAN ID。
- 点击“发送”按钮。注意,现在窗口使用 FD 作为类型。
- 单击“断开连接”。
- 最后取消勾选Ex Checkbox。注意ID又回到了11位。
- 重新连接。
- 使用不带扩展 ID 的 CAN FD 发送消息。
注意:重要的是要知道 CAN FD 能够接收经典 CAN 命令,但如果在 GUI 中选择了经典 CAN,它将无法接收 CAN FD,这也是在 CAN 协议中建立的。
6.3 监控CAN网络
在本例中,我们需要一个包含两个或更多设备的 CAN 网络。将使用带有 USB 转 CAN 适配器代码的 MCXN 开发板连接到网络。目标是监控网络上的所有流量。本演示将使用两块 NXP 开发板,并在两块开发板上分别运行 caninterrupttransfer 演示程序作为 CAN 网络。
准备示例:
- 使用 USB 电缆连接 PC 主机和板上的 J11 USB 设备端口。
- CAN网络的连接方式如下:
| 节点A USBtoCAN | |
| :------------------------: | :----------- |
| 信号名称 | 董事会位置 |
| 加勒比海 | J10-1 |
| 加拿大航空 | J10-2 |
| 接地 | J10-4 |
运行示例:
- 使用 MCXUSBtoCANGUI.py 或 MCXUSBtoCANGUI.exe 打开 Python 接口
- 选择与USB CDC对应的COM。
- 在此示例中,CAN 波特率为 1000000,CAN-FD 波特率为 2000000。
- 单击“连接”按钮。
- 设置 FD 复选框。
- 启动 CAN 网络上的数据传输,并检查 USB 转 CAN 接口捕获了什么。
运行demo后的Python GUI界面
7. 支持
如果您对此代码有任何疑问或反馈,请联系恩智浦支持或在我们的社区https://community.nxp.com/上发帖。您可以在这里找到有关此代码示例各个方面的论坛,包括 MCUXpresso 工具和设备系列。
项目元数据
来源:恩智浦appcodehub