基于QT的CAN通讯数据实时波形显示(连载二)========“CAN文件添加”

    前述工作:

    (1)将二次开发的h文件和lib文件拷入pro的文件夹,如图:

    (2)将dll文件拷入debug文件夹下,同时需要将kerneldlls文件夹放入debug文件夹下,与exe文件同一个文件夹。如图:

        昨天由于kerneldlls文件夹没有放入debug文件夹下,导致程序功能不能正常运行。即:

FLAG = VCI_OpenDevice(nDeviceType,nDeviceInd,nReserved);

     调用打开can口命令后,可以编译,可以运行,但是FLAG就是一直是FALSE,说明can口没有打开。找了很多资料后,确定是:不能仅仅将kerneldlls文件夹下的usbcan.dll文件放到debug文件夹下,而是要将kerneldlls文件夹整体放在debug文件夹下,这样程序才能正确调用,并顺利打开can口。

    (3)添加h文件,如图:

    这个是基本操作,就不再说怎么添加controlcan的h文件的了。

    (4)添加库文件。添加后如图所示,win32行。注意必须是x86文件夹下的dll,h和lib。添加x64后会发生错误。

    (5)修改controlcan.h文件,由于数据类型不同,需要添加在其头部添加#include "windows.h",并且选择sleect encoding,选择system。这个仅仅是汉字的问题,用系统自带的就好。

     这样程序就能正确编译和运行了。

第一部分:启动和运行can口

    (1)先搞两个按钮在ui界面,一个打开can,一个运行can。添加槽函数。目的:打开can按钮按下,打开can口和初始化can口;运行can按钮按下,运行can口。

    (2)参数初始化:其实不用知道啥意思,知道等于多少就行。我用的usbcan2,第一个参数就等于4。这个查阅下载的pdf就行。

         最后一个是结构体,为啥那么下,下载的pdf里面有例程,直接拿过来就好。,然后初始化结构体里面的参数。

    里面的具体意义查阅pdf,这个里面介绍的很详细,并且耐着性子看,这个非常重要,好好的看一遍,反正没几页,挺容易就熬过来了。其实当你把h文件还有dll文件加载好之后,后面的参数都会自己给你联想出来,非常的方便。这几个参数是设置波特率,掩码还有模式啥的,和你的can通讯协议一致就好(can发送不能模拟,只能老老实实的通过硬件和can盒连接到电脑上,并且发送固定的数据)。

    (3)初始执行代码

void MainWindow::on_OPEN_clicked()
{
    FLAG = VCI_OpenDevice(nDeviceType,nDeviceInd,nReserved);
    qDebug()<<FLAG;
    FLAG = VCI_InitCAN(nDeviceType,nDeviceInd,nCANInd,&InitCan);
    qDebug()<<FLAG;
}

    这是打开can按钮的槽函数,点击一下就open 和 init can口了。这个函数只能执行一次。同时打印出来的debug都是true。两个true。确定是open成功,并且init成功。

void MainWindow::on_START_clicked()
{
    FLAG = VCI_StartCAN(nDeviceType,nDeviceInd,nCANInd);
    qDebug()<<FLAG;
}

    这是运行can按钮的槽函数,点击一下就运行can口了。执行之前,can盒上的灯是红色的,执行之后就变成了绿色,并且闪烁周期和你的can接收周期一样(取决于你用的哪个can盒,会有不同)。打印出来的debug是true,说明can口启动成功。可以正确的接收和发送数据了。

第二部分:接收数据

    添加接收按钮,添加槽函数。界面如下:

        测试代码如下:可以打印出接收数据100个。至于receive函数怎么用法,可以好好看看debug。现在我也不是很明白100和400的意义,有待于进一步改写数字加以确定。

    ReceiveNum = VCI_Receive(nDeviceType,nDeviceInd,nCANInd,Receive,100,400);
    qDebug()<<ReceiveNum;

    只要打印出来的数据不是FFFF,就可以保证can帧是可以正产接收的。

    然后加入接收代码:测试代码时应该已经添加,这里顺序有点乱了。为了整体介绍,暂且放到后面。

public:
    int ReceiveNum;
    VCI_CAN_OBJ Receive[100];

    其中num是接收个数,下面是个结构体,接收的100个结构体数据,就是说这100个数据中的单单1个数据就包含了很多信息,其中有ID号,帧的格式,还有帧的长度,帧的数据。换句话说receive[0]里面有receive[0].ID,还有receive[0].data[0]到receive[0].data[7],具体看程序:

    int strCANID;
    int strFormat;
    int strType;
    int strLen;
    int strData[8];
    for (int i = 0; i < ReceiveNum; i++)
    {

        strCANID = Receive[i].ID;
        strFormat= Receive[i].RemoteFlag;
        strType  = Receive[i].ExternFlag;
        strLen   = Receive[i].DataLen;
        strData[0]  = Receive[i].Data[0];
        strData[1]  = Receive[i].Data[1];
        strData[2]  = Receive[i].Data[2];
        strData[3]  = Receive[i].Data[3];
        strData[4]  = Receive[i].Data[4];
        strData[5]  = Receive[i].Data[5];
        strData[6]  = Receive[i].Data[6];
        strData[7]  = Receive[i].Data[7];
    }

    Receive数组是个结构体的数组,可以将其中的值赋给我们定义好的int值,在传输can帧的时候一般都是固定的,远程帧也是固定的,扩展帧也是固定的,就是除了数据帧之外,其他的帧基本都是固定的。将结构体中的值赋给定义的变量,就可以将变量取出进行自己的设计了。

    for (int i = 0; i < ReceiveNum; i++)
    {

        strCANID = Receive[i].ID;
        strFormat= Receive[i].RemoteFlag;
        strType  = Receive[i].ExternFlag;
        strLen   = Receive[i].DataLen;
        strData[0]  = Receive[i].Data[0];
        strData[1]  = Receive[i].Data[1];
        strData[2]  = Receive[i].Data[2];
        strData[3]  = Receive[i].Data[3];
        strData[4]  = Receive[i].Data[4];
        strData[5]  = Receive[i].Data[5];
        strData[6]  = Receive[i].Data[6];
        strData[7]  = Receive[i].Data[7];

        qDebug()<<strData[0]<<strData[1]<<strData[2]<<strData[3]<<strData[4]<<strData[5]<<strData[6]<<strData[7];
 
    }

    加入数据段打印行。每个receive打印一次,打印8个8位,然后打印100次。经过测试,输出的值和自定义在can链路上的数据一致。可以基本确定程序执行是正确的。

第三部分:结论

    (1)可以保证can口设置,打开,和接收数据的正确性。中间走了不少弯路,一方面百度了很多东西,从一个一个中寻找自己需要的信息,并且加以试验,另一方面给的例程中可以借鉴一部分书写方法,还有一方面就是下载的函数说明pdf。

    (2)完全在一个未知的领域搞自己不熟悉的东西,很痛苦,并且搞不出来更痛苦。只能静下心一点一点的按照自己的逻辑一块一块的实现功能,一步一步的去调试,没啥捷径可走。

    (3)代码时别人编写的,说明肯定能调试通过,肯定是有方法去弄出来的,不能心急,越急越没有办法弄出来。pdf和参考网页都是攻城狮的心血,需要借鉴过来,都是很宝贵的,能节省你的不少时间。

第四部分:展望

    只能利用按钮接收一次数据,估计需要线程,自定义线槽去接收全部数据,又是一个全新的知识。只能硬着头皮继续搞。

    注:由于小伙伴需要源代码的时间不同,登录邮箱界面太多麻烦,所以建立了一个订阅号,如果有问题或者需要源码,可添加订阅号,留言后会发送源代码或者有任何问题可留言,将积极解决提出的问题。

​​​​​​​

 

  • 6
    点赞
  • 33
    收藏
    觉得还不错? 一键收藏
  • 29
    评论
评论 29
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值