news 2026/4/30 5:24:10

QT编写的CAN通信调试工具:从原理到实践

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
QT编写的CAN通信调试工具:从原理到实践

CAN调试工具源代码吉阳光电致远周立功USB卡CAN单帧通信协议带相同ID折叠显式加载dll数据保存QT编写的CAN通信调试工具,基于致远周立功USB转CAN卡,可完成CAN帧的发送和接收,带配置参数自动保存,定时发送,帧类型选择,文本和十六进制等。 带有折叠相同的帧ID的功能,如果有相同的帧ID,则会自动折叠显示。 可组装字符串,字节数,整数等并完成发送。 带有保存到文件功能,文件名根据时间自动生成,解决了保存成中文乱码的问题。 2.环境说明: 开发环境是Qt5.12.1,吉阳光电和周立功的USB-CAN卡的开发库ControlCAN.dll。 源代码中包含详细注释,使用说明,设计文档等。 请将源码放到纯英文路径下再编译。 3.使用介绍: 可直接运行在可执行程序里的exe文件,操作并了解软件运行流程。 本代码产品特点: 1、尽量贴合实际应用,方便软件模块复用。 2、注释完善,讲解详细,还有相关扩展知识点介绍。 3、提供代码设计文档,使用文档,环境配置文档等。 4.子功能模块介绍: 封装了CAN通信通信类,可方便更换其他CAN卡; 具有控制台调试窗口,配置参数可自动保存; 带有数据保存功能,文件名可根据时间及日期自动生成; 相同帧ID的报文可自动折叠显示; 带有自定义协议示例,可以文本或十六进制输入;

最近在研究CAN通信相关的项目,发现了一款基于Qt编写的超实用CAN通信调试工具,今天就来和大家分享一下。它基于致远周立功USB转CAN卡,功能丰富,在实际应用场景中能发挥很大作用。

一、工具核心功能

1. CAN帧的发送和接收

这是工具最基础也是最重要的功能。代码中通过调用吉阳光电和周立功USB - CAN卡的开发库ControlCAN.dll来实现这一功能。以发送为例,在Qt中,你可能会看到类似这样的代码片段:

// 假设已经初始化好了CAN设备,获取到设备句柄m_deviceHandle // 构建要发送的CAN帧 VCI_CAN_OBJ sendFrame; sendFrame.ID = 0x123; // 假设ID为0x123 sendFrame.DataLen = 8; // 数据长度为8字节 for (int i = 0; i < 8; ++i) { sendFrame.Data[i] = i; // 填充数据 } sendFrame.SendType = 0; // 正常发送类型 // 调用库函数发送CAN帧 int result = VCI_Transmit(m_deviceHandle, 0, 0, &sendFrame, 1); if (result == 1) { qDebug() << "CAN帧发送成功"; } else { qDebug() << "CAN帧发送失败"; }

在这段代码里,首先构建了一个VCICANOBJ结构体类型的CAN帧对象sendFrame,设置好ID、数据长度、数据内容以及发送类型。然后调用VCI_Transmit函数,这个函数是来自ControlCAN.dll库的,它接收设备句柄、CAN通道号、要发送的帧对象以及发送帧数等参数。通过返回值判断发送是否成功。

2. 配置参数自动保存

这个功能很贴心,对于经常使用的用户来说,不用每次都重新配置参数。在Qt里,通常会用到QSettings类来实现配置参数的保存和读取。

// 保存配置参数 QSettings settings("config.ini", QSettings::IniFormat); settings.setValue("CAN/baudrate", m_baudrate); settings.setValue("CAN/deviceID", m_deviceID); // 读取配置参数 int baudrate = settings.value("CAN/baudrate", 500000).toInt(); int deviceID = settings.value("CAN/deviceID", 0).toInt();

这里通过QSettings类,将CAN的波特率mbaudrate和设备IDmdeviceID保存到名为config.ini的配置文件中。读取时,如果配置文件中没有相应的值,就使用默认值。

3. 定时发送

定时发送功能在一些需要周期性发送CAN帧的场景下非常有用。在Qt中,可以利用QTimer类来实现定时功能。

QTimer *sendTimer = new QTimer(this); connect(sendTimer, &QTimer::timeout, this, &MainWindow::sendCANFrame); sendTimer->start(1000); // 每1000毫秒(1秒)发送一次

上述代码创建了一个QTimer对象sendTimer,当timeout信号触发时,会调用MainWindow类中的sendCANFrame函数(这个函数就是实际发送CAN帧的函数)。start(1000)表示每1000毫秒触发一次定时事件。

4. 帧类型选择

CAN帧有不同的类型,如标准帧、扩展帧等。在代码中,可以通过一个下拉框或者类似的UI控件,让用户选择帧类型,然后根据用户选择来设置CAN帧结构体中的相关标志位。

// 假设在UI中有一个QComboBox对象m_frameTypeComboBox用于选择帧类型 int frameTypeIndex = m_frameTypeComboBox->currentIndex(); if (frameTypeIndex == 0) { sendFrame.ExternFlag = 0; // 标准帧 } else { sendFrame.ExternFlag = 1; // 扩展帧 }

这里根据QComboBox的当前选中索引来判断用户选择的帧类型,进而设置CAN帧结构体sendFrame中的ExternFlag标志位。

5. 文本和十六进制显示及发送

用户既可以以文本形式输入要发送的数据,也可以以十六进制形式输入。在代码中,需要对用户输入进行解析。

// 假设用户在一个QLineEdit中输入十六进制数据,如"01 02 03" QString hexInput = ui->hexLineEdit->text(); QByteArray data = QByteArray::fromHex(hexInput.toUtf8()); // 将解析出来的QByteArray数据填充到CAN帧的Data数组中 for (int i = 0; i < data.length() && i < 8; ++i) { sendFrame.Data[i] = data.at(i); }

这段代码从QLineEdit中获取用户输入的十六进制字符串,通过QByteArray::fromHex函数将其转换为字节数组,然后填充到CAN帧的Data数组中。

6. 相同ID帧折叠显示

这是一个很实用的显示优化功能。在显示接收到的CAN帧列表时,如果有相同的帧ID,会自动折叠显示。实现这个功能的关键在于维护一个数据结构,比如一个QMap,来记录每个ID对应的帧列表。

QMap<int, QList<VCI_CAN_OBJ>> idFrameMap; // 假设接收到一个CAN帧recvFrame if (idFrameMap.contains(recvFrame.ID)) { idFrameMap[recvFrame.ID].append(recvFrame); } else { QList<VCI_CAN_OBJ> frameList; frameList.append(recvFrame); idFrameMap.insert(recvFrame.ID, frameList); }

上述代码根据接收到的CAN帧的ID,将其添加到对应的QList中,如果该ID还没有对应的列表,则创建一个新的列表并插入。这样在显示时,就可以根据这个QMap来实现折叠显示。

7. 数据保存功能

带有保存到文件功能,文件名根据时间自动生成,并且解决了保存成中文乱码的问题。在Qt中,可以这样实现:

QDateTime currentTime = QDateTime::currentDateTime(); QString fileName = currentTime.toString("yyyyMMdd_hhmmss") + ".txt"; QFile file(fileName); if (file.open(QIODevice::WriteOnly | QIODevice::Text | QIODevice::Append)) { QTextStream out(&file); out.setCodec("UTF - 8"); // 设置编码为UTF - 8,解决中文乱码 out << "接收到的CAN帧数据:" << endl; // 假设已经有一个QList<VCI_CAN_OBJ>类型的receivedFrames列表存储接收到的帧 for (const VCI_CAN_OBJ &frame : receivedFrames) { out << "ID: " << QString::number(frame.ID, 16) << " Data: "; for (int i = 0; i < frame.DataLen; ++i) { out << QString::number(frame.Data[i], 16) << " "; } out << endl; } file.close(); }

这段代码首先获取当前时间并格式化为文件名,然后以追加和文本模式打开文件。通过设置QTextStream的编码为UTF - 8来避免中文乱码问题。最后将接收到的CAN帧数据按格式写入文件。

二、开发环境及注意事项

开发环境是Qt5.12.1,使用了吉阳光电和周立功的USB - CAN卡的开发库ControlCAN.dll。这里要注意,源代码中包含详细注释、使用说明、设计文档等,但请将源码放到纯英文路径下再编译,不然可能会遇到编译错误。

三、使用介绍

大家可以直接运行可执行程序里的exe文件,通过实际操作来了解软件运行流程。这款代码产品特点也很突出,尽量贴合实际应用,方便软件模块复用;注释完善,讲解详细,还有相关扩展知识点介绍;提供代码设计文档、使用文档、环境配置文档等。

四、子功能模块介绍

1. 封装CAN通信类

封装了CAN通信通信类,这使得更换其他CAN卡变得很方便。通过将与CAN卡交互的底层操作封装在一个类中,上层代码只需要调用这个类的接口函数,而不需要关心具体的CAN卡型号细节。

class CANCommunication { public: CANCommunication(); ~CANCommunication(); bool initCANDevice(); bool sendFrame(VCI_CAN_OBJ &frame); bool receiveFrame(VCI_CAN_OBJ &frame); private: int m_deviceHandle; };

在这个简单的类定义中,包含了初始化CAN设备、发送帧和接收帧的接口函数,以及一个设备句柄成员变量。这样在实际应用中,如果要更换CAN卡,只需要修改这个类中与底层库交互的部分代码,而其他使用到CAN通信功能的地方基本不需要改动。

2. 控制台调试窗口

具有控制台调试窗口,配置参数可自动保存。控制台调试窗口方便开发者在调试过程中输出一些调试信息,观察程序的运行状态。结合前面提到的配置参数自动保存功能,在调试过程中修改的一些配置参数下次启动程序时依然生效。

3. 数据保存功能回顾

再次强调一下数据保存功能,文件名可根据时间及日期自动生成,这个功能在记录数据时非常实用,方便对不同时间的数据进行区分和管理。

4. 相同帧ID折叠显示回顾

相同帧ID的报文可自动折叠显示,优化了数据显示效果,让用户能更清晰地查看接收到的CAN帧数据。

5. 自定义协议示例

带有自定义协议示例,可以文本或十六进制输入。这为开发者在实际项目中根据自己的需求定制CAN通信协议提供了很好的参考,无论是简单的数据传输还是复杂的控制指令交互,都能从这个示例中获取灵感。

CAN调试工具源代码吉阳光电致远周立功USB卡CAN单帧通信协议带相同ID折叠显式加载dll数据保存QT编写的CAN通信调试工具,基于致远周立功USB转CAN卡,可完成CAN帧的发送和接收,带配置参数自动保存,定时发送,帧类型选择,文本和十六进制等。 带有折叠相同的帧ID的功能,如果有相同的帧ID,则会自动折叠显示。 可组装字符串,字节数,整数等并完成发送。 带有保存到文件功能,文件名根据时间自动生成,解决了保存成中文乱码的问题。 2.环境说明: 开发环境是Qt5.12.1,吉阳光电和周立功的USB-CAN卡的开发库ControlCAN.dll。 源代码中包含详细注释,使用说明,设计文档等。 请将源码放到纯英文路径下再编译。 3.使用介绍: 可直接运行在可执行程序里的exe文件,操作并了解软件运行流程。 本代码产品特点: 1、尽量贴合实际应用,方便软件模块复用。 2、注释完善,讲解详细,还有相关扩展知识点介绍。 3、提供代码设计文档,使用文档,环境配置文档等。 4.子功能模块介绍: 封装了CAN通信通信类,可方便更换其他CAN卡; 具有控制台调试窗口,配置参数可自动保存; 带有数据保存功能,文件名可根据时间及日期自动生成; 相同帧ID的报文可自动折叠显示; 带有自定义协议示例,可以文本或十六进制输入;

总之,这款QT编写的CAN通信调试工具功能全面且实用,无论是对于CAN通信初学者还是有一定经验的开发者,都有很大的参考价值。希望大家可以去尝试使用一下,说不定能在你的项目中发挥大作用。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/4/30 5:24:08

探索人脸识别追踪:从图像采集到电机驱动的奇妙旅程

人脸识别追踪。 图像采集识别和电机驱动系统&#xff0c;利用openmv图像识别对人脸进行实时采集&#xff0c;采集信号传入到单片机&#xff0c;根据分析结果利用matlab-PID算法控制电机系统跟随人脸运动&#xff0c;自动检测追踪在科技飞速发展的当下&#xff0c;人脸识别追踪技…

作者头像 李华
网站建设 2026/4/28 15:53:29

ArcGIS大师之路500技---061四至的计算方法

文章目录前言前言 本文介绍使用字段计算器计算要素四至的方法。 操作步骤&#xff1a; 新建一个要素类&#xff0c;添加以下字段&#xff0c;如下图&#xff1a; 这四个字段用于存储要素四至信息。 开始编辑&#xff0c;随便画几个圆。 开始计算&#xff0c;在XMAX字段右键…

作者头像 李华
网站建设 2026/4/17 19:50:59

探索直流有感无刷电机驱动器:功能与特色深度剖析

电机控制资料 注&#xff1a;本驱动器适合于直流有感无刷电机 功能特点 支持电压9V&#xff5e;36V&#xff0c;额定输出电流5A 支持电位器、开关、0~3.3V模拟信号范围、0/3.3/5/24V逻辑电平、PWM/频率/脉冲信号、RS485多种输入信号 支持占空比调速(调压)、速度闭环控制(稳速)、…

作者头像 李华
网站建设 2026/4/26 0:34:02

SAP智能测试中心:重构企业级ERP的质量守护范式

第一章&#xff1a;传统ERP测试的痛点与智能化转型必然性 1.1 复杂业务场景的测试困局 数据耦合性挑战&#xff1a;以S/4HANA迁移为例&#xff0c;单个物料主数据变更可能触发财务核算、生产计划、仓储管理等12模块连锁响应 回归测试成本分析&#xff1a;某制造业客户统计显示…

作者头像 李华
网站建设 2026/4/23 18:57:46

Windows虚拟内存不足

检查能分配的最大内存 import numpy as np import psutil import sys import time import gcdef get_system_memory_info():"""获取系统内存信息"""mem psutil.virtual_memory()swap psutil.swap_memory()print("\n 系统内存状态 ")…

作者头像 李华
网站建设 2026/4/23 18:58:37

【开题答辩全过程】以 基于Python的街区医院管理系统的设计与实现为例,包含答辩的问题和答案

个人简介一名14年经验的资深毕设内行人&#xff0c;语言擅长Java、php、微信小程序、Python、Golang、安卓Android等开发项目包括大数据、深度学习、网站、小程序、安卓、算法。平常会做一些项目定制化开发、代码讲解、答辩教学、文档编写、也懂一些降重方面的技巧。感谢大家的…

作者头像 李华