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 的选中状态去掉
原文:https://www.cnblogs.com/zwj-199306231519/p/13560929.html