• Advantech 硬件控制卡的 c# 接口函数


    最近要用到 Advantech 的 PCI-1752、PCI-1754 卡,但却苦于没有 c# 的调用接口函数。这两天接连奋战,根据 Delphi 的调用接口给转换掉,终于调试出来了,辛苦。

    现共享一下主要的接口部分,免得大家多走弯路。

    using System;
    using System.Collections.Generic;
    using System.Text;
    using System.Runtime.InteropServices;

    namespace Hardware.Advantech.Interface
    {
        
    #region PT_DEVLIST

        
    /// <summary>
        
    /// 安装在主机上所有的自动控制板卡设备结构。
        
    /// </summary>
        [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack=1)]
        
    public struct PT_DEVLIST
        {
            
    public UInt32 dwDeviceNum;
            
    /// <summary>
            
    /// 设备名,50个字符长。
            
    /// </summary>
            [MarshalAs(UnmanagedType.ByValTStr, SizeConst=50)] 
            
    public string szDeviceName;
            
    /// <summary>
            
    /// 设备的端口数,一般为8个端口。
            
    /// </summary>
            public Int16 nNumOfSubdevices;
        }

        
    /// <summary>
        
    /// 用于 DRV_DeviceGetList 调用返回的设备列表结构。
        
    /// 这一块真难改呀~~,耗费了我一整个晚上的时间~~~~~~~
        
    /// 网上也找不到资料,最可气的是.Net带的函数都不支持结构数组,只好变相再来一个结构了~~
        
    /// xiefang 2007/09/02
        
    /// </summary>
        [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 1)]
        
    public struct PT_DEVLISTARRAY
        {
            [MarshalAs(UnmanagedType.ByValArray, SizeConst 
    = AdvantechAPI.MaxEntries)]
            
    public PT_DEVLIST[] Devices;
        }

        
    #endregion

        
    #region PT_DeviceGetFeatures

        [StructLayout(LayoutKind.Sequential, CharSet 
    = CharSet.Ansi, Pack = 1)]
        
    internal struct PT_DeviceGetFeatures
        {
            
    public IntPtr Buffer;
            
    public int Size;
        }

        [StructLayout(LayoutKind.Sequential, CharSet 
    = CharSet.Ansi, Pack = 1)]
        
    public struct GainListBlob
        {
            [MarshalAs(UnmanagedType.ByValArray, SizeConst 
    = 448)]
            
    public byte[] gainArr;
        }

        
    /// <summary>
        
    /// Define hardware board(device) features.
        
    /// </summary>
        [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 1)]
        
    public struct DEVFEATURES
        {
            
    /// <summary>
            
    /// device driver version, array[0..7]
            
    /// </summary>
            [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 8)]
            
    public string szDriverVer;
            
    /// <summary>
            
    /// device driver name, array[0..MAX_DRIVER_NAME_LEN-1]
            
    /// </summary>
            [MarshalAs(UnmanagedType.ByValTStr, SizeConst = AdvantechAPI.MAX_DRIVER_NAME_LEN)]
            
    public string szDriverName;
            
    /// <summary>
            
    /// board ID, DWORD 4 bytes
            
    /// </summary>
            public uint dwBoardID;
            
    /// <summary>
            
    /// Max. number of differential channel
            
    /// </summary>
            public ushort usMaxAIDiffChl;
            
    /// <summary>
            
    /// Max. number of single-end channel
            
    /// </summary>
            public ushort usMaxAISiglChl;
            
    /// <summary>
            
    /// Max. number of D/A channel
            
    /// </summary>
            public ushort usMaxAOChl;
            
    /// <summary>
            
    /// Max. number of digital out channel
            
    /// </summary>
            public ushort usMaxDOChl;
            
    /// <summary>
            
    /// Max. number of digital input channel
            
    /// </summary>
            public ushort usMaxDIChl;
            
    /// <summary>
            
    /// specifies if programmable or not
            
    /// </summary>
            public ushort usDIOPort;
            
    /// <summary>
            
    /// Max. number of Counter/Timer channel
            
    /// </summary>
            public ushort usMaxTimerChl;
            
    /// <summary>
            
    /// Max number of  alram channel
            
    /// </summary>
            public ushort usMaxAlarmChl;
            
    /// <summary>
            
    /// number of bits for A/D converter
            
    /// </summary>
            public ushort usNumADBit;
            
    /// <summary>
            
    /// A/D channel width in bytes.
            
    /// </summary>
            public ushort usNumADByte;
            
    /// <summary>
            
    /// number of bits for D/A converter. 
            
    /// </summary>
            public ushort usNumDABit;
            
    /// <summary>
            
    /// D/A channel width in bytes.
            
    /// </summary>
            public ushort usNumDAByte;
            
    /// <summary>
            
    /// Max. number of gain code
            
    /// </summary>
            public ushort usNumGain;
            
    /// <summary>
            
    /// Gain listing array[0..15]
            
    /// </summary>
            public GainListBlob glGainList;
            
    /// <summary>
            
    /// Permutation array[0..3]
            
    ///   Bit 0: Software AI                                           
            
    ///   Bit 1: DMA AI                                                
            
    ///   Bit 2: Interrupt AI                                          
            
    ///   Bit 3: Condition AI
            
    ///   Bit 4: Software AO
            
    ///   Bit 5: DMA AO
            
    ///   Bit 6: Interrupt AO
            
    ///   Bit 7: Condition AO
            
    ///   Bit 8: Software DI
            
    ///   Bit 9: DMA DI
            
    ///   Bit 10: Interrupt DI
            
    ///   Bit 11: Condition DI
            
    ///   Bit 12: Software DO
            
    ///   Bit 13: DMA DO
            
    ///   Bit 14: Interrupt DO
            
    ///   Bit 15: Condition DO
            
    ///   Bit 16: High Gain
            
    ///   Bit 17: Auto Channel Scan
            
    ///   Bit 18: Pacer Trigger
            
    ///   Bit 19: External Trigger
            
    ///   Bit 20: Down Counter
            
    ///   Bit 21: Dual DMA
            
    ///   Bit 22: Monitoring
            
    ///   Bit 23: QCounter                                             
            
    /// </summary>
            public uint dwPermutation0;
            
    public uint dwPermutation1;
            
    public uint dwPermutation2;
            
    public uint dwPermutation3;
        }

        
    #endregion

        
    /// <summary>
        
    /// 写入设备的数据结构。
        
    /// </summary>
        [StructLayout(LayoutKind.Explicit, CharSet = CharSet.Ansi, Pack = 1)]
        
    internal struct PT_DioWritePortByte
        {
            [FieldOffset(
    0)]
            
    public short Port;
            [FieldOffset(
    2)]
            
    public short Mask;
            [FieldOffset(
    4)]
            
    public short State;
        }

        
    /// <summary>
        
    /// 读取IO设备的数据结构。
        
    /// </summary>
        [StructLayout(LayoutKind.Explicit, CharSet = CharSet.Ansi, Pack = 1)]
        
    internal struct PT_DioReadPortByte
        {
            [FieldOffset(
    0)]
            
    public short Port;
            [FieldOffset(
    4)]
            
    public IntPtr value;
        }

        
    /// <summary>
        
    /// 硬件调用的 API 函数封装类。
        
    /// </summary>
        public static class AdvantechAPI
        {
            
    /// <summary>
            
    /// 最大设备个数
            
    /// </summary>
            public const short MaxEntries = 255;
            
    public const short MaxDevices = 255;
            
    public const short MAX_DRIVER_NAME_LEN = 16;

            
    #region interface

            
    /// <summary>
            
    /// 获取设备列表。
            
    /// </summary>
            
    /// <param name="deviceList">返回的设备列表清单数组</param>
            
    /// <param name="maxEntries">最大的设备数</param>
            
    /// <param name="outEntries">返回的设备数</param>
            
    /// <returns>返回值为 0 则表示执行成功,否则执行失败。</returns>
            [DllImport("adsapi32.dll", CharSet = CharSet.Ansi)]
            
    static extern int DRV_DeviceGetList(IntPtr deviceList, Int16 maxEntries, ref short outEntries);

            [DllImport(
    "adsapi32.dll", CharSet = CharSet.Ansi)]
            
    static extern int DRV_DeviceGetFeatures(int DriverHandle, ref PT_DeviceGetFeatures lpDeviceGetFeatures);

            
    /// <summary>
            
    /// 获取设备列表个数,我就基本用不到它,姑且留着。
            
    /// </summary>
            
    /// <param name="numOfDevices"></param>
            
    /// <returns></returns>
            [DllImport("adsapi32.dll", CharSet = CharSet.Ansi)]
            
    public static extern int DRV_DeviceGetNumOfList(ref short numOfDevices);

            
    /// <summary>
            
    /// 打开设备。
            
    /// </summary>
            
    /// <param name="deviceNum">设备号</param>
            
    /// <param name="driverHandle">设备句柄</param>
            
    /// <returns></returns>
            [DllImport("adsapi32.dll", CharSet = CharSet.Ansi)]
            
    static extern int DRV_DeviceOpen(uint deviceNum, ref int deviceHandle);

            
    /// <summary>
            
    /// 关闭设备。
            
    /// </summary>
            
    /// <param name="deviceHandle"></param>
            
    /// <returns></returns>
            [DllImport("adsapi32.dll", CharSet = CharSet.Ansi)]
            
    static extern int DRV_DeviceClose(ref int deviceHandle);
            
    /// <summary>
            
    /// 向端口写数字信号。
            
    /// </summary>
            
    /// <param name="DriverHandle"></param>
            
    /// <param name="lpDioWritePortByte"></param>
            
    /// <returns></returns>
            [DllImport("adsapi32.dll", CharSet = CharSet.Ansi)]
            
    static extern int DRV_DioWritePortByte(int driverHandle, ref PT_DioWritePortByte lpDioWritePortByte);

            [DllImport(
    "adsapi32.dll", CharSet = CharSet.Ansi)]
            
    static extern int DRV_DioReadPortByte(int driverHandle, ref PT_DioReadPortByte lpDioReadPortByte);

            
    #endregion

            
    /// <summary>
            
    /// 打开设备
            
    /// </summary>
            
    /// <param name="deviceNum">设备号</param>
            
    /// <param name="deviceHandle">设备句柄</param>
            
    /// <returns>返回错误代码,如果无错误,则返回0。</returns>
            public static int OpenDevice(uint deviceNum, ref int deviceHandle)
            {
                
    return DRV_DeviceOpen(deviceNum, ref deviceHandle);
            }

            
    /// <summary>
            
    /// 关闭设备。
            
    /// </summary>
            
    /// <param name="deviceHandle"></param>
            public static void CloseDevice(int deviceHandle)
            {
                DRV_DeviceClose(
    ref deviceHandle);
            }

            
    /// <summary>
            
    /// 获取主机上安装的设备列表。
            
    /// </summary>
            
    /// <returns>返回错误代码,如果无错误,则返回0。</returns>
            public static int GetDeviceList(out PT_DEVLISTARRAY deviceList, ref short outEntries)
            {
                deviceList 
    = new PT_DEVLISTARRAY();
                
    int _DeviceListLenght = Marshal.SizeOf(deviceList);
                IntPtr _DeviceListPoint 
    = Marshal.AllocHGlobal(_DeviceListLenght);
                
    //打开设备的检查过程
                int errorCode = AdvantechAPI.DRV_DeviceGetList(_DeviceListPoint, MaxEntries, ref outEntries);
                deviceList 
    = (PT_DEVLISTARRAY)Marshal.PtrToStructure(_DeviceListPoint, typeof(PT_DEVLISTARRAY));
                Marshal.FreeHGlobal(_DeviceListPoint);
                
    return errorCode;
            }

            
    public static int GetFeatures(int deviceHandle, out DEVFEATURES outDevFeatures)
            {
                
    int iLength;
                
    int ErrCde = 0;
                PT_DeviceGetFeatures ptDevGetFeatures 
    = new PT_DeviceGetFeatures();
                outDevFeatures 
    = new DEVFEATURES();

                outDevFeatures.szDriverVer 
    = "?";
                outDevFeatures.szDriverName 
    = "?";
                iLength 
    = Marshal.SizeOf(outDevFeatures);
                
    //and reserve the space 
                IntPtr DevFeaturesPointer = Marshal.AllocHGlobal(iLength);
                
    //Copy the pointer into the struct
                ptDevGetFeatures.Buffer = DevFeaturesPointer;
                
    //and get the features
                ErrCde = DRV_DeviceGetFeatures(deviceHandle, ref ptDevGetFeatures);
                
    if (ErrCde == 0)
                {
                    outDevFeatures 
    = (DEVFEATURES)Marshal.PtrToStructure(DevFeaturesPointer, typeof(DEVFEATURES));
                }
                
    else
                {
                    
    //Error
                }
                Marshal.FreeHGlobal(DevFeaturesPointer);
                
    return ErrCde;
            }

            
    /// <summary>
            
    /// 数字信号按端口输出。
            
    /// </summary>
            
    /// <param name="deviceHandle"></param>
            
    /// <param name="port"></param>
            
    /// <param name="value"></param>
            
    /// <param name="mask"></param>
            
    /// <returns></returns>
            public static int Digital_WriteByteToPort(int deviceHandle, short port, short value, short mask)
            {
                PT_DioWritePortByte data 
    = new PT_DioWritePortByte();
                data.Port 
    = port;
                data.State 
    = value;
                data.Mask 
    = mask;
                
    return DRV_DioWritePortByte(deviceHandle, ref data);
            }

            
    public static int Digital_WriteByteToPort(int deviceHandle, short port, short value)
            {
                
    return Digital_WriteByteToPort(deviceHandle, port, value, 255);
            }

            
    /// <summary>
            
    /// 从指定的端口获取数据。
            
    /// </summary>
            
    /// <param name="deviceHandle"></param>
            
    /// <param name="port"></param>
            
    /// <param name="value"></param>
            
    /// <returns></returns>
            public static int Digital_ReadByteFromPort(int deviceHandle, short port, out short value)
            {
                
    int error = 0;
                
    short tempValue = 0;
                IntPtr vpoint 
    = Marshal.AllocHGlobal(Marshal.SizeOf(tempValue));
                
    try
                {
                    Marshal.StructureToPtr(tempValue, vpoint, 
    false);
                    PT_DioReadPortByte data 
    = new PT_DioReadPortByte();
                    data.Port 
    = port;
                    data.value 
    = vpoint;
                    error 
    = DRV_DioReadPortByte(deviceHandle, ref data);
                    tempValue 
    = (short)Marshal.PtrToStructure(vpoint, typeof(short));
                    value 
    = tempValue;
                }
                
    finally
                {
                    Marshal.FreeHGlobal(vpoint);
                }
                
    return error;
            }

        }

    }


    PCI_Base:

    using System;
    using System.ComponentModel;
    using System.Collections.Generic;
    using System.Collections;
    using System.Diagnostics;
    using System.Text;
    using System.Windows.Forms;

    namespace Hardware.Advantech
    {
        
    using System.Runtime.InteropServices;
        
    using Hardware.Advantech.Interface;

        
    /// <summary>
        
    /// PCI 硬件的基础类。
        
    /// </summary>
        [ToolboxItem(false), DefaultProperty("Connected")]
        
    public partial class PCI_Base : Component
        {
            
    #region 公共静态变量

            
    /// <summary>
            
    /// 获取主机上能检测到的设备个数,这个设备数量包括输入设备以及输出设备。
            
    /// </summary>
            private static short _OutEntries = 0;
            
    private static PT_DEVLISTARRAY _DeviceList;

            
    #endregion

            
    private string _DeviceName = string.Empty;
            
    private int _DeviceIndex = -1;
            
    private int _PortCount = 0;
            
    private uint _DeviceNum = 0;
            
    private bool _Connected = false;
            
    protected int _DeviceHandle = -1;
            
    protected DEVFEATURES _DevFeatures;

            
    public PCI_Base()
            {
                InitializeComponent();
            }

            
    public PCI_Base(IContainer container)
            {
                container.Add(
    this);

                InitializeComponent();
            }

            
    #region 公共属性

            
    #region 静态全局属性

            
    /// <summary>
            
    /// 获取主机上能检测到的设备个数,这个设备数量包括输入设备以及输出设备。
            
    /// </summary>
            public static short OutEntries
            {
                
    get { return _OutEntries; }
            }

            
    /// <summary>
            
    /// 
            
    /// </summary>
            public static PT_DEVLISTARRAY DeviceList
            {
                
    get { return _DeviceList; }
            }

            
    #endregion

            
    /// <summary>
            
    /// 获取设备名称。
            
    /// </summary>
            [Browsable(false)]
            
    public string DeviceName
            {
                
    get { return _DeviceName; }
            }

            
    /// <summary>
            
    /// 获取设备索引。
            
    /// </summary>
            [Browsable(false)]
            
    public int DeviceIndex
            {
                
    get { return _DeviceIndex; }
            }

            
    /// <summary>
            
    /// 获取设备端口数。
            
    /// </summary>
            [Browsable(false)]
            
    public int PortCount
            {
                
    get { return _PortCount; }
            }

            
    /// <summary>
            
    /// 获取设备数。
            
    /// </summary>
            [Browsable(false)]
            
    public uint DeviceNum
            {
                
    get { return _DeviceNum; }
            }

            
    /// <summary>
            
    /// 获取设备的识别名。
            
    /// </summary>
            [Browsable(false)]
            
    public virtual string DeviceSymbol 
            {
                
    get { return ""; }
            }

            
    /// <summary>
            
    /// 获取或设置连接属性。
            
    /// </summary>
            [Description("获取或设置连接属性。"), DefaultValue(false)]
            
    public bool Connected
            {
                
    get { return _Connected; }
                
    set
                {
                    
    if (value)
                    {
                        
    //打开设备的检查过程
                        if (_OutEntries <= 0)
                        {
                            
    if (!RefreshDeviceList()) return;
                        }
                        _DeviceIndex 
    = GetDeviceIndex();
                        
    //如果找到设备的索引,则继续查找端口号
                        if (_DeviceIndex != -1)
                        {
                            _DeviceName 
    = PCI_Base.DeviceList.Devices[_DeviceIndex].szDeviceName;
                            
    int portCount = _DeviceList.Devices[_DeviceIndex].nNumOfSubdevices;
                            
    if (portCount > AdvantechAPI.MaxDevices) portCount = AdvantechAPI.MaxDevices;
                            _DeviceNum 
    = _DeviceList.Devices[_DeviceIndex].dwDeviceNum;

                            
    //打开设备
                            if (!IsError(AdvantechAPI.OpenDevice(_DeviceNum, ref _DeviceHandle)))
                            {
                                _PortCount 
    = GetPortCount(_DeviceHandle, out _DevFeatures);
                                _Connected 
    = value;
                            }
                        }
                    }
                    
    else
                    {
                        AdvantechAPI.CloseDevice(_DeviceHandle);
                        _DeviceIndex 
    = -1;
                        _PortCount 
    = 0;
                        _DeviceNum 
    = 0;
                        _DeviceHandle 
    = -1;
                        _DeviceName 
    = "";
                        _Connected 
    = value;
                    }
                    
    //触发连接变更事件
                    if (OnConnectionChanged != null) OnConnectionChanged(this, EventArgs.Empty);
                }
            }

            
    #endregion

            
    #region 方法

            
    /// <summary>
            
    /// 检查错误代码是否是发生了错误。
            
    /// </summary>
            
    /// <param name="errorCode"></param>
            
    /// <returns>如果是错误,则返回 True,否则返回 False。</returns>
            protected bool IsError(int errorCode)
            {
                
    if (errorCode != 0
                    MessageBox.Show(
    "Error");
                
    return errorCode != 0;
            }

            
    /// <summary>
            
    /// 更新设备列表。该方法一般在创建基于 PCI_BASE 的对象时会自动进行调用,以创建
            
    /// 主机上存在的设备列表。除非需要手工刷新,否则,不应直接调用该方法。
            
    /// </summary>
            public static bool RefreshDeviceList()
            {
                Debug.WriteLine(
    "Execute RefreshDeviceList");
                
    //打开设备的检查过程
                return AdvantechAPI.GetDeviceList(out _DeviceList, ref _OutEntries) == 0;
            }

            
    /// <summary>
            
    /// 获取设备索引号
            
    /// </summary>
            
    /// <returns></returns>
            protected int GetDeviceIndex()
            {
                
    int iIndex = -1;
                
    for (int i = 0; i < OutEntries; i++)
                {
                    
    string sDeviceName = PCI_Base.DeviceList.Devices[i].szDeviceName.ToUpper().Trim();
                    
    if (sDeviceName.StartsWith(DeviceSymbol.ToUpper()))
                    {
                        iIndex 
    = i;
                        
    break;
                    }
                }
                
    return iIndex;
            }

            
    /// <summary>
            
    /// 获取端口数量,不应直接使用。
            
    /// </summary>
            
    /// <param name="deviceHandle"></param>
            
    /// <param name="deviceFeatures"></param>
            
    /// <returns></returns>
            protected virtual int GetPortCount(int deviceHandle, out DEVFEATURES deviceFeatures)
            {
                deviceFeatures 
    = new DEVFEATURES();
                
    return 0;
            }

            
    private short ReadData(short port)
            {
                
    short value = 255;
                IsError(AdvantechAPI.Digital_ReadByteFromPort(_DeviceHandle, port, 
    out value));
                
    return value;
            }

            
    private void WriteData(short port, short value)
            {
                WriteData(port, value, 
    255);
            }

            
    private void WriteData(short port, short value, short mask)
            {
                IsError(AdvantechAPI.Digital_WriteByteToPort(_DeviceHandle, port, value, mask));
            }

            
    /// <summary>
            
    /// 清除所有端口数据。
            
    /// </summary>
            public void Clear()
            {
                
    for (short i = 0; i < PortCount; i++)
                    
    this[i] = 0;
            }

            
    /// <summary>
            
    /// 获取或设置指定端口数据。
            
    /// </summary>
            
    /// <param name="port">端口号,范围:0..最大端口 - 1。</param>
            
    /// <returns>端口值</returns>
            public short this[short port]
            {
                
    get
                {
                    
    return ReadData(port);
                }
                
    set
                {
                    WriteData(port, value);
                }
            }

            
    /// <summary>
            
    /// 获取或设置指定端口指定位的值。
            
    /// </summary>
            
    /// <param name="port">端口号,范围:0..最大端口 - 1。</param>
            
    /// <param name="bit">端口中指定的位,范围:0..7。</param>
            
    /// <returns></returns>
            public bool this[short port, int bit]
            {
                
    get
                {
                    
    short a = (short)Math.Pow(2, bit);
                    
    int[] dt = new int[1] { (intthis[port] };
                    BitArray result 
    = new BitArray(dt);
                    
    if (result.Length > bit)
                    {
                        
    return result[bit];
                    }
                    
    else return false;
                }
                
    set
                {
                    
    if (value)
                    {
                        
    short a = (short)Math.Pow(2, bit);
                        
    this[port] |= a;
                    }
                    
    else
                    {
                        
    short a = (short)(255 - (short)Math.Pow(2, bit));
                        
    this[port] &= a;
                    }
                }
            }

            
    #endregion

            
    #region 公共事件

            
    /// <summary>
            
    /// 触发连接变更事件
            
    /// </summary>
            public event EventHandler OnConnectionChanged;

            
    #endregion
        }
    }


     PCI_1752:

    using System;
    using System.ComponentModel;
    using System.Collections.Generic;
    using System.Collections;
    using System.Diagnostics;
    using System.Text;

    namespace Hardware.Advantech
    {
        
    using Hardware.Advantech.Interface;

        
    /// <summary>
        
    /// 输出卡类。
        
    /// </summary>
        [ToolboxItem(true)]
        
    public partial class PCI_1752 : PCI_Base
        {
            
    public PCI_1752()
            {
                InitializeComponent();
            }

            
    public PCI_1752(IContainer container)
            {
                container.Add(
    this);

                InitializeComponent();
            }

            
    public override string DeviceSymbol
            {
                
    get { return "PCI-1752"; }
            }

            
    protected override int GetPortCount(int deviceHandle, out DEVFEATURES deviceFeatures)
            {
                
    int portCount = 0;
                
    if (!IsError(AdvantechAPI.GetFeatures(deviceHandle, out deviceFeatures)))
                {
                    portCount 
    = _DevFeatures.usMaxDOChl / 8;
                }
                
    return portCount;
            }
        }
    }

    PCI_1754:

    using System;
    using System.ComponentModel;
    using System.Collections.Generic;
    using System.Diagnostics;
    using System.Text;
    using System.Windows.Forms;

    namespace Hardware.Advantech
    {
        
    using Hardware.Advantech.Interface;

        
    /// <summary>
        
    /// 输入卡类。
        
    /// </summary>
        [ToolboxItem(true), DefaultEvent("DataInput")]
        
    public partial class PCI_1754 : PCI_Base
        {
            
    int _interval = 100;

            
    public PCI_1754()
            {
                InitializeComponent();
            }

            
    public PCI_1754(IContainer container)
            {
                container.Add(
    this);

                InitializeComponent();
            }

            
    public override string DeviceSymbol
            {
                
    get { return "PCI-1754"; }
            }

            
    protected override int GetPortCount(int deviceHandle, out DEVFEATURES deviceFeatures)
            {
                
    int portCount = 0;
                
    if (!IsError(AdvantechAPI.GetFeatures(deviceHandle, out deviceFeatures)))
                {
                    portCount 
    = _DevFeatures.usMaxDIChl / 8;
                }
                
    return portCount;
            }

            
    #region Thread

            
    /// <summary>
            
    /// 获取或设置读信号线程的间隔时间,单位为毫秒。
            
    /// </summary>
            [Browsable(true), Description("获取或设置读信号线程的间隔时间,单位为毫秒。"), DefaultValue(100)]
            
    public int Interval
            {
                
    get
                {
                    
    return _interval;
                }
                
    set
                {
                    _interval 
    = value;
                }
            }

            
    /// <summary>
            
    /// 启动读线程。
            
    /// </summary>
            public void StartReadWork()
            {
                backgroundReadWorker.RunWorkerAsync();
            }

            
    /// <summary>
            
    /// 停止读线程。
            
    /// </summary>
            public void StopReadWork()
            {
                backgroundReadWorker.CancelAsync();
            }

            
    private void backgroundReadWorker_DoWork(object sender, DoWorkEventArgs e)
            {
                BackgroundWorker worker 
    = sender as BackgroundWorker;
                
    do
                {
                    
    for (short i = 0; i < PortCount; i++)
                    {
                        
    for (short j = 0; j < 8; j++)
                        {
                            
    if (this[i, j] == true)
                            {
                                
    if (DataInput != null)
                                {
                                    DataInput(
    this, i, j);
                                }
                            }
                        }
                    }
                    System.Threading.Thread.Sleep(_interval);
                }
                
    while (!worker.CancellationPending);
                e.Cancel 
    = true;
            }

            
    private void backgroundReadWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
            {
                
    if (e.Error != null)
                {
                    
    //MessageBox.Show(e.Error.Message);
                }
                
    else if (e.Cancelled)
                {
                    
    // Next, handle the case where the user canceled 
                    
    // the operation.
                    
    // Note that due to a race condition in 
                    
    // the DoWork event handler, the Cancelled
                    
    // flag may not have been set, even though
                    
    // CancelAsync was called.
                    
    //触发停止事件。
                }
                
    else
                {
                    
    // Finally, handle the case where the operation 
                    
    // succeeded.
                    
    //正常结束。
                }
            }

            
    public event RaiseDataInput DataInput;

            
    #endregion
        }

        
    public delegate void RaiseDataInput(object sender, short port, short bit);
    }
  • 相关阅读:
    linux学习17 运维核心技能-Linux系统下用户权限管理
    linux学习16 Linux用户和组管理命令演练和实战应用
    linux学习15 Linux系统用户和组全面讲解
    linux学习14 Linux运维高级系统应用-glob通配及IO重定向
    linux学习13 Linux运维常用文件管理命令及系统变量基础
    linux学习12 bash的常见特性及文本查看命令实战
    linux学习11 Linux基础命令及命令历史
    linux学习10 Linux目录结构和根文件系统全面讲解
    【Hadoop离线基础总结】Hive调优手段
    【Hadoop离线基础总结】Hive的基本操作
  • 原文地址:https://www.cnblogs.com/xiefang2008/p/881907.html
Copyright © 2020-2023  润新知