上位机开发1
QT环境:
1、环境搭建
需要用到周立功 相关接口,拿到库文件,进行二次开发
使用以下文件
新建立一个工程,或者网找一个demo工程,在原有的基础进行开发(建议使用第二种)。
并链接上这个库,进行can通信开发。
以下就是库,暴露出来can通信接口
具体接口使用可以看文档。
2、CAN通信开发
目标:以500k/s的波特率与MCU进行CAN通信,可发可收。
CAN通信对象:
class Thread : public QThread
{
Q_OBJECT
public:
Thread();
void stop();
void OpenCANThread();
void CloseCANThread();
void ReceiveCANThread();
void TransmitCANThread();
//void OtaStart();
public:
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);
typedef DWORD(__stdcall VCI_SetReference)(DWORD DeviceType,DWORD DeviceInd,DWORD CANInd,DWORD RefType,PVOID pData);
typedef DWORD(__stdcall VCI_ReadBoardInfo)(DWORD DeviceType,DWORD DeviceInd,PVCI_BOARD_INFO pInfo);
int devtype;//设备类型号
int devind;//设备索引号
int res;//保留参数,通常为0
int canind;//第几路can
int reftype;//参数类型
VCI_Transmit *pTransmitCAN;
VCI_Receive *pReceive;
protected:
void run();
private:
volatile bool stopped;
VCI_OpenDevice *pOpenDevice;
VCI_ResetCAN *pResetCAN;
VCI_CloseDevice *pCloseDevice;
VCI_InitCAN *pInitCAN;
VCI_StartCAN *pStartCAN;
VCI_GetReceiveNum *pGetReceiveNum;
VCI_ClearBuffer *pClearBuffer;
VCI_ReadErrInfo *pReadErrInfoCAN;
VCI_ReadCANStatus *pReadCANStatus;
VCI_SetReference *pSetReference;
VCI_ReadBoardInfo *pReadBoardInfo;
};
初始化
devtype=VCI_USBCAN2;//设备类型USBCAN2
devind=0;//设备索引号
res=0;
canind=0;//CAN通道0
reftype=0;//参数类型
bool ok;
VCI_ERR_INFO vei;
VCI_CAN_OBJ preceive[100];
VCI_CAN_OBJ psend;
int baud=0x10000000;//参数有关数据缓冲区地址首指针
//导入库
QLibrary lib("usbcan.dll");
if(true==lib.load())
qDebug()<<"usbcan.dll load ok";
hander_init();
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");
pResetCAN=(VCI_ResetCAN *)lib.resolve("VCI_ResetCAN");
pSetReference=(VCI_SetReference *)lib.resolve("VCI_SetReference");
pReadBoardInfo=(VCI_ReadBoardInfo *)lib.resolve("VCI_ReadBoardInfo");
pReadCANStatus=(VCI_ReadCANStatus *)lib.resolve("VCI_ReadCANStatus");
打开CAN通道
VCI_ERR_INFO vei;
VCI_CAN_OBJ preceive[100];
VCI_CAN_OBJ psend;
int baud=0x10000000;//参数有关数据缓冲区地址首指针
//打开设备
if(pOpenDevice(devtype,devind,res)==STATUS_ERR )
{
if(pReadErrInfoCAN(devtype,devind,canind,&vei)!=STATUS_ERR)
{
qDebug()<<"打开失败:"<<QString::number(vei.ErrCode,16);
}else
qDebug()<<"error";
return;
}else
qDebug()<<"open successed";
//初始化
VCI_INIT_CONFIG init_config;
init_config.Mode=0;//0正常模式,1为只听模式
init_config.Filter=1;//滤波方式,单滤波
init_config.Timing0=0x00;//定时器0
init_config.Timing1=0x1c;//定时器1
init_config.AccCode=0x10000000;//验收码
init_config.AccMask=0xFFFFFFFF;//屏蔽码全部接收
if(pInitCAN(devtype,devind,canind,&init_config)==STATUS_ERR){
qDebug("Init Error");
pCloseDevice(devtype,devind);
return;
}else
qDebug()<<"Init successed";
//读取设备信息
VCI_BOARD_INFO vbi;
if(pReadBoardInfo(devtype,devind,&vbi)!=STATUS_ERR){
qDebug()<<"CAN通道数:"<<vbi.can_Num;
qDebug()<<"硬件版本号:"<<vbi.hw_Version;
qDebug()<<"接口库版本号:"<<vbi.in_Version;
qDebug()<<"中断号"<<vbi.irq_Num;
}
//设置设备参数
if(pSetReference(devtype,devind,canind,reftype,&baud)==STATUS_ERR){
qDebug("set reference error");
pCloseDevice(devtype,devind);
return;
}
//清除缓冲区
pClearBuffer(devtype,devind,canind);
//启动设备
if(pStartCAN(devtype,devind,canind)==STATUS_ERR){
qDebug()<<"start fail";
pCloseDevice(devtype,devind);
return;
}else
qDebug()<<"start successed";
选择正常模式、单滤波、500kbps、报文全接收
数据发送:
VCI_CAN_OBJ psend;
//发送
ULONG Tr;
QString buffer = "";
psend.ID=0x000007d1;
psend.SendType=0;
psend.RemoteFlag=0;
psend.ExternFlag=0;
psend.DataLen=3;
psend.Data[0]=0x02;
psend.Data[1]=0x10;
psend.Data[2]=0x01;
if(psend.DataLen < 8)
{
for(int i = psend.DataLen;i < 8 ;i++)
{
psend.Data[i] = 0xAA;
}
psend.DataLen = 8;
}
Tr=pTransmitCAN(devtype,devind,canind,&psend,1);
数据接收
res=pGetReceiveNum(devtype,devind,canind);
if(res > 0)
{
res=pReceive(devtype,devind,canind,preceive,50,200);
for(int i=0;i<res;i++)
{
frame_re.fr_format = CBUS_FR_FRM_STD;
frame_re.id_type = CBUS_ID_T_STANDARD;
frame_re.dlc = preceive[i].DataLen;
frame_re.id = preceive[i].ID;
memcpy(frame_re.dt, preceive[i].Data, frame_re.dlc);
iso15765_enqueue(&handler_15765, &frame_re);
}
}
3、UI设计
目标:
CAN设备:通道开启和关闭
升级文件:文件路径
OAT:升级进度