【Qt】基于Qt的CAN分析仪二次开发
CAN分析仪有上位机,能够满足我们大多数情况下的使用,但当我们想扩展CAN的使用,如对消息进行封装,实现特定的执行功能时,就需要根据库文件进行二次开发。下面是使用zlg
进行二次开发的一次尝试。
请提前准备好这三个文件(库函数说明、头文件、lib库),确认是32位还是64位:
首先,新建Qt工程
添加库文件:
编辑ui文件:
创建CANMsg类,并把ControlCAN.h加入进来:
代码示例如下:
canmsg.h
#ifndef CANMSG_H
#define CANMSG_H#include "ControlCAN.h"
#include <QThread>
#include <QMetaType>/*can发送类型*/
enum CAN_SEND_TYPE
{CAN_SEND_NORMAL = 0,//正常CAN_SEND_SIGNAL,//单次CAN_SEND_SELF,//自发自收CAN_SEND_SELF_SIGNAL//单次自发自收
};/*can数据类型*/
enum CAN_DATA_TYPE
{CAN_DATA_INFO=0,//数据帧CAN_DATA_REMOTE//远程帧
};/*是否扩展帧*/
enum CAN_EXTERN_TYPE
{CAN_FRAM_STANDARD=0,//标准帧CAN_FRAM_EXTERN//扩展帧
};Q_DECLARE_METATYPE(PVCI_CAN_OBJ*);/*这个类主要用来接收和发送can总线数据*/
class CANMsg : public QObject
{public:CANMsg();BOOL open(DWORD baudIdx);BOOL close();void send(VCI_CAN_OBJ info);protected:void run();private slots:signals:void sendedInfoSignal(PVCI_CAN_OBJ obj);void getCanData(PVCI_CAN_OBJ objs,quint32 count);//把接收到的多帧can数据发给解析线程private:DWORD m_Type;DWORD m_Idx;DWORD m_Chl;BOOL m_IsOpen;VCI_CAN_OBJ recvObj[10];};#endif // CANMSG_H
canmsg.cpp
#include "CANMsg.h"#include <QMessageBox>
#include <QThread>
#include <QDebug>
//#include <QTimer>
#include <QTime>CANMsg::CANMsg():QThread()
{m_Type = VCI_USBCAN2;m_Idx = 0;m_Chl = 0;m_IsOpen = false;
}BOOL CANMsg::open(DWORD baudIdx)
{if(m_IsOpen == false){DWORD ret = STATUS_OK;ret = VCI_OpenDevice(m_Type,m_Idx,0);//打开设备,只需一次if(ret != STATUS_ERR){VCI_INIT_CONFIG initConfig;memset(&initConfig,0,sizeof(initConfig));initConfig.AccMask = 0xFFFFFFFF;initConfig.Mode = 0;initConfig.Timing0 = 0x00; //1MbpsinitConfig.Timing1 = 0x14;switch(baudIdx){case 0:initConfig.Timing0 = 0x00; //1MbpsinitConfig.Timing1 = 0x14;break;case 1:initConfig.Timing0 = 0x00; //800KbpsinitConfig.Timing1 = 0x16;break;case 2:initConfig.Timing0 = 0x00; //500KbpsinitConfig.Timing1 = 0x1c;break;case 3:initConfig.Timing0 = 0x03; //250KbpsinitConfig.Timing1 = 0x1c;break;case 4:initConfig.Timing0 = 0x04; //100KbpsinitConfig.Timing1 = 0x1c;break;default:break;}ret = VCI_InitCAN(m_Type,m_Idx,m_Chl,&initConfig);//初始化设备if(ret != STATUS_ERR){ret = VCI_StartCAN(m_Type,m_Idx,m_Chl);//开始采集if(ret != STATUS_ERR){qDebug()<<"Open CAN device success!"<<endl;m_IsOpen = true;}else{qDebug()<<"VCI_StartCAN ERR!"<<endl;}}else{qDebug()<<"VCI_InitCAN ERR!"<<endl;}}else{qDebug()<<"VCI_OpenDevice ERR!"<<ret<<endl;}}return m_IsOpen;
}BOOL CANMsg::close(void)
{if(m_IsOpen != false){DWORD ret = STATUS_OK;ret = VCI_CloseDevice(m_Type,m_Idx);if(ret != STATUS_ERR){m_IsOpen = false;qDebug()<<"Close CAN device success!"<<endl;}else{qDebug()<<"Close CAN device fail!"<<endl;}}return !m_IsOpen;
}/***********************************************/
// z 函数名称:直接发送操函数
// h 函数作用:NULL
// u 函数参数:NULL
// x 函数返回值:NULL
// y 备注:NULL
/***********************************************/
void CANMsg::send(VCI_CAN_OBJ info)
{DWORD Ret = VCI_Transmit(m_Type,m_Idx,m_Chl,&info,1);if(STATUS_OK == Ret){qDebug()<<"send OK"<<endl;
#if 0QTime current_time =QTime::currentTime();int second = current_time.second(); //当前的秒int msec = current_time.msec(); //当前的毫秒qDebug()<<"time:"<< second << "."<< msec <<endl;
#endifemit sendedInfoSignal(&info);}else{qDebug()<<"send fail,ret:"<<Ret<<endl;}
}/***函数名:线程*函数参数:NULL*函数作用:NULL*函数返回值:NULL*备注:NULL*/
void CANMsg::run()
{VCI_ClearBuffer(m_Type,m_Idx,m_Chl);while(m_IsOpen){if(VCI_GetReceiveNum(m_Type,m_Idx,m_Chl) > 0){quint32 recvCount = VCI_Receive(m_Type,m_Idx,m_Chl,recvObj,10);if(0xFFFFFFFF == recvCount)//读取失败{qDebug()<<"VCI_Receive err!"<<endl;}else{//发送给数据线程处理qDebug()<<"received msg!"<<endl;
#if 0QTime current_time =QTime::currentTime();int second = current_time.second(); //当前的秒int msec = current_time.msec(); //当前的毫秒qDebug()<<"time:"<< second << "."<< msec <<endl;
#endifemit getCanData(recvObj,recvCount);}}else{Sleep(1);}}
}
mainwindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H#include <QMainWindow>
#include "canmsg.h"namespace Ui {class MainWindow;
}class MainWindow : public QMainWindow
{Q_OBJECTpublic:explicit MainWindow(QWidget *parent = nullptr);~MainWindow();private:Ui::MainWindow *ui;CANMsg *m_pObjCanMgr;void showCanInfo(bool isSend,PVCI_CAN_OBJ obj);private slots:void on_BtnOpen_clicked();void on_BtnSend_clicked();void onRecvCanData(PVCI_CAN_OBJ objs,quint32 count);void onSendCanData(PVCI_CAN_OBJ obj);void on_pushButtonClear_clicked();
};#endif // MAINWINDOW_H
mainwindow.cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"#include <QMessageBox>
#include <QDebug>MainWindow::MainWindow(QWidget *parent) :QMainWindow(parent),ui(new Ui::MainWindow)
{ui->setupUi(this);m_pObjCanMgr = new CANMsg();qRegisterMetaType<PVCI_CAN_OBJ>("PVCI_CAN_OBJ");}MainWindow::~MainWindow()
{delete ui;delete m_pObjCanMgr;
}void MainWindow::on_BtnOpen_clicked()
{if(ui->BtnOpen->text() == "打开"){DWORD baudIdx = ui->comboBoxBaud->currentIndex();qDebug()<<"baudIdx:"<<baudIdx<<endl;if(m_pObjCanMgr->open(baudIdx)){ui->BtnOpen->setText("关闭");ui->comboBoxBaud->setEnabled(false);//启动线程//if(!m_pObjCanMgr->isRunning())//{// m_pObjCanMgr->start();//}connect(m_pObjCanMgr,SIGNAL(sendedInfoSignal(PVCI_CAN_OBJ)),this,SLOT(onSendCanData(PVCI_CAN_OBJ)));connect(m_pObjCanMgr,SIGNAL(getCanData(PVCI_CAN_OBJ,quint32)),this,SLOT(onRecvCanData(PVCI_CAN_OBJ,quint32)));}}else{//停止线程//m_pObjCanMgr->quit();m_pObjCanMgr->close();ui->BtnOpen->setText("打开");ui->comboBoxBaud->setEnabled(true);disconnect(m_pObjCanMgr,SIGNAL(sendedInfoSignal(PVCI_CAN_OBJ)),this,SLOT(onSendCanData(PVCI_CAN_OBJ)));disconnect(m_pObjCanMgr,SIGNAL(getCanData(PVCI_CAN_OBJ,quint32)),this,SLOT(onRecvCanData(PVCI_CAN_OBJ,quint32)));}
}void MainWindow::on_BtnSend_clicked()
{if(ui->BtnOpen->text() == "关闭"){VCI_CAN_OBJ sendObj;memset(&sendObj,0,sizeof(sendObj));QString IdStr = ui->lineEditId->text().simplified();if(IdStr.isEmpty()){QMessageBox::information(this,"提示","id不能为空");return;}UINT canID = IdStr.toUInt(nullptr,16);qDebug()<< "canID:"<<canID<<endl;sendObj.ID = canID;//发送类型sendObj.SendType = CAN_SEND_NORMAL;//数据类型sendObj.RemoteFlag = CAN_DATA_INFO;//是否扩展帧sendObj.ExternFlag = CAN_FRAM_EXTERN;QString DataStr = ui->lineEditData->text().simplified();//数据长度sendObj.DataLen = DataStr.remove(QRegExp("\\s")).size()/2;//数据内容QByteArray DataByte = QByteArray::fromHex(DataStr.toUtf8());memcpy(sendObj.Data,DataByte.data(),sendObj.DataLen);m_pObjCanMgr->send(sendObj);}else{QMessageBox::information(this,"提示","未打开设备!");}
}void MainWindow::onRecvCanData(PVCI_CAN_OBJ objs,quint32 count)
{//qDebug()<< "count"<<count<<endl;for(quint32 i = 0;i < count;i++){showCanInfo(false,objs+i);}
}void MainWindow::onSendCanData(PVCI_CAN_OBJ obj)
{showCanInfo(true,obj);
}void MainWindow::showCanInfo(bool isSend,PVCI_CAN_OBJ obj)
{QString StrPrefix;QString StrText;QString StrData;if(isSend){StrPrefix.sprintf("Tx:");}else{StrPrefix.sprintf("Rx:");}StrText.sprintf("id:0x%08x len:%d data:0x",obj[0].ID,obj[0].DataLen);for(quint32 j = 0;j < obj[0].DataLen;j++){QString StrTmp;StrTmp.sprintf("%02x ",obj[0].Data[j]);StrData.append(StrTmp);}StrText.append(StrData);StrPrefix.append(StrText);ui->textEditInfo->append(StrPrefix);qDebug()<<StrPrefix<<endl;
}void MainWindow::on_pushButtonClear_clicked()
{ui->textEditInfo->clear();
}
以上。
【Qt】基于Qt的CAN分析仪二次开发相关推荐
- Qt对ZLG CAN盒的二次开发
Qt对ZLG CAN盒的二次开发 环境: 操作系统:Windows10 开发工具:Qt Creator CAN盒型号:ZCAN_CANFDNET_200U 语言:C++ 环境准备 除了上述的CAN盒设 ...
- Python基于周立功盒子的二次开发的封装和调用
Python基于周立功盒子的二次开发的封装和调用 一.介绍 前面我们介绍如何拿到官网给的例程并使用起来,但在使用的过程中,我们发现官网给的例子非常的冗长,可读性不好,于是我进行分解和封装,使得 ...
- 基于百度编辑器Ueditor的二次开发
基于百度编辑器Ueditor的二次开发 官网下载 基本配置 简化后端配置,不请求后端配置项 后端接口规范 修改图片上传 说明及修改 新增按钮及弹窗(自定义附件上传) 按钮文案修改 在业务开发的时候,曾 ...
- 基于屌丝青年网样式二次开发的WordPress主题:LIiu-One主题
源码下载:基于屌丝青年网样式二次开发的WordPress主题:LIiu-One主题-小程序文档类资源-CSDN下载 wordpress主题,基于屌丝青年网样式二次开发LIiu-One主题仿屌丝青年网模 ...
- 基于康耐视cognexVisionpro用C#二次开发的多相机视觉对位框架
基于康耐视cognexVisionpro用C#二次开发的多相机视觉对位框架 支持1:多相机对位逻辑运算,旋转标定坐标关联运算(可供参考学习)可以协助理解做对位贴合项目思路. 支持2:直接连接运动控制卡 ...
- 基于大疆无人机SDK二次开发
基于大疆无人机SDK二次开发 近期公司项目需求,需要基于大疆无人机SDK开发一款手机 APP,用于配合后台实现对无人机的管理.当然大疆本身也给我们提供了管理平台-----大疆司空.通过大疆的官方 AP ...
- Python基于周立功盒子的二次开发的准备工作
Python基于周立功盒子的二次开发的准备工作 一.基本介绍 基于周立功的二次开发是python通过调用zlgcan.dll,来实现CAN卡的通讯收发报文的,在python中通过ctypes模 ...
- 嵌入式linux配置qt,基于qt的嵌入式Linux开发环境搭建
摘要:本文主要介绍在PC机上搭建基于QT的嵌入式开发环境,其中很多源文件都是开发板自带,需要相应资料的可以评论留下邮箱地址. 版本:交叉编译工具链:GCC 4.7.3 [gcc-linaro-arm ...
- QT: 基于QT和嵌入式的视频监控系统
[摘 要]为了降低视频监控系统的成本,提高系统布防的简易性,使其具有较好的稳定性和实时性,利用QT 设计了一款基于嵌入式视频服务器的监控系统.系统采用三星公司的S3C2440 微处理器芯片为核心的AR ...
最新文章
- Java中Runnable和Thread的区别
- webapck将css 打包后单独提取到一个css文件中
- 0.0.5、Linux命令
- moment获取几小时前_momentjs – 使用时刻在两个日期时间之间获得hh:mm的时差
- C语言——结构体链表,附完整示例
- 大数据技术之 Kafka (第 1 章 Kafka 概述)
- 使用etop查看系统中进程信息
- Modify HTTP Headers (Examples)
- Lesson 3.1 - Python Core Data Types
- 为啥这个月流量,感觉跑得特别快
- java迭代遍历_JAVA集合中的迭代器的遍历
- VS2019离线安装包制作
- Matlab R2018b简体中文版完整安装图文教程(附安装包下载)
- SQL Server 2008 评估已过期解决方案
- 双因素认证令牌_安全令牌:防止双因素令牌认证攻击
- PM血泪总结项目管理中存在的教训
- UNCTF2020web方向部分题解
- Lynis介绍与使用
- Linux- 网络配置
- 合作式智能运输系统 应用层交互技术要求 第 1 部分:意图共享与协作
热门文章
- 2012年2月4日汇报Axure RP Pro 6.5 Beta简体中文加强测试版进展
- acc 蓝牙_蓝牙耳机=音质渣?四大音质超赞的蓝牙耳机推荐
- Tableau服务器部署方案
- 谷歌验证码,国内各种验证码识别
- 【SQL开发实战技巧】系列(十二):三问(如何对字符串字母去重后按字母顺序排列字符串?如何识别哪些字符串中包含数字?如何将分隔数据转换为多值IN列表?)
- 还原分区失败怎么办?为什么会出现还原分区失败
- oracle学生选课查询(学生表student、成绩表sc、课程表c)
- 头号音频对齐插件 VocAlign Project 5 发布
- Element UI数字组件四舍五入问题及居右显示
- sscom 中文显示 乱码_SSM框架:解决后台传数据到前台中文乱码问题,使用@ResponseBody返回json 中文乱码 Web程序 - 贪吃蛇学院-专业IT技术平台...