UDS升级入门,手把手教你——QT上位机开发1

本文介绍了如何在QT环境下进行上位机开发,特别是针对UDS升级和CAN通信的实现。首先,讲解了QT环境的搭建,包括使用周立功的库文件进行二次开发。接着,详细阐述了CAN通信的开发步骤,如初始化、设置波特率以及数据的发送和接收。最后,提到了UI设计的目标,包括CAN设备的通道控制和升级文件的选择,以及OAT升级进度的显示。
摘要由CSDN通过智能技术生成

上位机开发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:升级进度
在这里插入图片描述

LabVIEW是一款强大的图形化编程软件,可以用于开发各种应用程序,包括上位机应用程序。UDS(Unified Diagnostic Services)是一种用于诊断汽车电子系统的通信协议。在LabVIEW中,你可以使用各种工具和组件来开发UDS上位机应用程序。 首先,你需要使用LabVIEW提供的串口通信工具来与车辆的诊断接口进行通信。你可以选择使用NI-VISA(Virtual Instrument Software Architecture)库中的串口VISA函数进行通信。该函数集提供了方便的函数来配置串口参数、发送和接收数据。 然后,你可以创建一个用户界面来显示诊断结果和控制命令。LabVIEW提供了丰富的用户界面设计工具,包括控件和面板编辑器,可帮助你创建直观和交互式的界面。你可以添加按钮、指示灯、图表等控件来显示和控制诊断过程。 接下来,你需要根据UDS协议规范实现相应的功能。你可以使用LabVIEW的数据处理和逻辑控制功能来解析和生成UDS消息。根据需要,你可以使用LabVIEW的文件读写功能来保存和加载诊断数据。 最后,你可以使用LabVIEW的调试和测试工具来验证和优化你的UDS上位机应用程序。LabVIEW提供了强大的调试功能,包括断点、单步执行等,可帮助你定位和修复问题。 总之,使用LabVIEW开发UDS上位机应用程序可以帮助你快速构建功能强大且易于使用的诊断工具。希望这个回答对你有帮助!如果你有任何进一步的问题,请随时提问。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小昭dedug

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值