Qt配置USBCAN通訊

周立功爲CAN通訊提供了動態庫:官方提供了不少相關動態庫和lib等,如圖linux

,其中kerneldlls裏還有不少動態庫,還有一個配置文件。其實這麼多的文件,若是咱們只用到USBCAN2通訊,只須要kerneldlls裏面的usbcan.dll這個動態庫,裏面真正封裝了用了windows和can模塊經過usb通訊的函數。而後還須要ControlCAN.h這個頭文件,裏面有對使用dll函數時一些結構體的聲明和定義。對於ControlCAN.dll和ControlCAN.lib其實是對使用usbcan.dll動態庫的引導入口。編程

對於如何使用Qt加載這些動態庫來實現CAN通訊,有兩種方式,1是顯式,2是隱式。windows

顯式:經過代碼加載動態庫咱們須要的函數,把這些函數實際放在本身的工程之中;數組

隱式:經過在工程中加入動態庫入口的路徑,使可執行文件在運行時在相應路徑找動態庫,再使用其函數。app

1、顯式函數

一、新建工程,在工程中(和源文件放在一塊兒)添加ControlCAN.h頭文件、usbcan.dll動態庫。性能

ControlCAN.h是須要包含在工程中的(右鍵工程-》添加存在路徑-》此時默認勾選好了ControlCAN.h,確認便可);usbcan.dll是須要加載的動態庫編碼

二、使用QLibrary加載動態庫spa

QLibrary lib("usbcan.dll");線程

if(true == lib.load())

  qDebug()<<"load ok";

三、聲明一個本身的函數,功能與usbcan.dll裏的函數的功能想對應

好比,usbcan.dll中有個打開設備的函數,那就本身定義一個打開設備的函數,把usbcan.dll中打開設備函數的功能賦值到自定義函數中--!

頭文件中:

typedef DWORD(__stdcall VCI_OpenDevice)(DWORD,DWORD,DWORD);//不知道爲何,反正沒有就會出錯

typedef DWORD(__stdcall VCI_ResetCAN)(DWORD DeviceType,DWORD DeviceInd,DWORD CANInd);

typedef DWORD(__stdcall VCI_CloseDevice)(DWORD DeviceType,DWORD DeviceInd);

typedef DWORD(__stdcall VCI_InitCAN)(DWORD DeviceType, DWORD DeviceInd, DWORD CANInd, PVCI_INIT_CONFIG pInitConfig);

typedef DWORD(__stdcall VCI_StartCAN)(DWORD DeviceType,DWORD DeviceInd,DWORD CANInd);

typedef ULONG(__stdcall VCI_Transmit)(DWORD DeviceType,DWORD DeviceInd,DWORD CANInd,PVCI_CAN_OBJ pSend,ULONG Len);

typedef ULONG(__stdcall VCI_Receive)(DWORD DeviceType,DWORD DeviceInd,DWORD CANInd,PVCI_CAN_OBJ pReceive,ULONG Len,INT WaitTime/*=-1*/);

typedef ULONG(__stdcall VCI_GetReceiveNum)(DWORD DeviceType,DWORD DeviceInd,DWORD CANInd);

typedef DWORD(__stdcall VCI_ClearBuffer)(DWORD DeviceType,DWORD DeviceInd,DWORD CANInd);

typedef DWORD(__stdcall VCI_ReadErrInfo)(DWORD DeviceType,DWORD DeviceInd,DWORD CANInd,PVCI_ERR_INFO pErrInfo);

typedef DWORD(__stdcall VCI_ReadCANStatus)(DWORD DeviceType,DWORD DeviceInd,DWORD CANInd,PVCI_CAN_STATUS pCANStatus);

以上函數全是can通訊重要的函數,所有爲本身定義的,名字隨便取均可以。

四、使用上面的函數聲明對應的函數對象

頭文件中:

VCI_OpenDevice *pOpenDevice;

VCI_ResetCAN *pResetCAN;

VCI_CloseDevice *pCloseDevice;

VCI_InitCAN *pInitCAN;

VCI_StartCAN *pStartCAN;

VCI_Transmit *pTransmitCAN;

VCI_Receive *pReceive;

VCI_GetReceiveNum *pGetReceiveNum;

VCI_ClearBuffer *pClearBuffer;

VCI_ReadErrInfo *pReadErrInfoCAN;

VCI_ReadCANStatus *pVCI_ReadCANStatus;

五、引入usbcan.dll動態庫

在源文件中:

QLibrary lib("usbcan.dll");

true == lib.load();

六、將usbcan.dll中的函數功能分解到自定義對應函數中

源文件中:

pOpenDevice = (VCI_OpenDevice *)lib.resolve("VCI_OpenDevice");

pCloseDevice = (VCI_CloseDevice *)lib.resolve("VCI_CloseDevice");

pInitCAN = (VCI_InitCAN *)lib.resolve("VCI_InitCAN");

pStartCAN = (VCI_StartCAN *)lib.resolve("VCI_StartCAN");

pTransmitCAN = (VCI_Transmit *)lib.resolve("VCI_Transmit");

pReceive = (VCI_Receive *)lib.resolve("VCI_Receive");

pGetReceiveNum = (VCI_GetReceiveNum *)lib.resolve("VCI_GetReceiveNum");

pClearBuffer = (VCI_ClearBuffer *)lib.resolve("VCI_ClearBuffer");

pReadErrInfoCAN = (VCI_ReadErrInfo*)lib.resolve("VCI_ReadErrInfo");

七、接下來就可使用自定義的函數來進行CAN總線編程了

 2、隱式

一、把ControlCAN.h和ControlCAN.lib放在工程目錄下,和源文件放在一塊兒

二、把kerneldlls文件夾(裏面只須要放ini配置文件和usbcan.dll文件便可)和ControlCAN.dll和可執行文件放在一塊兒

三、右鍵Qt工程,添加庫->外部庫,在庫文件中找到ControlCAN.lib文件路徑,不勾選Mac和linux,不勾選爲debug版本添加d做爲後綴

 

四、下一步,肯定。此時已經把路徑加進去了

五、右鍵工程,添加已經存在文件,此時已經默認勾選了ControlCAN.h,肯定便可

 

 

PS:

一、周立功提供的動態庫不少變量類型沒有定義的,好比DWORD,能夠再ControlCAN.h中

#include "windows.h"//windows

#include "windef.h"//linux

二、打開ControlCAN.h時會提醒編碼不正確,選擇system編碼就好了

 

PS:

一、時間標識:CAN盒子接收到當前幀的時間,這個時間是CAN盒子啓動的時間,最小單位是0.1ms,比較準

如何將時間標識轉爲字符串:

QString MyMethod::getTimeStampStr(UINT TimeStamp)

{

QString resultStr = "";

int hour = TimeStamp/36000000;

int minute = (TimeStamp - hour*36000000)/600000;

int second = (TimeStamp - hour*36000000 - minute*600000)/10000;

int ms = (TimeStamp - hour*36000000 - minute*600000 - second*10000)/10;

int mms = (TimeStamp - hour*36000000 - minute*600000 - second*10000 - ms*10);

resultStr = QString("%1:").arg(hour,2,10,QChar('0'));//時

resultStr += QString("%1:").arg(minute,2,10,QChar('0'));//分

resultStr += QString("%1:").arg(second,2,10,QChar('0'));//秒

resultStr += QString("%1:").arg(ms,3,10,QChar('0'));//毫秒

resultStr += QString::number(mms);//0.1ms

return resultStr;

}

二、如何高速CAN通訊

根據我在項目中的實踐,發現利用PC裏能達到的最塊CAN通訊(使用USBCAN-2)速度是1ms,可是須要不少技巧。

①、使用3個線程類:1個用來接收,1個用來發送,1個用來解析

②、接收線程最好使用最高線程權限:QThread::HighestPriority,其餘的用第二高權限(這個根據計算機性能來考慮)

③、如何循環發送報文:在發送線程裏再多加一個定時器(這個定時器不是主界面的,而是發送線程的),定時器timeout時間爲須要循環發送的時間(可達到1ms);

用戶在主界面設置須要發送的報文爲OBJ結構體數組,而後經過狗仔函數的方式傳到發送線程,最後發送就好了。

④、解析過程:接收函數循環接收報文,每接收到n幀就發送到解析線程,而後根據ID解析,將解析數據發送主界面顯示(顯示的時候textedit不要滾動,即不要append,直接替換,不然會卡頓)

 

 

 

 

 

PS:

一、打開兩路CAN:VCI_OpenDevice只能調用一次,而且須要在同一個軟件中使用(dll只能調用一次)

相關文章
相關標籤/搜索