基于CAN总线的汽车诊断协议UDS(上位机开发驱动篇)

Posted qq2020809663

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了基于CAN总线的汽车诊断协议UDS(上位机开发驱动篇)相关的知识,希望对你有一定的参考价值。

本篇作为UDS上位机的驱动开发篇,从市面上多见的CAN分析仪着手介绍UDS上位机驱动开发和移植的一般过程,目的是使UDS上位机软件能适应多家CAN分析仪,降低使用者的硬件成本。

一:广成CAN分析仪的驱动开发

首先创建ECANDLL类,从广成提供的二次开发包中获取ECANVCI.dll文件,将DLL文件放置与生成程序的目录中,如下类中创建了CAN常用的控制函数。

    public static class ECANDLL

    {

 

        [DllImport("ECANVCI.dll", EntryPoint = "OpenDevice")]

        public static extern ECANStatus OpenDevice(

            UInt32 DeviceType,

            UInt32 DeviceInd,

            UInt32 Reserved);

 

        [DllImport("ECANVCI.dll", EntryPoint = "CloseDevice")]

        public static extern ECANStatus CloseDevice(

            UInt32 DeviceType,

            UInt32 DeviceInd);

 

 

        [DllImport("ECANVCI.dll", EntryPoint = "InitCAN")]

        public static extern ECANStatus InitCAN(

            UInt32 DeviceType,

            UInt32 DeviceInd,

            UInt32 CANInd,

            ref INIT_CONFIG InitConfig);

 

 

        [DllImport("ECANVCI.dll", EntryPoint = "StartCAN")]

        public static extern ECANStatus StartCAN(

            UInt32 DeviceType,

            UInt32 DeviceInd,

            UInt32 CANInd);

 

 

        [DllImport("ECANVCI.dll", EntryPoint = "ResetCAN")]

        public static extern ECANStatus ResetCAN(

            UInt32 DeviceType,

            UInt32 DeviceInd,

            UInt32 CANInd);

 

 

        [DllImport("ECANVCI.dll", EntryPoint = "Transmit")]

        public static extern ECANStatus Transmit(

            UInt32 DeviceType,

            UInt32 DeviceInd,

            UInt32 CANInd,

            ref CAN_OBJ Send,

            UInt16 length);

 

 

        [DllImport("ECANVCI.dll", EntryPoint = "Receive")]

        public static extern ECANStatus Receive(

            UInt32 DeviceType,

            UInt32 DeviceInd,

            UInt32 CANInd,

            out CAN_OBJ Receive,

            UInt32 length,

            UInt32 WaitTime);

 

        [DllImport("ECANVCI.dll", EntryPoint = "ReadErrInfo")]

        public static extern ECANStatus ReadErrInfo(

            UInt32 DeviceType,

            UInt32 DeviceInd,

            UInt32 CANInd,

            out CAN_ERR_INFO ReadErrInfo);

 

    }

在MainForm中,针对不同的控件调用不同的控制函数

如初始化:

INIT_CONFIG init_config = new INIT_CONFIG();

 

                    init_config.AccCode = 0;

                    init_config.AccMask = 0xffffff;

                    init_config.Filter = 0;

 

                    switch (m_Baudrate)

                    {

                        case 0: //1000

 

                            init_config.Timing0 = 0;

                            init_config.Timing1 = 0x14;

                            break;

                        case 1: //800

 

                            init_config.Timing0 = 0;

                            init_config.Timing1 = 0x16;

                            break;

                        case 2: //666

 

                            init_config.Timing0 = 0x80;

                            init_config.Timing1 = 0xb6;

                            break;

                        case 3: //500

 

                            init_config.Timing0 = 0;

                            init_config.Timing1 = 0x1c;

                            break;

                        case 4://400

 

                            init_config.Timing0 = 0x80;

                            init_config.Timing1 = 0xfa;

                            break;

                        case 5://250

 

                            init_config.Timing0 = 0x01;

                            init_config.Timing1 = 0x1c;

                            break;

                        case 6://200

 

                            init_config.Timing0 = 0x81;

                            init_config.Timing1 = 0xfa;

                            break;

                        case 7://125

 

                            init_config.Timing0 = 0x03;

                            init_config.Timing1 = 0x1c;

                            break;

                        case 8://100

 

                            init_config.Timing0 = 0x04;

                            init_config.Timing1 = 0x1c;

                            break;

                        case 9://80

 

                            init_config.Timing0 = 0x83;

                            init_config.Timing1 = 0xff;

                            break;

                        case 10://50

 

                            init_config.Timing0 = 0x09;

                            init_config.Timing1 = 0x1c;

                            break;

 

                    }

 

                    init_config.Mode = 0;

                   

                    if (ECANDLL.OpenDevice(m_devtype, m_devind, 0) != ECAN.ECANStatus.STATUS_OK)

                    {

                        MessageBox.Show("Open device fault!", "Error!", MessageBoxButtons.OK, MessageBoxIcon.Error);

                        return;

                    }

                    //Set can1 baud

                    if (ECANDLL.InitCAN(m_devtype, m_devind, 0, ref init_config) != ECAN.ECANStatus.STATUS_OK)

                    {

 

                        MessageBox.Show("Init can fault!", "Error!", MessageBoxButtons.OK, MessageBoxIcon.Error);

 

                        ECANDLL.CloseDevice(1, 0);

                        return;

                    }

 

二:周立功CAN分析仪驱动开发

                周立功的CAN分析仪与广成基本相同,将DLL文件替换为周立功的DLL文件。在初始化和其他调用函数中注意m_devtype和m_devind与广成的不同,这两个变量的取值可通过不同厂家的测试软件中获取。

一般的广成m_devtype =1,m_devind=0,周立功USBCAN II m_devtype =4,m_devind=0.

ECANDLL.OpenDevice(m_devtype, m_devind, 0)

 

三:Kvaser CAN分析仪驱动开发

Kvaser CAN驱动开发与上述两者差别较大。

首先引入驱动DLL文件

 

 

以下是初始化过程

               int hnd = Canlib.canOpenChannel(channel, Canlib.canOPEN_ACCEPT_VIRTUAL);

 

                CheckStatus("Open channel", (Canlib.canStatus)hnd);

                if (hnd >= 0)

                {

                    handle = hnd;

                }

 

                int[] bitrates = new int[] {

                Canlib.BAUD_1M,

                Canlib.BAUD_500K,

                Canlib.BAUD_250K,

                Canlib.BAUD_125K,

                Canlib.BAUD_100K,

                Canlib.BAUD_83K,

                Canlib.BAUD_62K,

                Canlib.BAUD_50K,

                };

                int bitrate = bitrates[comboBoxBaud.SelectedIndex];

                Canlib.canStatus status = Canlib.canSetBusParams(handle, bitrate, 0, 0, 0, 0, 0);

                CheckStatus("Setting bitrate to " + comboBoxBaud.SelectedItem, status);

 

 

                Canlib.canBusOn(handle);

 

                CheckStatus("Bus on", status);

                    if (status == Canlib.canStatus.canOK)

                    {

                        onBus = true;

                        /*

                        if (!dumper.IsBusy)

                        {

                            dumper.RunWorkerAsync();

                        }*/

                    }

写CAN报文函数

Canlib.canStatus status = Canlib.canWrite(handle, id, dat, dlc, flags);

读CAN报文函数

status = Canlib.canReadWait(handle, out id, dat, out dlc, out flags, out time, 50);

以上是关于基于CAN总线的汽车诊断协议UDS(上位机开发驱动篇)的主要内容,如果未能解决你的问题,请参考以下文章

如何看懂UDS诊断报文

如何看懂UDS诊断报文

如何看懂UDS诊断报文

如何看懂UDS诊断报文

CAN总线在OSI模型中层级

详解UDS CAN诊断:什么是UDS(ISO 14229)诊断?