1. 引言
在基于图莫斯(TOOMOSS)USB转CAN适配器开发UDS升级上位机时,设备打开与初始化是整个软件栈的基石。无论后续要实现多复杂的UDS服务(如10会话切换、27安全访问、34-36-37下载流程),都离不开一个正确初始化并正常工作的CAN设备句柄。
TOOMOSS_OpenDev(CAN).vi 就是这个基石。它封装了图莫斯DLL中与设备管理相关的四个核心函数,完成从扫描设备 → 打开设备 → 获取波特率参数 → 初始化CAN通道的完整流程,最终输出一个有效的设备句柄供后续所有CAN通信子VI使用。
本文将详细拆解这个子VI的设计思路、前面板布局、程序框图实现以及关键结构体参数的配置方法。
2. 子VI功能概述
2.1 输入参数
| 控件 | 类型 | 默认值 | 说明 |
|---|---|---|---|
| 设备号 | U8(0~5) | 0 | 指定要打开的CAN设备序号,由USB_ScanDevice扫描结果决定 |
| 通道号 | 枚举(CAN1/CAN2) | CAN1 | 选择使用设备的CAN1还是CAN2通道 |
| 波特率 | 数值输入(单位Kbps) | 500 | CAN总线通信速率,如125、250、500、1000等 |
2.2 输出参数
| 控件 | 类型 | 说明 |
|---|---|---|
| 设备句柄 | U32 | 成功打开设备后返回的句柄,后续所有CAN操作函数都需要传入此句柄 |
| 错误信息 | 字符串 | 初始化失败时的错误描述 |
2.3 调用的DLL函数
本子VI通过"调用库函数节点"(CLN)调用图莫斯USB2XXX库中的四个核心函数:
| 函数 | 功能 |
|---|---|
USB_ScanDevice |
扫描并获取可用设备的句柄 |
USB_OpenDevice |
打开指定设备 |
CAN_GetCANSpeedArg |
根据波特率计算CAN初始化参数 |
CAN_Init |
初始化CAN通道 |
3. 关键结构体:CAN_INIT_CONFIG
在调用CAN_Init之前,需要填充一个CAN_INIT_CONFIG结构体,它定义了CAN控制器的全部工作时序参数。
该结构体的定义如下:
c
typedef struct _CAN_INIT_CONFIG
{
unsigned int CAN_BRP; ///< 波特率预分频器,取值范围1~1024
unsigned char CAN_SJW; ///< 同步跳转宽度,取值范围1~4
unsigned char CAN_BS1; ///< 时间段1,取值范围1~16
unsigned char CAN_BS2; ///< 时间段2,取值范围1~8
unsigned char CAN_Mode; ///< CAN工作模式:0-正常,1-环回,2-静默,3-静默环回
unsigned char CAN_ABOM; ///< 自动离线管理:0-禁止,1-使能
unsigned char CAN_NART; ///< 报文重发管理:0-使能重传,1-禁止重传
unsigned char CAN_RFLM; ///< FIFO锁定管理:0-新报文覆盖旧报文,1-丢弃新报文
unsigned char CAN_TXFP; ///< 发送优先级管理:0-标识符决定,1-发送请求顺序决定
} CAN_INIT_CONFIG, *PCAN_INIT_CONFIG;
3.1 各成员详解
CAN_BRP(波特率预分频器)
计算公式为:CAN波特率 = 主频时钟 / (CAN_BRP * (CAN_SJW + CAN_BS1 + CAN_BS2))
该值由CAN_GetCANSpeedArg函数根据用户指定的波特率自动计算,开发者无需手动配置。
CAN_SJW(同步跳转宽度)
指定CAN控制器在重新同步时允许调整的最大时间量子数。取值范围1~4,通常取1或2即可满足绝大多数应用场景。
CAN_BS1 / CAN_BS2(时间段1 / 时间段2)
共同决定了一个位时间的采样点位置。典型配置中,BS1占位时间的60%~80%,BS2占剩余部分。
CAN_Mode(工作模式)
-
0(正常模式):标准CAN通信模式,适用于实际车载或测试环境。
-
1(环回模式):数据在内部环回,不实际发送到总线,适合自测。
-
2(静默模式):只接收不发送,用于总线监听。
-
3(静默环回模式):环回+静默的组合。
CAN_ABOM(自动离线管理)
-
0:禁止自动恢复,设备离线后需手动恢复。
-
1:使能自动恢复,设备检测到总线恢复后自动重新加入通信。
CAN_NART(报文重发管理)
-
0:使能自动重传(标准CAN行为)。
-
1:禁止自动重传,适用于对实时性要求极高的场景。
CAN_RFLM(FIFO锁定管理)
-
0:新报文覆盖旧报文(FIFO溢出时)。
-
1:丢弃新报文,保留旧报文。
CAN_TXFP(发送优先级管理)
-
0:按CAN标识符决定发送优先级(ID越小优先级越高)。
-
1:按发送请求的先后顺序决定。
4. 程序框图设计
4.1 整体流程
4.2 第一步:扫描设备
调用USB_ScanDevice函数扫描当前连接的图莫斯设备:
-
参数 :
pDevHandle(输出参数,存储扫描到的设备句柄) -
返回值:扫描到的设备数量。若为0,表示没有扫描到任何设备
在LabVIEW中通过CLN节点调用时,pDevHandle应配置为指向U32的指针类型,调用后返回实际扫描到的设备数量。
4.3 第二步:打开设备
调用USB_OpenDevice打开指定序号的设备:
-
参数:设备号(0~5)
-
返回值:0表示打开失败,1表示打开成功
4.4 第三步:获取波特率参数
调用CAN_GetCANSpeedArg根据用户选择的波特率计算CAN_INIT_CONFIG结构体的各成员值:
-
输入:设备句柄、波特率(单位bps)
-
输出 :填充好的
CAN_INIT_CONFIG结构体
4.5 第四步:初始化CAN通道
调用CAN_Init完成CAN控制器的初始化:
-
参数 :设备句柄、CAN通道索引(0或1)、
CAN_INIT_CONFIG结构体指针 -
返回值:0表示初始化成功,非0表示失败
5. 前面板设计
前面板包含4个核心控件,布局简洁清晰:

6. 关键CLN节点配置
6.1 USB_ScanDevice
| 配置项 | 设置 |
|---|---|
| 函数名 | USB_ScanDevice |
| 调用规范 | stdcall (WINAPI) |
| 参数1 | pDevHandle → 指向U32的数值数据指针(输出) |
| 返回值 | 有符号32位整数(扫描到的设备数量) |

6.2 USB_OpenDevice
| 配置项 | 设置 |
|---|---|
| 函数名 | USB_OpenDevice |
| 调用规范 | stdcall (WINAPI) |
| 参数1 | 设备号 → 无符号8位整数(输入) |
| 返回值 | 有符号32位整数(0失败/1成功) |
6.3 CAN_GetCANSpeedArg
| 配置项 | 设置 |
|---|---|
| 函数名 | CAN_GetCANSpeedArg |
| 调用规范 | stdcall (WINAPI) |
| 参数1 | 设备句柄 → 无符号32位整数(输入) |
| 参数2 | pCanConfig → 指向CAN_INIT_CONFIG结构体的指针(输出) |
| 参数3 | 波特率 → 无符号32位整数(输入,单位bps) |
| 返回值 | 有符号32位整数(0成功/非0失败) |

6.4 CAN_Init
| 配置项 | 设置 |
|---|---|
| 函数名 | CAN_Init |
| 调用规范 | stdcall (WINAPI) |
| 参数1 | 设备句柄 → 无符号32位整数(输入) |
| 参数2 | CAN索引 → 无符号8位整数(输入,0或1) |
| 参数3 | pCanConfig → 指向CAN_INIT_CONFIG结构体的指针(输入) |
| 返回值 | 有符号32位整数(0成功/非0失败) |
7. 错误处理
子VI应在以下环节进行错误检查并返回明确的错误信息:
| 错误场景 | 返回信息 |
|---|---|
USB_ScanDevice返回0 |
"未检测到图莫斯设备,请检查连接" |
USB_OpenDevice返回0 |
"打开设备失败,请检查设备号是否正确" |
CAN_GetCANSpeedArg返回非0 |
"获取波特率参数失败,请检查波特率设置" |
CAN_Init返回非0 |
"CAN初始化失败,请检查通道号和波特率" |
8. 测试验证
-
连接图莫斯USB转CAN适配器到电脑。
-
在子VI前面板设置设备号=0,通道号=CAN1,波特率=500Kbps。
-
运行子VI,观察设备句柄是否输出非0值。
-
如输出0或错误信息,检查设备连接和驱动安装。
9. 总结
TOOMOSS_OpenDev(CAN).vi封装了图莫斯CAN设备从扫描到初始化的完整流程,是该UDS升级上位机系列中最基础的子VI 。后续所有涉及CAN通信的子VI(如TOOMOSS_SendAndWaitResp.vi、TOOMOSS_SID10_RequestSession.vi等)都依赖它输出的设备句柄。
理解CAN_INIT_CONFIG结构体各成员的含义,有助于在遇到CAN通信异常时快速定位问题(如波特率不匹配、模式配置错误等)。
下一篇将介绍 TOOMOSS_SendAndWaitResp.vi ------ 核心通信基座,敬请期待。