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 ] { ( int this [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);
}

转载于:https://www.cnblogs.com/xiefang2008/archive/2007/10/20/881907.html

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值