基于QT编写的周立功CAN,可进行uds、bootloder的上位机开发

基于QT编写的解析周立功CAN

1.介绍

应用场景:需要将CAN数据传输到上位机。
可以进行界面显示,做一些基于can的演示系统等

2.封装的模块

1.CanComm.c 中间层 封装通信函数
封装了
可以读取uds报文
可以写入uds报文
可以读取应用报文
可以写入应用报文
2.cantxthread.cpp 中间层 重底层读取
3.canrxthread.cpp 中间层 重底层读取
4.zlgCANFunctions.cpp 底层 周立功库函数封装
5.xlCANFunctions.cpp 底层 周立功库函数封装
6.widget.cpp 应用层

3.基本的一些介绍

底层周立功zlgCANFunctions.cpp 介绍

bool zlgCANFunctions::zlgCANInit(int devtype,unsigned long baud, int canNum)
{
    VCI_INIT_CONFIG init_config;
    int baudTemp;

    m_devtype = devtype;
    m_canind  = canNum;
    m_devind  = 0;

    /* 0x700 ~ 0x7ff */
//    if (0 == canExternFlag)
//    {
//        init_config.AccCode = 0xE0000000;
//        init_config.AccMask = 0x1FFFFFFF;
//    }
//    else
//    {
//        init_config.AccCode = 0x00003800;
//        init_config.AccMask = 0xFFFFC7FF;
//    }

    /* 不滤波 */
    init_config.AccCode = 0x00;//0xE0000000;
    init_config.AccMask = 0xFFFFFFFF;//0x1FFFFFFF;

    /* 0->双滤波 , 1->单滤波 */
    init_config.Filter = 1;
    /* 0->正常模式,1->监听模式 */
    init_config.Mode   = 0;
    switch(baud)
    {
    case 500000://500k
    default:
       if (m_devtype == VCI_USBCAN2)
       {
           init_config.Timing0 = 0x00;
           init_config.Timing1 = 0x1c;
       }
       else if (((m_devtype == VCI_USBCAN_E_U))||((m_devtype == VCI_USBCAN_2E_U)))
       {
           baudTemp = 0x60007;
       }
       break;
    case 250000://250k
        if (m_devtype == VCI_USBCAN2)
        {
            init_config.Timing0 = 0x01;
            init_config.Timing1 = 0x1c;
        }
        else if (((m_devtype == VCI_USBCAN_E_U))||((m_devtype == VCI_USBCAN_2E_U)))
        {
            baudTemp = 0x1c0008;
        }
        break;
    case 125000://125k
        if (m_devtype == VCI_USBCAN2)
        {
            init_config.Timing0 = 0x03;
            init_config.Timing1 = 0x1c;
        }
        else if (((m_devtype == VCI_USBCAN_E_U))||((m_devtype == VCI_USBCAN_2E_U)))
        {
            baudTemp = 0x1c0011;
        }
        break;
    }


    if(VCI_OpenDevice(m_devtype,m_devind,0) != STATUS_OK )
    {
        return false;
    }
    if(VCI_SetReference(m_devtype,m_devind,m_canind,0,&baudTemp)!= STATUS_OK)
    {
        VCI_CloseDevice(m_devtype,m_devind);
        return false;
    }

    if(VCI_InitCAN(m_devtype,m_devind,m_canind,&init_config)!= STATUS_OK)
    {
        VCI_CloseDevice(m_devtype,m_devind);
        return false;
    }
    if(VCI_StartCAN(m_devtype,m_devind,m_canind) != STATUS_OK )
    {
        VCI_CloseDevice(m_devtype,m_devind);
        return false;
    }

    VCI_ClearBuffer(m_devtype,m_devind,0);
    return true;
}

这个底层配置周立功CAN设置,可以自行查看周立功CAN的封装库
需要支持你的CAN卡只需要添加更改这个代码块即可
查看ControlCAN.h 导入相应名称即可

   switch(baud)
    {
    case 500000://500k
    default:
       if (m_devtype == VCI_USBCAN2)
       {
           init_config.Timing0 = 0x00;
           init_config.Timing1 = 0x1c;
       }
       else if (((m_devtype == VCI_USBCAN_E_U))||((m_devtype == VCI_USBCAN_2E_U)))
       {
           baudTemp = 0x60007;
       }
       break;
    case 250000://250k
        if (m_devtype == VCI_USBCAN2)
        {
            init_config.Timing0 = 0x01;
            init_config.Timing1 = 0x1c;
        }
        else if (((m_devtype == VCI_USBCAN_E_U))||((m_devtype == VCI_USBCAN_2E_U)))
        {
            baudTemp = 0x1c0008;
        }
        break;
    case 125000://125k
        if (m_devtype == VCI_USBCAN2)
        {
            init_config.Timing0 = 0x03;
            init_config.Timing1 = 0x1c;
        }
        else if (((m_devtype == VCI_USBCAN_E_U))||((m_devtype == VCI_USBCAN_2E_U)))
        {
            baudTemp = 0x1c0011;
        }
        break;
    }


拿取数据的周期及数据数。这里使用的函数VCI_GetReceiveNum及VCI_Receive
周立功的库开发里面有使用方法

bool zlgCANFunctions::zlgCANRecv()
{
    VCI_CAN_OBJ rec[20];//这里10ms拿取20为拿取的数据数
    int reclen ,i;

    int length = VCI_GetReceiveNum(m_devtype,m_devind,m_canind);

    if(length <= 0)
    {
        return false;
    }

    if(length > 20)
    {
        length = 20;
    }

    mutex.lock();
    if((reclen = VCI_Receive(m_devtype,m_devind,m_canind,rec,length,10))>0)//周期10MS
    {
        for(i = 0; i < reclen; i++)
        {
            COMM_WriteRxMessage(rec[i].ID,rec[i].Data,rec[i].DataLen);
        }
    }
    mutex.unlock();
    return true;
}

可以在这里更改周期等。使用方法如下
在这里插入图片描述
在这里插入图片描述
相应的一些底层配置都在zlgCANFunctions.cpp 这个里面。一些配置都在这里修改。使用方法查看周立功的接口函数的调用方法

CanComm.c中间层 介绍

你需要重can读取数据,就需要把数据放到一个池子里面,然后在周期性的去取数据出来。这里的中间层就起到了一个缓存池的作用

已经封装了多个函数。读应用数据,写应用数据,读uds数据,写uds数据
。这里就可以开发uds、can应用型上位。

/***************************************************************
**	Function Name	:	App_SendAppMsgToCOMM
**	Description		:	插入应用报文到队列中去
**	Input parameters:	NONE
**	Return Value	:	NONE
**	Version			:	V0.1
**	Author			:   WZH
***************************************************************/
void App_SendAppMsgToCOMM(unsigned int can_id,unsigned char *buffer,unsigned char length)
{
    unsigned char i = 0;

    if(!g_tCanAppMsgTx.full)
    {
        g_tCanAppMsgTx.msg[g_tCanAppMsgTx.wr_index].canId = can_id;
        g_tCanAppMsgTx.msg[g_tCanAppMsgTx.wr_index].len = length;
        for( i = 0 ; i < length ; i++)
        {
          g_tCanAppMsgTx.msg[g_tCanAppMsgTx.wr_index].buffer[i] = buffer[i];
        }

        if (++g_tCanAppMsgTx.wr_index >= CAN_MSG_QUEUE_LEN)
        {
            g_tCanAppMsgTx.wr_index = 0;
        }
        if (g_tCanAppMsgTx.wr_index == g_tCanAppMsgTx.rd_index)
        {
            g_tCanAppMsgTx.full = 1;
        }
    }
    if(!g_tCanAllMsg.full)
    {
        g_tCanAllMsg.msg[g_tCanAllMsg.wr_index].canId  = can_id;
        g_tCanAllMsg.msg[g_tCanAllMsg.wr_index].len    = length;
        MemeryCopy(g_tCanAllMsg.msg[g_tCanAllMsg.wr_index].buffer,buffer,8);
        if(++g_tCanAllMsg.wr_index >= CAN_MSG_QUEUE_LEN)
        {
            g_tCanAllMsg.wr_index = 0;
        }
        if(g_tCanAllMsg.wr_index == g_tCanAllMsg.rd_index)
        {
            g_tCanAllMsg.full = 1;
        }
    }
}

4.demo分享

这里提供一个demo 。只需要更改serial.cpp就可以了。

1、https://download.csdn.net/download/a_954710805/13053480

2、https://wwdj.lanzout.com/iDEu20x0dk1i

5.Tsmaster调用库来完成底层库

关注我另外一个文章
https://blog.csdn.net/a_954710805/article/details/130821093?spm=1001.2014.3001.5501

  • 12
    点赞
  • 112
    收藏
    觉得还不错? 一键收藏
  • 6
    评论
### 回答1: LabVIEW是一款用于虚拟仪器控制和数据采集的编程环境,而立功CAN盒则是一种基于控制区域网络(CAN)总线的硬件设备。UDS(Unified Diagnostic Services)是一种用于汽车电子系统诊断的通信协议。 基于立功CAN盒的UDS功能可以在LabVIEW中实现车辆的故障诊断和数据采集。首先,通过连接LabVIEW和立功CAN盒,可以读取车辆上的各种故障码和状态信息。LabVIEW提供了用于CAN总线通信的函数库,可以通过CAN通信协议与立功CAN盒进行数据交互。 在LabVIEW中,可以根据车辆的需求编写UDS协议的相应代码。UDS协议包括了诊断服务请求、响应和报文格式等信息。通过使用LabVIEW的编程功能,可以实现UDS协议中的各种服务功能,如读取故障码、清除故障码、读取实时数据等。 此外,基于立功CAN盒的UDS功能还可以通过LabVIEW实现数据采集。通过CAN总线,LabVIEW可以读取车辆传感器的数据,并将其显示、存储和分析。因此,可以通过LabVIEW的图形化界面来实时监测车辆的信号和参数,并进行数据分析和处理。 综上所述,LabVIEW基于立功CAN盒的UDS功能可以为汽车电子系统提供故障诊断和数据采集的解决方案。通过LabVIEW的编程环境和立功CAN盒的硬件设备,可以实现对车辆的故障诊断和数据采集,以提高车辆的运行效率和安全性。 ### 回答2: LabVIEW是一款强大的可视化编程语言和开发环境,可以用于各种工程和科研项目的设计和实现。基于立功CAN盒的UDS是LabVIEW中的一种应用,用于处理基于CAN总线的统一诊断服务(UDS)。 首先,立功CAN盒是一种常用的CAN总线接口设备,可以与汽车电子控制单元(ECU)进行通信。它通过支持CAN通信协议,允许LabVIEW与车辆的诊断系统进行连接和交互。这使得LabVIEW可以用作车辆的UDS诊断工具。 基于立功CAN盒的UDS应用,使用LabVIEW的编程功能来实现对车辆ECU的诊断和控制。它可以通过CAN总线向ECU发送特定的命令和请求,以获取ECU的信息、诊断故障和执行各种调试任务。 通过LabVIEW的图形化编程界面,用户可以轻松地创建UDS应用程序,并通过CAN盒与车辆的ECU进行通信。LabVIEW提供了丰富的函数库和工具,用于解析和处理UDS通信数据。用户可以根据自己的需求,设计自定义的UDS通信协议,以满足特定的诊断和控制要求。 基于立功CAN盒的UDS应用可以广泛应用于汽车制造商和汽车诊断设备供应商等领域。它可以用于车辆故障排除、ECU参数配置、软件更新和数据采集等任务。通过LabVIEW的灵活性和可靠性,基于立功CAN盒的UDS应用可以更高效地完成车辆的诊断和维护工作,提高了整个汽车制造和维修行业的效率和可靠性。 ### 回答3: LabVIEW是一款基于立功CAN盒的UDS(Unified Diagnostic Services)的软件应用开发环境。UDS是一种通用的车辆诊断协议,用于对车辆进行故障诊断和故障排除。 立功CAN盒是一种硬件设备,用于实现CAN总线通信。它可以连接到车辆的CAN总线上,通过读取和发送CAN消息来实现与车辆各个ECU(Electronic Control Unit)的通信。 LabVIEW作为一款强大的图形化编程工具,可以与立功CAN盒结合使用,通过UDS协议与车辆进行数据交互。LabVIEW提供了一系列的CAN相关的工具和函数,使得开发人员可以轻松地与车辆进行通信。 使用LabVIEW基于立功CAN盒的UDS,开发人员可以实现以下功能: 1. 读取车辆的诊断数据:LabVIEW可以通过UDS协议向车辆的ECU发送指令,以读取车辆的诊断数据,例如故障码、传感器数据等。 2. 发送控制指令:LabVIEW可以通过UDS协议向车辆的ECU发送控制指令,例如修改参数、执行复位等操作,实现对车辆的远程控制。 3. 实时监测:LabVIEW基于立功CAN盒的UDS可以实时监测车辆的各个ECU的状态和数据,以帮助开发人员进行故障诊断和性能优化。 总而言之,LabVIEW基于立功CAN盒的UDS为开发人员提供了一个强大的工具,使他们能够轻松地与车辆进行通信,并进行诊断和控制操作。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值