做一个USBCAN总线的shan上位机,使用周立功提供的SDK。要有参数设置的xu选项、接发数据、数据过滤等功能。
我这边的CAN卡型号是USBCAN_4E_U,所以要使用USBCAN_4E_U这个dll。使用周立功提供的哪个dll,是根据你的CAN卡来决定的。周立功提供的vs2008编写的MFC例子会起到一定的误解。因为那个例子直接使用了ControlCAN这个dll。在进行类型设置的时候选择了31,也就是USBCAN_4E_U这个dll。而Qt用这样的方法不行。
首先是Qt调用第三方的dll。有显示和隐式2种方式。我这边使用了显示调用。剩下的就是加入头文件,然后定义函数指针。然后根据周立功提供的开发文档进行相应的开发。开发文档对每个函数的使用和参数的含义做了详细的解释。
做对应开发的情况下,看你编译器的版本,如果是64位,就选择64位的dll。如果是32位就选择32位的版本。大家千万别用错了,然后找不到原因。
配置方面大家可以参考这篇文章:https://www.cnblogs.com/judes/p/6952079.html
CAN的通讯都放在线程里,通过信号与槽与UI界面进行交互
void DataThread::transmitCanThread(QString idStr, QString chStr, int sendFrameTypeInt)
{
if(m_connect == false)
{
return;
}
char* id = idStr.toLatin1().data();
char* ch = chStr.toLatin1().data();
//QByteArray id = idStr.toLatin1();
//QByteArray ch = chStr.toLatin1();
VCI_CAN_OBJ frameinfo;
char szFrameID[9];
unsigned char FrameID[4]={0,0,0,0};
memset(szFrameID,'0',9);
unsigned char Data[8];
char szData[25];
BYTE datalen=0;
if(strlen(id) > 8)
{
qDebug() << "ID值超过范围...";
emit sendStateInfoToUI("ID值超过范围...");
return;
}
if(strlen(ch) > 24)
{
qDebug() << "数据长度超过范围,最大为8个字节...";
emit sendStateInfoToUI("数据长度超过范围,最大为8个字节...");
return;
}
if(sendFrameTypeInt == 0)
{
if(strlen(ch) % 3 == 1)
{
qDebug() << "数据格式不对,请重新输入...";
emit sendStateInfoToUI("数据格式不对,请重新输入...");
return;
}
}
memcpy(&szFrameID[8- strlen(id)],id,strlen(id));
strtodata((unsigned char*)szFrameID,FrameID,4,0);
datalen=(strlen(ch)+1)/3;
//strcpy(szData,(LPCTSTR)ch);
strcpy(szData,ch);
strtodata((unsigned char*)szData,Data,datalen,1);
frameinfo.DataLen = datalen;
memcpy(&frameinfo.Data,Data,datalen);
frameinfo.RemoteFlag = m_remoteFlag;
frameinfo.ExternFlag = m_externFlag;
if(frameinfo.ExternFlag==1)
{
frameinfo.ID=((DWORD)FrameID[0]<<24)+((DWORD)FrameID[1]<<16)+((DWORD)FrameID[2]<<8)+
((DWORD)FrameID[3]);
}
else
{
frameinfo.ID=((DWORD)FrameID[2]<<8)+((DWORD)FrameID[3]);
}
frameinfo.SendType=m_sendType;
int ret = pTransmitCAN(m_devtype,m_devind,m_canind,&frameinfo,1);
if(ret==1)
{
qDebug() << "写入成功...";
emit sendStateInfoToUI("写入成功...");
}
else
{
qDebug() << "写入失败...";
emit sendStateInfoToUI("写入失败...");
}
}
void DataThread::resetCanThread()
{
if(m_connect == false)
{
return;
}
if(pResetCAN(m_devtype,m_devind,m_canind) == STATUS_ERR)
{
qDebug() << "复位失败";
emit sendStateInfoToUI("复位失败");
pCloseDevice(m_devtype,m_devind);
}
else
{
qDebug() << "复位成功";
emit sendStateInfoToUI("复位成功");
}
}
void DataThread::run()
{
while(!m_stopped)
{
receiveCanThread();
}
m_stopped = false;
}
链接:https://pan.baidu.com/s/1rGvkr4qMg9UypjqV_yFdyg
提取码:0oac