QLibrary实现动态库调用,上位机同时兼任使用ZLG-USBCan2卡与USBCan2C

ZLG-USBCan2

USBCan2C

ZLG-USBCan2卡是行业中最常用的CAN卡,但是价格较贵;而一般场合的情况下可以使用USBCan2C替代使用,价格只有前者1/8。需要USBCan2C只需要更换动态库文件,就可以替代USBCan2C。故编写一个测试上位机同时兼任两者,再需要的时候替换。
构建一个类,通过QLibrary实现动态库切换。代码如下:
一、CPP文件

#include "drivecan.h"DriveCAN::DriveCAN(QObject *parent) : QObject(parent)
{}DriveCAN:: ~DriveCAN()
{this->Close();
}DriveCAN::DriveCAN(DWORD DeviceType,DWORD DeviceInd)
{this->DeviceType = DeviceType;this->DeviceInd = DeviceInd;
}bool DriveCAN::SelectDll(DWORD DeviceType,bool USBCAN2C_Flag)
{if((DeviceType==VCI_USBCAN2_C) && (USBCAN2C_Flag == true)){if(!MyLibrary.isLoaded()){MyLibrary.setFileName(QCoreApplication::applicationDirPath() + "/driver/2C/ControlCAN.dll");if(!MyLibrary.load()){qDebug()<< "load dll for 2C err" << MyLibrary.fileName();return false;}}}else{if(!MyLibrary.isLoaded()){MyLibrary.setFileName(QCoreApplication::applicationDirPath() + "/driver/zlg/ControlCAN.dll");if(!MyLibrary.load()){qDebug()<< "load dll for 2EU err" << MyLibrary.fileName();return false;}}}pVCI_OpenDevice = (CAN_VCI_OpenDevice)MyLibrary.resolve("VCI_OpenDevice");pVCI_CloseDevice = (CAN_VCI_CloseDevice)MyLibrary.resolve("VCI_CloseDevice");pVCI_InitCAN = (CAN_VCI_InitCAN)MyLibrary.resolve("VCI_InitCAN");pVCI_StartCAN = (CAN_VCI_StartCAN)MyLibrary.resolve("VCI_StartCAN");pVCI_GetReceiveNum = (CAN_VCI_GetReceiveNum)MyLibrary.resolve("VCI_GetReceiveNum");pVCI_Transmit = (CAN_VCI_Transmit)MyLibrary.resolve("VCI_Transmit");pVCI_Receive = (CAN_VCI_Receive)MyLibrary.resolve("VCI_Receive");pVCI_SetReference = (CAN_VCI_SetReference)MyLibrary.resolve("VCI_SetReference");pVCI_ClearBuffer = (CAN_VCI_ClearBuffer)MyLibrary.resolve("VCI_ClearBuffer");if(!pVCI_OpenDevice || !pVCI_InitCAN || !pVCI_StartCAN || !pVCI_CloseDevice || !pVCI_CloseDevice){qDebug()<< "函数加载失败" << MyLibrary.fileName();return false;}return true;
}bool DriveCAN::Open(DWORD DeviceType,DWORD DeviceInd)
{int nReserved = 0;DWORD dwRel = STATUS_ERR;this->DeviceType = DeviceType;this->DeviceInd = DeviceInd;if(this->DeviceType == VCI_USBCAN2_C)this->DeviceType = 4;dwRel = pVCI_OpenDevice(this->DeviceType, this->DeviceInd, nReserved);if (dwRel != STATUS_OK)return false;return true;
}bool DriveCAN::Init(int Channel,int Bode)
{VCI_INIT_CONFIG pInitConfig;DWORD dwRel = STATUS_ERR;DWORD RefType = 0;DWORD BaudRate = 0x1C0008;//0x060007PVOID pData;pData= &BaudRate;pInitConfig.AccCode = 0x00000000;pInitConfig.AccMask = 0xFFFFFFFF;pInitConfig.Filter = 0;pInitConfig.Mode = 0;pInitConfig.Reserved = 0;switch(Bode){case 250:pInitConfig.Timing0 = 0x01;pInitConfig.Timing1 = 0x1c;BaudRate = 0x1C0008;break;case 500:pInitConfig.Timing0 = 0x00;pInitConfig.Timing1 = 0x1c;BaudRate = 0x060007;break;default:pInitConfig.Timing0 = 0x01;pInitConfig.Timing1 = 0x1c;BaudRate = 0x1C0008;break;}//本人使用的 ZLG USBCAN-2E-U 需要特殊设置if(DeviceType == VCI_USBCAN_2E_U)dwRel = pVCI_SetReference(this->DeviceType, this->DeviceInd, Channel,RefType,pData);elsedwRel = pVCI_InitCAN (this->DeviceType, this->DeviceInd, Channel, &pInitConfig);if (dwRel == STATUS_ERR){pVCI_CloseDevice (this->DeviceType, this->DeviceInd);return false;}return true;
}bool DriveCAN::Start(int Channel)
{DWORD dwRel;dwRel = pVCI_StartCAN (this->DeviceType, this->DeviceInd, Channel);if (dwRel == STATUS_ERR){Close();return false;}return true;
}void DriveCAN::Close()
{pVCI_CloseDevice(this->DeviceType, this->DeviceInd);
}int DriveCAN::SendData (UINT ID,BYTE ExternFlag,QString CANBuf,int Channel)
{QStringList CANBufList;BYTE Len;bool ok;DWORD dwRel;CANBuf=CANBuf.trimmed ();CANBuf=CANBuf.simplified ();CANBufList = CANBuf.split (" ");Len = CANBufList.count ();if(Len > 8)Len = 8;VCI_CAN_OBJ vco[1];// 定义一帧的结构体数组// 中间略去其他函数代码vco[0].ID = ID;// 填写第一帧的IDvco[0].SendType = 0;// 正常发送vco[0].RemoteFlag = 0;// 数据帧vco[0].ExternFlag = ExternFlag;// 扩展帧vco[0].DataLen = Len;// 数据长度1个字节for(int i=0;i<vco[0].DataLen;i++){QString qstr =CANBufList.at (i);int val=qstr.toInt(&ok,16);//以十六进制数读入vco[0].Data[i]=val;}dwRel = pVCI_Transmit (this->DeviceType, this->DeviceInd, Channel, vco, 1); // 发送一帧return dwRel;
}int DriveCAN::RecData ( VCI_CAN_OBJ vco[1],int Channel)
{DWORD dwRel;// 中间略去其他函数代码dwRel=pVCI_Receive (this->DeviceType, this->DeviceInd, Channel, vco, 1, 400);// 一次最多能接收100帧,如果缓冲区无数据,接收函数等待400毫秒后退出,返回0if(dwRel == 0 || dwRel == 0xFFFFFFFF)return false;return true;
}int DriveCAN::RecData_100 ( VCI_CAN_OBJ vco[100],int Channel)
{DWORD dwRel;// 中间略去其他函数代码dwRel=pVCI_Receive (this->DeviceType, this->DeviceInd, Channel, vco, 100, 400);// 一次最多能接收100帧,如果缓冲区无数据,接收函数等待400毫秒后退出,返回0if(dwRel == 0 || dwRel == 0xFFFFFFFF)return false;return true;
}void DriveCAN::ClearBuffer(int Channel)
{DWORD dwRel;dwRel = pVCI_ClearBuffer(this->DeviceType,this->DeviceInd,Channel);
}

二、头文件

#ifndef DRIVECAN_H
#define DRIVECAN_H#include <QObject>
#include <QDebug>
#include <QLibrary>
#include <QCoreApplication>#include "ControlCan.h"typedef DWORD __stdcall (*CAN_VCI_OpenDevice)(DWORD ,DWORD ,DWORD );
typedef DWORD __stdcall (*CAN_VCI_CloseDevice)(DWORD ,DWORD);
typedef DWORD __stdcall (*CAN_VCI_InitCAN)(DWORD, DWORD, DWORD, PVCI_INIT_CONFIG);
typedef DWORD __stdcall (*CAN_VCI_StartCAN)(DWORD ,DWORD ,DWORD );
typedef ULONG __stdcall (*CAN_VCI_GetReceiveNum)(DWORD ,DWORD ,DWORD);
typedef ULONG __stdcall (*CAN_VCI_Transmit)(DWORD ,DWORD ,DWORD ,PVCI_CAN_OBJ ,ULONG );
typedef ULONG __stdcall (*CAN_VCI_Receive)(DWORD ,DWORD,DWORD ,PVCI_CAN_OBJ ,ULONG ,INT );
typedef DWORD __stdcall (*CAN_VCI_SetReference)(DWORD , DWORD , DWORD , DWORD , PVOID );
typedef DWORD __stdcall (*CAN_VCI_ClearBuffer)(DWORD ,DWORD ,DWORD );class DriveCAN : public QObject
{Q_OBJECTsignals:public slots:public:explicit DriveCAN(QObject *parent = nullptr);~DriveCAN();DriveCAN(DWORD DeviceType,DWORD DeviceInd);private:DWORD DeviceType;DWORD DeviceInd;QLibrary MyLibrary;CAN_VCI_OpenDevice    pVCI_OpenDevice;CAN_VCI_CloseDevice   pVCI_CloseDevice;CAN_VCI_InitCAN       pVCI_InitCAN;CAN_VCI_StartCAN      pVCI_StartCAN;CAN_VCI_GetReceiveNum pVCI_GetReceiveNum;CAN_VCI_Transmit      pVCI_Transmit;CAN_VCI_Receive       pVCI_Receive;CAN_VCI_SetReference  pVCI_SetReference;CAN_VCI_ClearBuffer   pVCI_ClearBuffer;public:bool SelectDll(DWORD DeviceType,bool USBCAN2C_Flag);void SetParam(DWORD DeviceType,DWORD DeviceInd);bool Open(DWORD DeviceType,DWORD DeviceInd);bool Init(int Channel,int Bode);bool Start(int Channel);void Close();int SendData (UINT ID,BYTE ExternFlag,QString CANBuf,int Channel);int RecData ( VCI_CAN_OBJ vco[1],int Channel);int RecData_100 ( VCI_CAN_OBJ vco[100],int Channel);void ClearBuffer(int Channel);};#endif // DRIVECAN_H

示例下载
https://download.csdn.net/download/FQJ19950804/18938976

Qt上位机同时使用ZLG-USBCan2卡与USBCan2C相关推荐

  1. qt串口采用队列_基于STM32的RGB调色器——STM32程序和Qt上位机全开源

    前言 uFUN开发板1.0版本评测时,基于Qt写了个小上位机,可以通过串口来控制板子上的RGB灯,通过控制,可以混合出任意的颜色,今天整理了一下,开源这个Qt上位机和STM32代码. 项目介绍 基于u ...

  2. 基于STM32的RGB调色器——STM32程序和Qt上位机全开源

    文章目录 前言 项目介绍 uFUN开发板 STM32下位机 Qt上位机 我的评测文章 关于我 前言 uFUN开发板1.0版本评测时,基于Qt写了个小上位机,可以通过串口来控制板子上的RGB灯,通过控制 ...

  3. FPGA基于XDMA实现PCIE X4通信方案 提供工程源码和QT上位机程序和技术支持

    目录 1.前言 2.我已有的PCIE方案 3.PCIE理论 4.总体设计思路和方案 5.vivado工程详解 6.驱动安装 7.QT上位机软件 8.上板调试验证 9.福利:工程代码的获取 1.前言 P ...

  4. 【HNU小学期硬件实训】基于QT上位机的汽车监控警报系统

    测试视频已上传到b站: 基于QT上位机的汽车监控警报系统 一.绪论 本次实验的选题是基于 QT 上位机的汽车行驶监控警报系统,灵感来源于本人在行驶电动车过程 中遇到的问题,为汽车模拟了不同的场景,外接 ...

  5. 基于uFUN开发板的心率计(三)Qt上位机的实现

    前言 上两周利用周末的时间,分别写了基于uFUN开发板的心率计(一)DMA方式获取传感器数据和基于uFUN开发板的心率计(二)动态阈值算法获取心率值,介绍了AD采集传感器数据和数据的滤波处理获取心率值 ...

  6. 【USB网络摄像头】基于mjpeg-streamer的视频采集与播放【QT上位机软件】

    前言 最近一直在尝试制作一个,网络摄像头,先后分别尝试了使用QT包装的UDP类TCP类,和LINUX中的socket编程等方式,但是非常遗憾,都没有取得非常好的播放效果.以为只要一帧一帧的传输视频数据 ...

  7. STM32串口烧录BIN文件、字库文件【QT上位机】- Uart_Transfer_BIN_to_EX_FLASH

    STM32串口烧录BIN文件.字库文件[QT上位机] 项目已开源至GitHub,供大家一起学习使用 点我传送 这里写目录标题 STM32串口烧录BIN文件.字库文件[QT上位机] 一.上位机部分 1. ...

  8. Qt上位机软件串口通讯

    录了一个串口讲解的视频,分别放在了抖音和B站,大家可以看看,主要讲了一下原理, B站我的主页:laorenshen的个人空间_哔哩哔哩_Bilibili 视频源码下载免费:Qt上位机软件串口通讯,视频 ...

  9. 1.QT上位机开发之表格设计-TABLE WIDGET

    QT上位机开发之表格设计-TABLE WIDGET 开发平台: QT Designer QT5 系统:Windows 11 软件语言:python 项目需要开发上位机软件用于模块测试,自己之前没有做过 ...

最新文章

  1. 2016百度之星 - 初赛(Astar Round2B)解题报告
  2. python变长参数传递
  3. 本教程针对HBuilder5.0.0,制作日期2014-12-31(从HBuilder工具上获得)
  4. 微服务(Microservices)和服务网格(Service Mesh)架构概念整理
  5. java 调用打印机 api_java 调用打印机API无法打印,但是直接打印可以,请问有人遇到过这样的问题吗?...
  6. 判定浏览器是否支持原生透明
  7. php zmq demo1
  8. Numpy详细函数属性
  9. Java 并发编程实战-创建和执行任务的最佳实践
  10. CMake 简单入门
  11. VHDL实现数码管的动态扫描(可以连接其他的模块)
  12. origin常用函数
  13. kafka-生产者消息发送流程
  14. ChinaSoft 论坛巡礼 | 形式化方法工业应用前沿
  15. TigerGraph首将模式匹配与高效图计算相结合,为欺诈检测、网络安全保护、人工智能等应用增砖加瓦!
  16. 【Flutter】如何完成一个透明沉浸式状态栏
  17. 游戏的汇总,在github和码云上找的,主要是安卓游戏,还有垃圾分类游戏
  18. 家用小型监控器安装位置与功能
  19. 有关面试八股文的一些难点
  20. Linux系统安装rar压缩软件

热门文章

  1. 《C陷阱与缺陷》——第三章(语义陷阱)
  2. JZOJ2020年8月11日提高组T3 页
  3. Centos7 下Scrapy安装过程
  4. 9个offer,12家公司
  5. [深度学习论文笔记]医学图像分割U型网络大合集
  6. Office 2010 PPT插入数字钟表
  7. JavaScript字符串方法汇总
  8. 百度下拉词怎么做?出现负面应该如何处理?此方法适用百度、搜狗、神马
  9. 贪吃蛇大作战ai_当玩家发现《贪吃蛇大作战》是单机游戏后 世界都炸了
  10. 一个让我用得很爽的个性导航h2w1.com