USB-CAN通讯

1.打开并初始化CAN设备代码:

 private void OpenCAN()
        {
            if (!IsOpen)
            {
                ControlCAN.VCI_INIT_CONFIG initCOnfig = new ControlCAN.VCI_INIT_CONFIG();
                initCOnfig.Mode = 0;//正常模式,1为只听模式
                initCOnfig.AccMask = 0xFFFFFFFF;
                initCOnfig.Timing0 = 0x01;
                initCOnfig.Timing1 = 0x1C;
                //打开设备

                uint dwRel = ControlCAN.VCI_OpenDevice(DeviceType, DeviceInd, Reserved);

                if (dwRel != ControlCAN.STATUS_OK)
                {
                    MessageBox.Show("打开设备失败");
                    return;
                }

                //初始化
                dwRel = ControlCAN.VCI_InitCAN(DeviceType, DeviceInd, CANInd, ref initCOnfig);
                if (dwRel == ControlCAN.STATUS_ERR)
                {
                    MessageBox.Show("初始化设备失败");
                    return;
                }

                dwRel = ControlCAN.VCI_StartCAN(DeviceType, DeviceInd, CANInd);
                if (dwRel == ControlCAN.STATUS_ERR)
                {
                    MessageBox.Show("启动设备失败");
                    return;
                }
                //WriteLog("CAN初始化成功");

                // if (OrderRecvHanlde == null)
                //{
                //启用接收线程
                Thread myThreadSend = new Thread(new ThreadStart(SendThread));
                myThreadSend.Start();
                myThreadSend.IsBackground = true;
                Thread myThread1 = new Thread(new ThreadStart(OrderRecvProc));
                myThread1.Start();
              
                IsOpen = true;
            }
        }

2.CAN发送数据:

private void SendThread()
        {
            while (true)
            {
                ControlCAN.VCI_CAN_OBJ[] sendCanObj1 = new ControlCAN.VCI_CAN_OBJ[100];
                if (IsFSBH_Flg && IsReceiveDataFlag)
                {
                    //Array.Clear(sendCanObj, 0, sendCanObj.Length);
                    Thread.Sleep(10);
                    sendCanObj1[0].Data = new byte[8];
                    int idNum = (addr << 3) + 1;
                    sendCanObj1[0].SendType = 0;//正常发送
                    sendCanObj1[0].RemoteFlag = 0;//数据帧
                    sendCanObj1[0].ExternFlag = 0;//标准帧
                    sendCanObj1[0].ID = (uint)idNum;
                    sendCanObj1[0].DataLen = (byte)(8);
                    sendCanObj1[0].Data[0] = 0;
                    sendCanObj1[0].Data[1] = 0;
                    sendCanObj1[0].Data[2] = 0;
                    sendCanObj1[0].Data[3] = 0;
                    sendCanObj1[0].Data[4] = 0;
                    sendCanObj1[0].Data[5] = 0; 
                    sendCanObj1[0].Data[6] = 0;
                    sendCanObj1[0].Data[7] = 0;
                    ControlCAN.VCI_Transmit(DeviceType, DeviceInd, CANInd, sendCanObj1, 1);
                    IsFSBH_Flg = false;


                }
            }
        }

3.CAN接受数据:

       private void OrderRecvProc()
        {
            SByte[] buf = new SByte[256];
            SByte recvFenJI = 3;
            s_buf = new Byte[100];
            sendCanObj[0].Data = new byte[8];
            sendCanObj[1].Data = new byte[8];
            sendCanObj[2].Data = new byte[8];
            sendCanObj[0].Reserved = new byte[3];
            sendCanObj[1].Reserved = new byte[3];
            sendCanObj[2].Reserved = new byte[3];
            string str, str1;
            //Array.Clear(receiveCanObj, 0, receiveCanObj.Length);  
            while (true)
            {
                uint recvlen = ControlCAN.VCI_GetReceiveNum(DeviceType, DeviceInd, CANInd);
                int recvNum = 0;

                if (recvlen > 0)
                {
                    IsReceiveDataFlag = true;
                    try
                    {
                        recvNum = (int)ControlCAN.VCI_Receive(DeviceType, DeviceInd, CANInd, receiveCanObj, recvlen, 400);
                    }
                    catch (Exception ex)
                    {
                        MessageBox.Show(ex.Message);
                    }
                }
                else
                {
                    IsReceiveDataFlag = false;
                    Thread.Sleep(100);
                    continue;
                }
                str = "RecvData";
                for (int i = 0; i < recvNum; i++)
                {
                    int Num = receiveCanObj[i].DataLen;
                    int canaddr = (int)(receiveCanObj[i].ID >> 3);//CAN地址
                    str = string.Format("{0}分机RecvData:", canaddr);
                    for (int j = 0; j < Num; j++)
                    {
                        int value = receiveCanObj[i].Data[j];
                        str1 = string.Format("{0:X2} ", value);
                        str += str1;
                    }
                    str.ToUpper();
                    //字节数判定
                    if (Num < 2)
                    {
                        str += "数据字节数不对!!!";
                        //WriteLog(str);
                        continue;
                    }
                    //WriteLog(str);

                    if (receiveCanObj[i].Data[1] == 0x20)//灯丝报警状态
                    {
                        addr = (int)(receiveCanObj[i].ID >> 3);//CAN地址
                        for (int m = 0; m < g_XHJSum / 8; m++)
                        {
                            int idNum = (addr << 3) + 2;
                            int endIdNum = (addr << 3) + 1;
                            sendCanObj[0].SendType = 0;//正常发送
                            sendCanObj[0].RemoteFlag = 0;//数据帧
                            sendCanObj[0].ExternFlag = 0;//标准帧
                            sendCanObj[0].ID = (uint)idNum;
                            sendCanObj[0].DataLen = 8;
                            sendCanObj[0].Data[0] = 0;
                            sendCanObj[0].Data[1] = 0;//单帧索引
                            sendCanObj[0].Data[2] = 0x20;
                            sendCanObj[0].Data[3] = (byte)(g_XHJSum & 0xFF);//开关量总数
                            sendCanObj[0].Data[4] = (byte)(g_XHJSum >> 8);//开关量总数高字节
                            sendCanObj[0].Data[5] = sendBUF[m];
                            sendCanObj[0].Data[6] = 0x00;
                            sendCanObj[0].Data[7] = 0x00;

                            Thread.Sleep(0);
                            ControlCAN.VCI_Transmit(DeviceType, DeviceInd, CANInd, sendCanObj, 1);
                            //Application.DoEvents();
                            addr = (int)(receiveCanObj[i].ID >> 3);//CAN地址;//CAN地址
                            string str2, str3;
                            str2 = string.Format("{0}分机自主帧SendData:", canaddr);
                            for (int j = 0; j < sendCanObj[0].DataLen; j++)
                            {
                                int value = sendCanObj[0].Data[j];
                                str3 = string.Format("{0:X2} ", value);
                                str2 += str3;
                            }
                            str2.ToUpper();
                        }
                        break;
                    }
                }
            }
        }

4.操作可能遇到的问题

  (1):打开设备失败,ControlCAN.VCI_OpenDevice(DeviceType, DeviceInd, Reserved)这个函数返回值为0,可能的原因(我当时遇到),缺少kerneldlls这个文件夹,这个文件夹里面放了要用到的库,如下:

             

  解决办法:将kerneldlls这个文件夹放到可执行文件目录(.exe文件目录)下即可。

  (2):遇到以下错误:

      

     解决办法:把VS菜单的 调试->异常->Managed Debuggin Assistants->LoaderLock 的选中状态去掉

    

111
原文地址:https://www.cnblogs.com/zwj-199306231519/p/13560929.html