当前位置: 首页 > article >正文

创芯科技USB_CAN【库文件】

只用到【只收】【只发】功能

23.11.18

using help;
//using Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.NetworkInformation;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Security.Cryptography;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;


// 1先引用  CAN_namespace   用于参数类型 //  using USB_CAN;
// 2再引用 help的方法

namespace CAN_namespace
{
    #region 全局类型【声明】:通讯接口
    /// <summary>
    /// 全局类型:通讯接口
    /// </summary>
    public interface Iface_RTX  // 开,关,收,发,轮询
    {
        /// <summary>
        /// 连接
        /// </summary>
        /// <typeparam name="T">连接</typeparam>
        /// <param name="a">ip地址</param>
        /// <param name="b">端口</param>
        /// <returns></returns>
        bool connect<T>(T a, T b);

        /// <summary>
        /// 断开
        /// </summary>
        /// <returns></returns>
        bool Close();

        /// <summary>
        /// 只收
        /// </summary>
        /// <returns></returns>
        int RXs(ref object obj);
        //int RXs<T>(ref T obj);//测试

        /// <summary>
        /// 只发,格式148报文
        /// </summary>
        /// <param name="cmd"></param>
        /// <returns></returns>
        bool TXs(string cmd);

        /// <summary>
        /// 轮询
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="cmd"></param>
        /// <param name="t"></param>
        /// <returns></returns>
        bool sendAndReceive<T>(string cmd, ref T t);//万物皆文本

    }
    #endregion
    #region 对象
    public class Help_USB_CAN : Iface_RTX
    {//作者qq750273008 祁成  更新日期:2023.11.13
        //===============================================
        //[Browsable(true)]    //可浏览
        //[Category("自定义属性")]   // 属性分栏
        //[Description("属性的说明")]   //
        //================================================
        #region 全局
        //1申明委托》委托命令
        public delegate void WT_GET_Data<T>(T ciA402);//↑ui显示发送命令
        public delegate void WT_SET_Data(byte[] butes, string data);//↓下执行对象

        #region CAN参数类型:全局;【设备类型,主板信息,单帧信息,配置表



        /*------------兼容ZLG的数据类型---------------------------------*/
        //1.设备类型
        /// <summary>
        /// 设备类型(单路,双路,以太网CAN)
        /// </summary>
        public enum DeviceType : byte   //设备类型【USB的【单路,双路】,以太网的【单路,双路】can】
        {
            DEV_USBCAN = 3, // USB单路CAN
            DEV_USBCAN2 = 4,// USB双路CAN

            VCI_USBCAN1 = 3,
            VCI_USBCAN2 = 4,// 我买的属于这个(创新科技CAN-Pro)
            VCI_USBCAN2A = 4,
            VCI_USBCAN_E_U = 20,// 以太网单路CAN
            VCI_USBCAN_2E_U = 21// 以太网双路CAN
        }
        //设备类型
        public enum CAN设备类型 : int
        {
            DEV_USBCAN = 3, // USB单路CAN
            DEV_USBCAN2 = 4,// USB双路CAN

            VCI_USBCAN1 = 3,
            VCI_USBCAN2 = 4,
            VCI_USBCAN2A = 4,
            VCI_USBCAN_E_U = 20,// 以太网单路CAN
            VCI_USBCAN_2E_U = 21// 以太网双路CAN

        }

        //2.ZLGCAN系列接口卡信息的数据类型。
        /// <summary>
        /// 主板设备【31F01031C93】v3.41  VCI_ReadBoardInfo
        /// </summary>
        public struct VCI_BOARD_INFO //主板信息
        { // VCI_ReadBoardInfo【要先运行VCI_OpenDevice(4,0,0);】   VCI_FindUsbDevice2
            public UInt16 hw_Version;//【0x0900】硬件版本,比如0x0100表示V1.00。
            public UInt16 fw_Version;//【0x0341】固件版本,v3.41
            public UInt16 dr_Version;//【0x0900】驱动版本,
            public UInt16 in_Version;//【0x0905】接口版本,
            public UInt16 irq_Num;//   【0x00】  保留参数。
            public byte can_Num;  //   【0x02】  表示有几路CAN通道。
            [MarshalAs(UnmanagedType.ByValArray, SizeConst = 20)]
            public char[] str_Serial_Num;// 板卡序列号。【31F01031C93】

            [MarshalAs(UnmanagedType.ByValArray, SizeConst = 40)]
            public char[] str_hw_Type;// 硬件类型【55 53 42 43 41 4e 2d 49 49】“USBCAN-II”

            [MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)]
            public UInt16[] Reserved;// 系统保留。
        }

        //2-1.USB-CAN总线适配器板卡信息的数据类型1,该类型为VCI_FindUsbDevice函数的返回参数。
        /// <summary>
        /// USB-CAN设备主板信息,该类型为VCI_FindUsbDevice函数的返回参数。
        /// </summary>
        public struct VCI_BOARD_INFO1 // 读取USB主板信息 设备【31F01031C93】v3.41
        {// VCI_FindUsbDevice

            public UInt16 hw_Version;//【0x0900】 硬件版本,0x0100表示V1.00。 // 
            public UInt16 fw_Version;//【0x0341】 固件版本,v3.41, 
            public UInt16 dr_Version;//【0x0900】 驱动版本,
            public UInt16 in_Version;//【0x0905】 接口版本, 
            public UInt16 irq_Num;//   【0x0000】 保留参数。
            public byte can_Num;//     【0x02】   表示有几路CAN通道。
            public byte Reserved;//    【0x00】   保留。
            [MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)]
            public char[] str_Serial_Num;// 此板卡的序列号。【43 41 4e 2d 31 43 39 33】"CAN-1C93"

            [MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)]
            public char[] str_hw_Type;// 硬件类型“USBCAN V1.00”【55 53 42 43 41 4e 2d 49 49】"USBCAN-II"

            [MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)]
            public char[] str_Usb_Serial;// 序列号【31 43 39 33】// "1C93"
        }
        //3.定义CAN每帧的数据类型。
        /// <summary>
        /// CAN的每一帧详细信息(每帧对象)
        /// </summary>
        public unsafe struct VCI_CAN_OBJ  //CAN每帧对象,
        {
            public uint ID;// 帧ID。        【u32】帧id,数据格式为靠右对齐。 详情请参照: 《8.附件1: ID对齐方式.pdf》说明文档。
            public uint TimeStamp;        //【u32】设备时间标识。 时间标示从CAN卡上电开始计时,计时单位为0.1ms。
            public byte TimeFlag;         //是否使用时间标识,=1时TimeStamp有效
            public byte SendType;         //发送类型。=0时为正常发送(重发超时时间为1秒,1秒内没有发出则取消);=1时为单次发送
            public byte RemoteFlag;       //是否远程帧标志。 =0时为数据帧, =1时为远程帧(数据段空)。
            public byte ExternFlag;       //是否扩展帧标志。 =0时为标准帧(11位ID), =1时为扩展帧(29位ID)。
            public byte DataLen;          //有效字节 DLC (<=8),即CAN帧Data有几个字节。约束了后面Data[8]中有效字节数。
            public fixed byte Data[8];    //数据包,如DataLen定义为3,即Data[0]、 Data[1]、 Data[2]是有效的。
            public fixed byte Reserved[3];//系统保留。
        }

        //4.定义配置CAN的数据类型
        /// <summary>
        /// USB-CAN2、配置表(参数表)
        /// </summary>
        public struct VCI_INIT_CONFIG // 配置参数 设备【31F01031C93】v3.41
        {
            public UInt32 AccCode;// bit全部匹配,此帧才可以被接收。否则不能接收。(//标准帧右移21bit分析)
                                  // 相当于机械钥匙,凸起和凹槽必须匹配,才能开锁(接收)
                                  // b31对应帧id最高位,所以11bit要左移21bit(//分析标准帧时右移21bit)
            public UInt32 AccMask;// 屏蔽码。使AccCode的某个bit功能失效。左对齐,bit31~bit21置1为屏蔽AccCode的bit匹配功能,
                                  // 相当于机械钥匙的bit销位,是否失效(bit置1为失效)
                                  // 。屏蔽码推荐设置为0xFFFFFFFF,即全部接收。
            public UInt32 Reserved;// 保留。
            public byte Filter;   // 1接收所有帧。2只收标准帧,3只收扩展帧。
            public byte Timing0;  //波特率参数,具体配置,请查看二次开发库函数说明书。(1Mbps):《Timing0=0x00,Timing1=0x14》
            public byte Timing1;    // 0x14       波特率参数 1MHz(T0=0x00,T1=0x14)
            public byte Mode;     //模式,0表示正常模式,1表示只听模式,2自测模式(环回模式)。
        }
        /*------------其他数据结构描述---------------------------------*/
        public struct CHGDESIPANDPORT // 扩展端口?
        {
            [MarshalAs(UnmanagedType.ByValArray, SizeConst = 10)]
            public byte[] szpwd;
            [MarshalAs(UnmanagedType.ByValArray, SizeConst = 20)]
            public byte[] szdesip;
            public Int32 desport;

            public void Init()
            {
                szpwd = new byte[10];
                szdesip = new byte[20];
            }
        }

        public struct VCI_FILTER_RECORD //滤帧配置
        {
            UInt32 ExtFrame;// 过滤的帧类型【1】过滤扩展帧【0】过滤标准帧。
            UInt32 Start;//起始帧ID 
            UInt32 End;  //结束帧ID 
        }

        /*------------数据结构描述完成---------------------------------*/



        #endregion

        #endregion
        #region 字段
        //private CancellationTokenSource cts;//线程令牌
        //private ManualResetEvent resetEvent = new ManualResetEvent(true);// 暂停业务
        //=====================================================
        Help_String help_String = new Help_String();//文本处理
        //设备类型
        public const int VCI_USBCAN = 3;// USB单路CAN
        public const int VCI_USBCAN2 = 4;// USB双路CAN
        // E表示以太网
        public const int VCI_USBCAN_E_U = 20;// 以太网单路CAN
        public const int VCI_USBCAN_2E_U = 21;// 以太网双路CAN

        const uint CAN1 = 0; // 字段,内部使用
        const uint CAN2 = 1;
        const byte STATUS_OK = 1;
        const byte STATUS_ERR = 0;
        #endregion
        #region 属性
        //public Iface_RTX help_rtx { get; set; }// 接口扩展
        /// <summary>
        /// ↑:byte包,文本
        /// </summary>
        //static public WT_GET_Data  Wt_get;//↑event委托=》呼叫上ui层  让上层显示:发送命令
        /// <summary>
        /// ↓:byte包,文本
        /// </summary>
        static public WT_SET_Data Wt_set;//↓委托=》呼叫下位机执行

        public VCI_BOARD_INFO1[] get_FindUsbDevice
        {
            get
            {
                VCI_BOARD_INFO1[] pInfo = new VCI_BOARD_INFO1[5];
                Int32 num = VCI_FindUsbDevice(ref pInfo[0]);// 查找5个设备
                return pInfo;
            }
        }
        /// <summary>
        /// USB设备id:查找50个USB设备【31F01031C93】
        /// </summary>
        public VCI_BOARD_INFO[] get_FindUsbDevice2
        {
            get
            {
                VCI_BOARD_INFO[] pInfo = new VCI_BOARD_INFO[50];
                UInt32 num = VCI_FindUsbDevice2(ref pInfo[0]);// 查找50个设备
                return pInfo;
            }
        }
        public VCI_BOARD_INFO get_ReadBoardInfo
        {
            get
            {
                Set_Open();
                VCI_BOARD_INFO info = new VCI_BOARD_INFO();
                Int32 num = VCI_ReadBoardInfo(VCI_USBCAN2, 0, ref info);
                return info;

            }
        }

        #endregion
        #region 构造

        #endregion
        #region 事件

        #endregion

        #region APP方法【 开,关,收,发,复位
        /// <summary>
        /// 打开CAN:设备类型,硬件id,CAN通道id,参数表
        /// </summary>
        /// <param name="DeviceType"></param>
        /// <param name="DeviceInd"></param>
        /// <param name="CANInd"></param>
        /// <param name="pInitConfig"></param>
        /// <returns></returns>
        public Int32 Set_Open()//(DeviceType deviceType, uint deviceID,uint canX, VCI_INIT_CONFIG Config)// 设备类型,设备id,通道,配置参数
        {//打开CAN:设备类型,硬件索引,CAN通道索引,初始化参数,
            //查找CAN并打开can1通道

            Int32 sta = 1;// 故障标记
            UInt32 DeviceType = (int)VCI_USBCAN2;// 设备类型4【USB双路CAN】
            UInt32 DeviceInd = 0;// 设备ID

            VCI_BOARD_INFO1 bord = new VCI_BOARD_INFO1();// 设备信息【结构体】
            int num = VCI_FindUsbDevice(ref bord);// 查找USB设备【31F01031C93】v3.41
            if (num < 1)
            {// 找不到设备
                return 0;
            }

            // 配置表
            VCI_INIT_CONFIG config = new VCI_INIT_CONFIG();// 参数表【结构体】
            // bit全部匹配,此帧才可以被接收。否则不能接收。【左对齐】(//标准帧右移21bit分析)
            config.AccCode = 0;//bit【钥匙销子】匹配id,(右移21bit分析【32-11】)b31对应帧id最高位【左对齐】
            config.AccMask = 0xffffffff;// 屏蔽码。使AccCode的某个bit功能失效。左对齐,【标准帧11bit】bit31~bit21置1为屏蔽AccCode的bit匹配功能,
            config.Filter = 1;//0或1接收所有帧。2只接收标准帧,3只接收扩展帧。
            config.Timing0 = 0x00;//波特率 1MHz【T0=0x00,T1=0x14】  // 查手册
            config.Timing1 = 0x14;
            config.Mode = 0;//模式,0表示正常模式,1表示只听模式,2表示自发自收模式(环回模式)

            // usb硬件
            sta &= VCI_使能设备(DeviceType, DeviceInd);// 通电

            sta &= VCI_初始化通道(DeviceType, DeviceInd, CAN1, ref config);// CAN 1
            sta &= VCI_初始化通道(DeviceType, DeviceInd, CAN2, ref config);// CAN 2

            sta &= VCI_CAN通道工作(DeviceType, DeviceInd, CAN1);// CAN 1
            //sta &= VCI_CAN通道工作(DeviceType, DeviceInd, CAN2);// CAN 2

            // 硬件信息【在VCI_OpenDevice运行后才可读设备信息】
            VCI_BOARD_INFO pInfo = new VCI_BOARD_INFO();// 设备信息
            Int32 num1 = VCI_ReadBoardInfo(4, 0, ref pInfo);//   VCI_ReadBoardInfo     VCI_FindUsbDevice
            if (num1 >= 1)
            {
                string 序列号 = new string(pInfo.str_Serial_Num);
                string 设备名称 = new string(pInfo.str_hw_Type);
            }


            return (Int32)(sta == 1 ? 1 : 0);// 1完成,0故障

            //================================
            //VCI_INIT_CONFIG config = new VCI_INIT_CONFIG();// 参数表
            //config.AccCode = 0;// bit全部匹配,此帧才可以被接收。否则不能接收。【左对齐】(//标准帧右移21bit分析)
            //config.AccMask = 0xffffffff;//全部接收  // 屏蔽码。使AccCode的某个bit功能失效。左对齐,bit31~bit21置1为屏蔽AccCode的bit匹配功能,
            //config.Filter = 0;//0或1接收所有帧。2标准帧滤波,3是扩展帧滤波。
            //config.Timing0 = 0x00;//波特率参数 1MHz(T0=0x00,T1=0x14)
            //config.Timing1 = 0x14;
            //config.Mode = 0;//模式,0表示正常模式,1表示只听模式,2自测模式

            //uint i = can.set_Open(Help_USB_CAN.VCI_USBCAN2, 0, 0, ref config);// CAN 1
            //i &= can.set_Open(Help_USB_CAN.VCI_USBCAN2, 0, 1, ref config);// CAN 2

        }
        /// <summary>
        /// 关闭CAN:设备类型,设备id
        /// </summary>
        /// <param name="DeviceType"></param>
        /// <param name="DeviceInd"></param>
        /// <returns></returns>
        public Int32 Set_Close(UInt32 DeviceType, UInt32 DeviceInd)// UInt32 DeviceType, UInt32 DeviceInd
        {
            Int32 sta = 1;// 故障标记

            sta &= VCI_CloseDevice(DeviceType, DeviceInd);//设备关
            sta &= VCI_UsbDeviceReset(DeviceType, DeviceInd, 0);// 设备复位

            return sta;
        }
        public Int32 Set_ClearBuffer(UInt32 DeviceType, UInt32 DeviceInd, UInt32 CANInd)
        {//设备类型,设备id,通道id
            Int32 sta = 1;
            sta &= VCI_ClearBuffer(DeviceType, DeviceInd, CANInd);
            //sta&= VCI_ClearBuffer(DeviceType, DeviceInd, 1);// CAN2
            return sta;
        }
        /// <summary>
        /// 接收:设备类型,设备索引,CAN通道索引,参数表,最大帧数2000,超时时间
        /// </summary>
        /// <param name="DeviceType">设备类型</param>
        /// <param name="DeviceInd">设备id</param>
        /// <param name="CANInd">通道id</param>
        /// <param name="pReceive">数据包</param>
        /// <param name="Len">小于2500帧</param>
        /// <param name="WaitTime">保留=0</param>
        /// <returns></returns>
        public Int32 get_Receive(UInt32 DeviceType, UInt32 DeviceInd, UInt32 CANInd, ref VCI_CAN_OBJ pReceive, UInt32 Len, Int32 WaitTime)
        {//VCI_CAN_OBJ pReceive 设置为数组,2000帧
            // 设备类型,设备id,通道id,数据包,帧数,等待时间【保留0】
            return VCI_Receive(DeviceType, DeviceInd, CANInd, ref pReceive, Len, WaitTime);
        }
        /// <summary>
        /// 发送:设备类型,设备索引,CAN通道索引,参数表,要发帧数
        /// </summary>
        /// <param name="DeviceType">设备类型</param>
        /// <param name="DeviceInd">设备id</param>
        /// <param name="CANInd">通道id</param>
        /// <param name="pSend">数据包</param>
        /// <param name="Len">帧数小于1000</param>
        /// <returns></returns>
        public Int32 set_Send(UInt32 DeviceType, UInt32 DeviceInd, UInt32 CANInd, ref VCI_CAN_OBJ pSend, UInt32 Len)
        {
            // 设备类型,设备id,通道id,数据包,帧数
            return VCI_Transmit(DeviceType, DeviceInd, CANInd, ref pSend, Len);
        }
        public Int32 set_ResetCAN(UInt32 DeviceType, UInt32 DeviceInd, UInt32 CANInd)
        {// 复位can通道
            return VCI_ResetCAN(DeviceType, DeviceInd, CANInd);
        }
        /// <summary>
        /// 获取CAN设备信息【需要先打开设备】
        /// </summary>
        /// <param name="DeviceType"></param>
        /// <param name="DeviceInd"></param>
        /// <param name="pInfo"></param>
        /// <returns></returns>
        public Int32 get_BoardInfo(UInt32 DeviceType, UInt32 DeviceInd, ref VCI_BOARD_INFO pInfo)
        {//需要设备开启后,才能读取
            return VCI_ReadBoardInfo(DeviceType, DeviceInd, ref pInfo);
            //=======================================================
            //VCI_BOARD_INFO info = new VCI_BOARD_INFO();
            //uint i = can.get_Board(4, 0, ref info);

        }


        //==以下不再重要=======================================================================
        //==以下不再重要========




        /// <summary>
        /// 使能硬件:设备类型,设备id。
        /// </summary>
        /// <param name="DeviceType">Help_USB_CAN.VCI_USBCAN2 = 4;双路CAN</param>
        /// <param name="DeviceInd">第1个CAN通道是0</param>
        /// <param name="Reserved">备用=0</param>
        /// <returns></returns>
        public Int32 VCI_使能设备(UInt32 DeviceType, UInt32 DeviceInd)
        {// 相当于 插电
            return VCI_OpenDevice(DeviceType, DeviceInd, 0x00);// 通电
        }
        /// <summary>
        /// 初始化硬件:can设备类型,设备id,CAN通道id,VCI_INIT_CONFIG初始化参数结构体
        /// </summary>
        /// <param name="DeviceType">can设备类型</param>
        /// <param name="DeviceInd">设备索引0</param>
        /// <param name="CANInd">CAN通道索引0</param>
        /// <param name="pInitConfig">VCI_INIT_CONFIG初始化参数结构</param>
        /// <returns></returns>
        public Int32 VCI_初始化通道(UInt32 DeviceType, UInt32 DeviceInd, UInt32 CANInd, ref VCI_INIT_CONFIG pInitConfig)
        {
            return VCI_InitCAN(DeviceType, DeviceInd, CANInd, ref pInitConfig);
        }
        //设备类型。设备索引,CAN通道索引。初始化参数结构。

        /// <summary>
        /// CAN工作:设备类型,设备id,CAN通道id(返回【1】成功; 【0】失败; 【-1】设备不存在或USB掉线。)
        /// </summary>
        /// <param name="DeviceType"></param>
        /// <param name="DeviceInd"></param>
        /// <param name="CANInd"></param>
        /// <returns></returns>
        public Int32 VCI_CAN通道工作(UInt32 DeviceType, UInt32 DeviceInd, UInt32 CANInd)
        {
            return VCI_StartCAN(DeviceType, DeviceInd, CANInd);
        }

        /// <summary>
        /// CAN发送:设备类型,设备索引,CAN通道索引,VCI_CAN_OBJ数组的首指针,(帧数量 最大为10)
        /// </summary>
        /// <param name="DeviceType"></param>
        /// <param name="DeviceInd"></param>
        /// <param name="CANInd"></param>
        /// <param name="pSend"></param>
        /// <param name="Len"></param>
        /// <returns></returns>
        public Int32 VCI_set发送(UInt32 DeviceType, UInt32 DeviceInd, UInt32 CANInd, ref VCI_CAN_OBJ pSend, UInt32 Len)
        {
            return VCI_Transmit(DeviceType, DeviceInd, CANInd, ref pSend, Len);
        }

        public Int32 VCI_get缓存区帧数(UInt32 DeviceType, UInt32 DeviceInd, UInt32 CANInd)
        {
            return VCI_GetReceiveNum(DeviceType, DeviceInd, CANInd);// 缓存区,帧数
        }
        /// <summary>
        /// CAN接收:设备类型,设备id,CAN通道id,VCI_CAN_OBJ数组的首指针,本次接收的最大帧数 2500 ,超时时间ms
        /// </summary>
        /// <param name="DeviceType"></param>
        /// <param name="DeviceInd"></param>
        /// <param name="CANInd"></param>
        /// <param name="pReceive"></param>
        /// <param name="Len"></param>
        /// <param name="WaitTime"></param>
        /// <returns></returns>
        public Int32 VCI_get接收(UInt32 DeviceType, UInt32 DeviceInd, UInt32 CANInd, ref VCI_CAN_OBJ pReceive, UInt32 Len, Int32 WaitTime)
        {
            //VCI_CAN_OBJ[] obj = new VCI_CAN_OBJ[2000];
            //uint i = can.VCI_get接收(4, 0, 1, ref obj[0], 2000, 0);
            return VCI_Receive(DeviceType, DeviceInd, CANInd, ref pReceive, Len, WaitTime);
        }

        #endregion

        #region 后台方法
        #region 元始库方法

        //方法
        /*------------兼容ZLG的函数描述---------------------------------*/
        [DllImport("controlcan.dll")]
        public static extern Int32 VCI_OpenDevice(UInt32 DeviceType, UInt32 DeviceInd, UInt32 Reserved);
        //返回值=1,表示操作成功;=0表示操作失败;=-1表示USB-CAN设备不存在或USB掉线。
        //使能设备//(can通道不工作,只设备工作)
        [DllImport("controlcan.dll")]
        public static extern Int32 VCI_CloseDevice(UInt32 DeviceType, UInt32 DeviceInd);
        //返回值=1,表示操作成功;=0表示操作失败;=-1表示USB-CAN设备不存在或USB掉线。
        //关闭设备
        [DllImport("controlcan.dll")]
        public static extern Int32 VCI_InitCAN(UInt32 DeviceType, UInt32 DeviceInd, UInt32 CANInd, ref VCI_INIT_CONFIG pInitConfig);
        //初始化can通道(参数配置)b31对应帧id最高位,所以11bit要左移21bit
        [DllImport("controlcan.dll")]
        public static extern Int32 VCI_ReadBoardInfo(UInt32 DeviceType, UInt32 DeviceInd, ref VCI_BOARD_INFO pInfo);
        //读取主板信息【需要先VCI_OpenDevice】
        [DllImport("controlcan.dll")]
        public static extern Int32 VCI_GetReceiveNum(UInt32 DeviceType, UInt32 DeviceInd, UInt32 CANInd);
        //缓存区可用帧数(<=2000帧)
        [DllImport("controlcan.dll")]
        public static extern Int32 VCI_ClearBuffer(UInt32 DeviceType, UInt32 DeviceInd, UInt32 CANInd);
        //清空缓存区
        [DllImport("controlcan.dll")]
        public static extern Int32 VCI_StartCAN(UInt32 DeviceType, UInt32 DeviceInd, UInt32 CANInd);
        //CAN通道启动(启动can通道)
        [DllImport("controlcan.dll")]
        public static extern Int32 VCI_ResetCAN(UInt32 DeviceType, UInt32 DeviceInd, UInt32 CANInd);
        //CAN通道复位
        [DllImport("controlcan.dll")]
        public static extern Int32 VCI_Transmit(UInt32 DeviceType,UInt32 DeviceInd, UInt32 CANInd, ref VCI_CAN_OBJ pSend,UInt32 Length);
        //返回实际发送的帧数,=-1表示USB-CAN设备不存在或USB掉线。
        //Length 最大为1000,建议设为1,每次发送单帧,以提高发送效率
                //CAN通道发送(单次<=10帧)
        [DllImport("controlcan.dll")]
        public static extern Int32 VCI_Receive(UInt32 DeviceType, UInt32 DeviceInd, UInt32 CANInd, ref VCI_CAN_OBJ pReceive, UInt32 Len, Int32 WaitTime);
        //CAN通道接收(函数调用间隔至少应设置在5ms以上。)【Len为单次封顶帧数2500帧被读出

        /*------------其他函数描述---------------------------------*/
        [DllImport("controlcan.dll")]
        public static extern Int32 VCI_ConnectDevice(UInt32 DevType, UInt32 DevIndex);
        //设备连接
        [DllImport("controlcan.dll")]
        public static extern Int32 VCI_UsbDeviceReset(UInt32 DevType, UInt32 DevIndex, UInt32 Reserved);
        //设备复位
        [DllImport("controlcan.dll")]
        public static extern Int32 VCI_FindUsbDevice(ref VCI_BOARD_INFO1 pInfo);
        //返回前5个设备信息
        //若计算机中插入多于5个适配器,则使用VCI_FindUsbDevice2函数,最大支持50个USB-CAN适配器。
        [DllImport("controlcan.dll")]
        public static extern UInt32 VCI_FindUsbDevice2 (ref VCI_BOARD_INFO pInfo);
        //如:VCI_BOARD_INFO pInfo[50]。 

        [DllImport("controlcan.dll")]
        public static extern Int32 VCI_SetReference(UInt32 DeviceType, UInt32 DeviceInd, UInt32 CANInd, UInt32 RefType, ref VCI_FILTER_RECORD pData);
        //设置滤帧(设备类型,设备id,通道id,参数类型,参数包)【只监听某一范围的帧】
        //RefType=1,添加滤帧表 指向VCI_FILTER_RECORD结构的指针
        //RefType=2,启用滤帧表
        //RefType=3,清除滤帧表。

        /*------------函数描述结束---------------------------------*/

        #endregion
        #endregion


        #region 窗体移动

        //private Point mouseOff;//鼠标移动位置变量
        //private bool leftFlag;//标签是否为左键
        //private void Frm_MouseDown(object sender, MouseEventArgs e)//鼠标按下
        //{
        //    if (e.Button == MouseButtons.Left)
        //    {
        //        mouseOff = new Point(-e.X, -e.Y); //得到变量的值
        //        leftFlag = true;                  //点击左键按下时标注为true;
        //    }
        //}
        //private void Frm_MouseMove(object sender, MouseEventArgs e)//鼠标移动
        //{
        //    if (leftFlag)
        //    {
        //        Point mouseSet = Control.MousePosition;
        //        mouseSet.Offset(mouseOff.X, mouseOff.Y);  //设置移动后的位置
        //                                                  //Location = mouseSet;//Form 窗体父类字段
        //    }
        //}
        //private void Frm_MouseUp(object sender, MouseEventArgs e)//鼠标松开
        //{
        //    if (leftFlag)
        //    {
        //        leftFlag = false;//释放鼠标后标注为false;
        //    }
        //}

        #endregion

        #region 错误
        //try
        //{
        //    byte[] buffer = Encoding.Default.GetBytes(data);//以计算机的编码发送
        //    serialPort.Write(buffer, 0, buffer.Length);//  开始发送
        //}
        //catch (Exception ex) { MessageBox.Show(ex.Message); }//显示错误
        #endregion

        #region 接口实现

        public bool connect<T>(T a, T b)
        {// 打开USB-CAN设备的can1通道

            //throw new NotImplementedException();
            int sta = Set_Open();
            return sta == STATUS_OK ? true : false; // 1完成,0故障
        }

        bool Iface_RTX.Close()
        {
            //throw new NotImplementedException();
            if (Set_Close(VCI_USBCAN2, 0) == 1)
            {
                return true;
            }
            return false;
        }
      
        public Int32 RXs(ref object Obj)
        {
            //throw new NotImplementedException();
            // 缓存区可用帧数=============================
            
            //int i = VCI_GetReceiveNum(Help_USB_CAN.VCI_USBCAN2, CAN_inD, CAN1);// can1

            VCI_CAN_OBJ[] obj = new VCI_CAN_OBJ[2500];// 创新科技CAN分析仪,单次最大缓存2500帧接收,间隔5ms以上
            Int32 num = VCI_get接收(VCI_USBCAN2, 0, CAN1, ref obj[0], 2500, 0);//  注意 CAN1  通道
            if (num > 0)// CAN1接收帧数
            {
                Obj = obj;
                return num;

                #region 取一帧      【1   4    8】
                //=================================================
                //byte[] bytes = new byte[13];
                //bytes[0] = obj[0].DataLen;   //  【1】有效字节
                //uint id = obj[0].ID; //     帧 id【4】帧id
                //bytes[1] = (byte)(id >> 24);
                //bytes[2] = (byte)(id >> 16);
                //bytes[3] = (byte)(id >> 8);
                //bytes[4] = (byte)(id & 0xff);

                //fixed (VCI_CAN_OBJ* p_obj = &obj[0])// 8字节    第一帧
                //{
                //    bytes[5] = p_obj->Data[0];//  【8】包数据
                //    bytes[6] = p_obj->Data[1];
                //    bytes[7] = p_obj->Data[2];
                //    bytes[8] = p_obj->Data[3];
                //    bytes[9] = p_obj->Data[4];
                //    bytes[10] = p_obj->Data[5];
                //    bytes[11] = p_obj->Data[6];
                //    bytes[12] = p_obj->Data[7];
                //}
                //return bytes;

                #endregion

            }

            return 0;
        }
        //public int RXs<T>(ref T obj)// 待测试
        //{
        //    //throw new NotImplementedException();
        //    VCI_CAN_OBJ[] obj2 = new VCI_CAN_OBJ[2000];// 创新科技CAN分析仪最大支持2000帧接收,间隔5ms以上
        //    int num = VCI_get接收(4, 0, CAN1, ref obj2[0], 2000, 50);
        //    if (num > 0)// CAN1接收帧数
        //    {
        //        //obj = obj2.ToList<T>();

        //        return num;
        //    }
        //    return 0;


        //    }
        public unsafe bool TXs(string cmd)//  "08   00000602  4064600000000000"   //   CAN_namespace.Iface_RTX.
        {// 1  4  8 (DLC字节,帧id,Byte8数据包)
            //throw new NotImplementedException();
            cmd.Replace(" ", "");//去除空白
            byte[] buffercmd = help_String.StringsToHexBytes(cmd);//准备报文  //去除空白   StringsToHexBytes
            VCI_CAN_OBJ[] buffer = new VCI_CAN_OBJ[10];
            string id = cmd.Substring(2, 8);// 从站地址  00000602
            // 4   
            buffer[0].ID = Convert.ToUInt32(id, 16);//从站id
            // 重发功能 0开,1关
            buffer[0].SendType = 0;//【0】正常,失败有重发  【1】只发单次,失败无重发
            // 1      
            buffer[0].DataLen = buffercmd[0];//数据长度 DLC (<=8),即CAN帧Data有几个字节。约束了后面Data[8]中的有效字节。
            // 8           
            buffer[0].Data[0] = buffercmd[5];// byte8
            buffer[0].Data[1] = buffercmd[6];
            buffer[0].Data[2] = buffercmd[7];
            buffer[0].Data[3] = buffercmd[8];
            buffer[0].Data[4] = buffercmd[9];
            buffer[0].Data[5] = buffercmd[10];
            buffer[0].Data[6] = buffercmd[11];
            buffer[0].Data[7] = buffercmd[12];
            // 上车
            Int32 ret = VCI_set发送(Help_USB_CAN.VCI_USBCAN2, 0, CAN1, ref buffer[0], 1);// 库函数(发送TXs)
            if (ret == 1) return true;

            return false;
        }


        public unsafe object sendAndReceive(string stringcmd)
        {//"1803052000018705"
            //"04000006014000200000000000"
            //throw new NotImplementedException();
            stringcmd.Replace(" ", "");//去除空白
            byte[] buffercmd = help_String.StringsToHexBytes(stringcmd);//准备报文  //去除空白   StringsToHexBytes

            VCI_CAN_OBJ[] buffer = new VCI_CAN_OBJ[10];
            string id = stringcmd.Substring(7, 3);// 从站地址
            buffer[0].ID = Convert.ToUInt32(id, 16);//从站id
            buffer[0].SendType = 1;//发送帧类型。=0时为正常发送(发送失败会自动重发,重发超时时间为4秒, 4秒内没有发出则取消);=1时为单次发送
            buffer[0].DataLen = buffercmd[0];//数据长度 DLC (<=8),即CAN帧Data有几个字节。约束了后面Data[8]中的有效字节。

            buffer[0].Data[0] = buffercmd[5];
            buffer[0].Data[1] = buffercmd[6];
            buffer[0].Data[2] = buffercmd[7];
            buffer[0].Data[3] = buffercmd[8];
            buffer[0].Data[4] = buffercmd[9];
            buffer[0].Data[5] = buffercmd[10];
            buffer[0].Data[6] = buffercmd[11];
            buffer[0].Data[7] = buffercmd[12];

            Int32 ret = set_Send(VCI_USBCAN2, 0, 0, ref buffer[0], 1);// 发1帧



            //byte[] buff = SendAndReceive(buffer, stringcmd);//  收发报文

            //if (buff == null) throw new Exception("ACK 未应答。。。");

            //if (buff != null)
            //{
            //    string str = help_String.BytesToHexStrings(buff);
            //    return str;
            //}
            return null;// 发送后未接收





        }

        //public unsafe object RXs()//  VCI_CAN_OBJ  //CAN帧参数
        //{
        //    //throw new NotImplementedException();

        //    // 缓存区可用帧数=============================
        //    uint i = VCI_GetReceiveNum(Help_USB_CAN.VCI_USBCAN2, 0, 0);// can1
        //    if (i > 0)// CAN1接收帧数
        //    {
        //        uint CAN1 = 0;
        //        VCI_CAN_OBJ[] obj = new VCI_CAN_OBJ[2000];// 创新科技CAN分析仪最大支持2000帧接收
        //        i = VCI_get接收(4, 0, CAN1, ref obj[0], 1, 0);//  注意 CAN1  通道

        //        #region 取一帧
        //        //=================================================
        //        byte[] bytes = new byte[13];
        //        bytes[0] = obj[0].DataLen;   //obj[0].
        //        uint id = obj[0].ID; //       帧 id
        //        bytes[1] = (byte)(id >> 24);
        //        bytes[2] = (byte)(id >> 16);
        //        bytes[3] = (byte)(id >> 8);
        //        bytes[4] = (byte)(id & 0xff);

        //        fixed (VCI_CAN_OBJ* p_obj = &obj[0])// 8字节    第一帧
        //        {
        //            bytes[5] = p_obj->Data[0];
        //            bytes[6] = p_obj->Data[1];
        //            bytes[7] = p_obj->Data[2];
        //            bytes[8] = p_obj->Data[3];
        //            bytes[9] = p_obj->Data[4];
        //            bytes[10] = p_obj->Data[5];
        //            bytes[11] = p_obj->Data[6];
        //            bytes[12] = p_obj->Data[7];
        //        }
        //        return bytes;

        //        #endregion
        //        //return obj;
        //    }
        //    return null;
        //}

        //public unsafe object RXs()//  VCI_CAN_OBJ  //CAN帧参数
        //{// CAN1 接收

        //    //throw new NotImplementedException();

        //    // 缓存区可用帧数=============================
        //    //Help_Delay.delayTime(0.005);// usb大概3~5ms
        //    int i = VCI_GetReceiveNum(Help_USB_CAN.VCI_USBCAN2, CAN_inD, CAN1);// can1
        //    if (i > 0)// CAN1接收帧数
        //    {
        //        VCI_CAN_OBJ[] obj = new VCI_CAN_OBJ[2000];// 创新科技CAN分析仪最大支持2000帧接收,间隔5ms以上
        //        i = VCI_get接收(4, 0, CAN1, ref obj[0], 2000, 50);//  注意 CAN1  通道

        //        #region 取一帧      【1   4    8】
        //        //=================================================
        //        //byte[] bytes = new byte[13];
        //        //bytes[0] = obj[0].DataLen;   //  【1】有效字节
        //        //uint id = obj[0].ID; //     帧 id【4】帧id
        //        //bytes[1] = (byte)(id >> 24);
        //        //bytes[2] = (byte)(id >> 16);
        //        //bytes[3] = (byte)(id >> 8);
        //        //bytes[4] = (byte)(id & 0xff);

        //        //fixed (VCI_CAN_OBJ* p_obj = &obj[0])// 8字节    第一帧
        //        //{
        //        //    bytes[5] = p_obj->Data[0];//  【8】包数据
        //        //    bytes[6] = p_obj->Data[1];
        //        //    bytes[7] = p_obj->Data[2];
        //        //    bytes[8] = p_obj->Data[3];
        //        //    bytes[9] = p_obj->Data[4];
        //        //    bytes[10] = p_obj->Data[5];
        //        //    bytes[11] = p_obj->Data[6];
        //        //    bytes[12] = p_obj->Data[7];
        //        //}
        //        //return bytes;

        //        #endregion
        //        return obj;
        //    }
        //    return null;
        //}
        //public unsafe object TXs(string stringcmd)// "04000006014000200000000000"
        //{//被CanOpen调用

        //    //throw new NotImplementedException();

        //    stringcmd.Replace(" ", "");//去除空白
        //    byte[] buffercmd = help_String.StringsToHexBytes(stringcmd);//准备报文  //去除空白   StringsToHexBytes

        //    VCI_CAN_OBJ[] buffer = new VCI_CAN_OBJ[10];
        //    string id = stringcmd.Substring(2, 8);// 从站地址  00000601
        //    buffer[0].ID = Convert.ToUInt32(id, 16);//从站id
        //    // 重发功能 0开,1关
        //    buffer[0].SendType = 0;//0(4秒内有重发)  1只发单次
        //    buffer[0].DataLen = buffercmd[0];//数据长度 DLC (<=8),即CAN帧Data有几个字节。约束了后面Data[8]中的有效字节。

        //    buffer[0].Data[0] = buffercmd[5];// byte8
        //    buffer[0].Data[1] = buffercmd[6];
        //    buffer[0].Data[2] = buffercmd[7];
        //    buffer[0].Data[3] = buffercmd[8];
        //    buffer[0].Data[4] = buffercmd[9];
        //    buffer[0].Data[5] = buffercmd[10];
        //    buffer[0].Data[6] = buffercmd[11];
        //    buffer[0].Data[7] = buffercmd[12];

        //    Int32 ret = VCI_set发送(Help_USB_CAN.VCI_USBCAN2, 0, CAN1, ref buffer[0], 1);// 库函数(发送TXs)
        //    return ret;
        //}

        //public int Close()
        //{
        //    //throw new NotImplementedException();
        //    return (int)set_Close((UInt32)CAN设备类型.VCI_USBCAN2, CAN_inD);
        //}

        public bool sendAndReceive<T>(string cmd, ref T t)
        {
            throw new NotImplementedException();
        }




        #endregion

    }


    #endregion




}




http://www.kler.cn/a/133776.html

相关文章:

  • 卷积神经网络之Yolo详解
  • 【机器学习】如何配置anaconda环境(无脑版)
  • Android 10 默认授权安装app运行时权限(去掉运行时所有权限授权弹窗)
  • Flink_DataStreamAPI_输出算子Sink
  • Python多进程间通讯(包含共享内存方式)
  • 使用支付宝沙箱完成商品下单
  • Network(四)NAT实现方式与VRRP概述
  • SQL编写规范【干货】
  • YOLOv8改进 | 如何在网络结构中添加注意力机制、C2f、卷积、Neck、检测头
  • MySQL进阶_9.事务基础知识
  • Redis哨兵模式(Docker)
  • 抽象工厂模式-C++实现
  • 当小白遇到电脑程序不完全退出怎么办?
  • kubernetes--Pod控制器详解
  • 【Java并发编程六】多线程越界问题
  • nginx 如何根据IP做限流,以及 nginx 直接返回 json 格式数据
  • 深信服AC密码认证(外部认证:LDAP认证)
  • C#中委托和事件的使用总结
  • JDK1.5 新特性【反射】
  • 大数据基础设施搭建 - ZooKeeper
  • 漏洞利用工具的编写
  • kafka 磁盘扩容与数据均衡实在操作讲解
  • K-Means算法进行分类
  • 2342. 数位和相等数对的最大和 --力扣 --JAVA
  • MySQL数据库下的Explain命令深度解析
  • 自动驾驶学习笔记(九)——车辆控制