周立功 CAN PCI介面卡C#語言樣本

來源:互聯網
上載者:User

      周立功CAN pci介面卡提供的範例程式碼都是VC,VB和Delphi的,沒有C#.net的例子。但是在使用C#調用CAN api的時候,由於這些api對資料類型的校正非常嚴格,所以,調試起來比較麻煩。摸索了一段時間,終於使用C# 2.0 VS.2008調用CAN api可以正常的發送接收資料了。

      現在把API的聲明提供如下,有同樣需求的,就可以少走很多彎路了。public sealed class CANApi { //介面卡類型定義 public enum PCIDeviceType { VCI_PCI5121 =1, VCI_PCI9810 =2, VCI_USBCAN1 =3, VCI_USBCAN2 =4, VCI_PCI9820 =5, VCI_CAN232 =6, VCI_PCI5110 =7, VCI_CANLITE =8, VCI_ISA9620 =9, VCI_ISA5420 =10, VCI_PC104CAN = 11, VCI_CANETE =12, VCI_DNP9810 =13, VCI_PCI9840 =14, VCI_PCI9820I =16 } //函數調用返回狀態值 public static readonly int STATUS_OK =1; public static readonly int STATUS_ERR =0; public enum ErrorType { //CAN錯誤碼 ERR_CAN_OVERFLOW =0x0001, //CAN控制器內部FIFO溢出 ERR_CAN_ERRALARM =0x0002, //CAN控制器錯誤判警 ERR_CAN_PASSIVE =0x0004, //CAN控制器消極錯誤 ERR_CAN_LOSE =0x0008, //CAN控制器仲裁丟失 ERR_CAN_BUSERR =0x0010, //CAN控制器匯流排錯誤 //通用錯誤碼 ERR_DEVICEOPENED =0x0100, //裝置已經開啟 ERR_DEVICEOPEN =0x0200, //開啟裝置錯誤 ERR_DEVICENOTOPEN =0x0400, //裝置沒有開啟 ERR_BUFFEROVERFLOW =0x0800, //緩衝區溢位 ERR_DEVICENOTEXIST =0x1000, //此裝置不存在 ERR_LOADKERNELDLL =0x2000, //裝載動態庫失敗 ERR_CMDFAILED =0x4000, //執行命令失敗錯誤碼 ERR_BUFFERCREATE =0x8000 //記憶體不足 } //1.ZLGCAN系列介面卡資訊的資料類型。 [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)] public struct VCI_BOARD_INFO { public ushort hw_Version; public ushort fw_Version; public ushort dr_Version; public ushort in_Version; public ushort irq_Num; public byte can_Num; [System.Runtime.InteropServices.MarshalAsAttribute(System.Runtime.InteropServices.UnmanagedType.ByValTStr, SizeConst = 20)] public string str_Serial_Num; [System.Runtime.InteropServices.MarshalAsAttribute(System.Runtime.InteropServices.UnmanagedType.ByValTStr, SizeConst = 40)] public string str_hw_Type; [System.Runtime.InteropServices.MarshalAsAttribute(System.Runtime.InteropServices.UnmanagedType.ByValArray, SizeConst = 4, ArraySubType = System.Runtime.InteropServices.UnmanagedType.U2)] public ushort[] Reserved; } //2.定義CAN資訊幀的資料類型。 [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)] public struct VCI_CAN_OBJ { public uint ID; public uint TimeStamp; public byte TimeFlag; public byte SendType; public byte RemoteFlag;//是否是遠程幀 public byte ExternFlag;//是否是擴充幀 public byte DataLen; [MarshalAs(UnmanagedType.ByValArray, SizeConst = 8, ArraySubType = UnmanagedType.I1)] public byte[] Data; [MarshalAs(UnmanagedType.ByValArray, SizeConst = 3, ArraySubType = UnmanagedType.I1)] public byte[] Reserved; } //3.定義CAN控制器狀態的資料類型。 [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)] public struct VCI_CAN_STATUS { public byte ErrInterrupt; public byte regMode; public byte regStatus; public byte regALCapture; public byte regECCapture; public byte regEWLimit; public byte regRECounter; public byte regTECounter; public uint Reserved; } //4.定義錯誤資訊的資料類型。 [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)] public struct VCI_ERR_INFO { public uint ErrCode; [System.Runtime.InteropServices.MarshalAsAttribute(System.Runtime.InteropServices.UnmanagedType.ByValArray, SizeConst = 3, ArraySubType = System.Runtime.InteropServices.UnmanagedType.I1)] public byte[] Passive_ErrData; public byte ArLost_ErrData; } //5.定義初始化CAN的資料類型 [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)] public struct VCI_INIT_CONFIG { public uint AccCode; public uint AccMask; public uint Reserved; public byte Filter; public byte Timing0; public byte Timing1; public byte Mode; } [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)] public struct CHGDESIPANDPORT { [System.Runtime.InteropServices.MarshalAsAttribute(System.Runtime.InteropServices.UnmanagedType.ByValTStr, SizeConst = 10)] public string szpwd; [System.Runtime.InteropServices.MarshalAsAttribute(System.Runtime.InteropServices.UnmanagedType.ByValTStr, SizeConst = 20)] public string szdesip; public int desport; } #region API函數 [DllImport("ControlCAN.dll", EntryPoint = "VCI_OpenDevice", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.StdCall)] public static extern uint VCI_OpenDevice(uint DeviceType, uint DeviceInd, uint Reserved); [DllImport("ControlCAN.dll", EntryPoint = "VCI_CloseDevice", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.StdCall)] public static extern uint VCI_CloseDevice(uint DeviceType, uint DeviceInd); [DllImport("ControlCAN.dll", EntryPoint = "VCI_InitCAN", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.StdCall)] public static extern uint VCI_InitCAN(uint DeviceType, uint DeviceInd, uint CANInd, ref VCI_INIT_CONFIG pInitConfig); [DllImport("ControlCAN.dll", EntryPoint = "VCI_ReadBoardInfo", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.StdCall)] public static extern uint VCI_ReadBoardInfo(uint DeviceType, uint DeviceInd, ref VCI_BOARD_INFO pInfo); [DllImport("ControlCAN.dll", EntryPoint = "VCI_ReadErrInfo", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.StdCall)] public static extern uint VCI_ReadErrInfo(uint DeviceType, uint DeviceInd, uint CANInd, ref VCI_ERR_INFO pErrInfo); [DllImport("ControlCAN.dll", EntryPoint = "VCI_ReadCANStatus", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.StdCall)] public static extern uint VCI_ReadCANStatus(uint DeviceType, uint DeviceInd, uint CANInd, ref VCI_CAN_STATUS pCANStatus); [DllImport("ControlCAN.dll", EntryPoint = "VCI_GetReference", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.StdCall)] public static extern uint VCI_GetReference(uint DeviceType, uint DeviceInd, uint CANInd, uint RefType, object pData); [DllImport("ControlCAN.dll", EntryPoint = "VCI_SetReference", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.StdCall)] public static extern uint VCI_SetReference(uint DeviceType, uint DeviceInd, uint CANInd, uint RefType, object pData); [DllImport("ControlCAN.dll", EntryPoint = "VCI_GetReceiveNum", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.StdCall)] public static extern uint VCI_GetReceiveNum(uint DeviceType, uint DeviceInd, uint CANInd); [DllImport("ControlCAN.dll", EntryPoint = "VCI_ClearBuffer", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.StdCall)] public static extern uint VCI_ClearBuffer(uint DeviceType, uint DeviceInd, uint CANInd); [DllImport("ControlCAN.dll", EntryPoint = "VCI_StartCAN", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.StdCall)] public static extern uint VCI_StartCAN(uint DeviceType, uint DeviceInd, uint CANInd); [DllImport("ControlCAN.dll", EntryPoint = "VCI_ResetCAN", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.StdCall)] public static extern uint VCI_ResetCAN(uint DeviceType, uint DeviceInd, uint CANInd); [DllImport("ControlCAN.dll", EntryPoint = "VCI_Transmit", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.StdCall)] public static extern uint VCI_Transmit(uint DeviceType, uint DeviceInd, uint CANInd, ref VCI_CAN_OBJ pSend, uint Len); [DllImport("ControlCAN.dll", EntryPoint = "VCI_Receive", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.StdCall)] public static extern uint VCI_Receive(uint DeviceType, uint DeviceInd, uint CANInd, ref VCI_CAN_OBJ pReceive, uint Len, int WaitTime); #endregion }

 

注意:在使用過程中,需要把ControlCAN.dll並kerneldlls檔案夾及其下面的所有DLL都添加到工程中,並且把這些檔案的“Copy到輸出檔案”屬性設定為“常拷貝”。

 

發送和接收比較的容易出問題,範例程式碼如下:

CANApi.VCI_CAN_OBJ[] frameInfo = new CANApi.VCI_CAN_OBJ[1]; frameInfo[0].DataLen = (byte)(ss.Length); frameInfo[0].Data = data; frameInfo[0].Reserved = new byte[3]; frameInfo[0].RemoteFlag = (byte)this.combFrameFormat.SelectedIndex; frameInfo[0].ExternFlag = (byte)this.combFrameType.SelectedIndex; uint frameID = 0; if (!uint.TryParse(this.txtFrameID.Text, System.Globalization.NumberStyles.AllowHexSpecifier, null, out frameID)) frameID = 0; if (frameInfo[0].ExternFlag == 1) { frameInfo[0].ID = frameID; } else { frameInfo[0].ID = frameID | 0x0000FFFF; } frameInfo[0].SendType = (byte)this.combSendFormat.SelectedIndex; CANApi.VCI_Transmit(this.mDeviceType, this.mDeviceIndex, this.mCANIndex, ref frameInfo[0], 1);

 

CANApi.VCI_CAN_OBJ[] frameInfos = new CANApi.VCI_CAN_OBJ[50]; len = (int)CANApi.VCI_Receive(this.mDeviceType, this.mDeviceIndex, this.mCANIndex, ref frameInfos[0], 50, 200); if (len <= 0) { //注意:如果沒有讀到資料則必須調用此函數來讀取出當前的錯誤碼, //千萬不能省略這一步(即使你可能不想知道錯誤碼是什麼) CANApi.VCI_ReadErrInfo(this.mDeviceType, this.mDeviceIndex, this.mCANIndex, ref errInfo); } else {...

 

 

運行效果圖如下:

 

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.