C# API 串口通信 代码

来源:互联网 发布:imo软件 编辑:程序博客网 时间:2024/05/16 09:26

class   CommPort   {  
   
  public   string   PortNum;    
  public   int   BaudRate;  
  public   byte   ByteSize;  
  public   byte   Parity;   //   0-4=no,odd,even,mark,space    
  public   byte   StopBits;   //   0,1,2   =   1,   1.5,   2    
  public   int   ReadTimeout;  
   
  //comm   port   win32   file   handle  
  private   int   hComm   =   -1;  
   
  public   bool   Opened   =   false;  
     
  //win32   api   constants  
    private   const   uint   GENERIC_READ   =   0x80000000;  
    private   const   uint   GENERIC_WRITE   =   0x40000000;  
    private   const   int   OPEN_EXISTING   =   3;  
    private   const   int   INVALID_HANDLE_VALUE   =   -1;  
   
  [StructLayout(LayoutKind.Sequential)]  
  public   struct   DCB   {  
  //taken   from   c   struct   in   platform   sdk    
  public   int   DCBlength;   //   sizeof(DCB)    
  public   int   BaudRate;   //   指定当前波特率   current   baud   rate  
  //   these   are   the   c   struct   bit   fields,   bit   twiddle   flag   to   set  
  public   int   fBinary;   //   指定是否允许二进制模式,在windows95中必须主TRUE   binary   mode,   no   EOF   check    
  public   int   fParity;   //   指定是否允许奇偶校验   enable   parity   checking    
  public   int   fOutxCtsFlow;   //   指定CTS是否用于检测发送控制,当为TRUE是CTS为OFF,发送将被挂起。   CTS   output   flow   control    
  public   int   fOutxDsrFlow;   //   指定CTS是否用于检测发送控制   DSR   output   flow   control    
  public   int   fDtrControl;   //   DTR_CONTROL_DISABLE值将DTR置为OFF,   DTR_CONTROL_ENABLE值将DTR置为ON,   DTR_CONTROL_HANDSHAKE允许DTR"握手"   DTR   flow   control   type    
  public   int   fDsrSensitivity;   //   当该值为TRUE时DSR为OFF时接收的字节被忽略   DSR   sensitivity    
  public   int   fTXContinueOnXoff;   //   指定当接收缓冲区已满,并且驱动程序已经发送出XoffChar字符时发送是否停止。TRUE时,在接收缓冲区接收到缓冲区已满的字节XoffLim且驱动程序已经发送出XoffChar字符中止接收字节之后,发送继续进行。 FALSE时,在接收缓冲区接收到代表缓冲区已空的字节XonChar且驱动程序已经发送出恢复发送的XonChar之后,发送继续进行。XOFF   continues   Tx    
  public   int   fOutX;   //   TRUE时,接收到XoffChar之后便停止发送接收到XonChar之后将重新开始   XON/XOFF   out   flow   control    
  public   int   fInX;   //   TRUE时,接收缓冲区接收到代表缓冲区满的XoffLim之后,XoffChar发送出去接收缓冲区接收到代表缓冲区空的XonLim之后,XonChar发送出去   XON/XOFF   in   flow   control    
  public   int   fErrorChar;   //   该值为TRUE且fParity为TRUE时,用ErrorChar   成员指定的字符代替奇偶校验错误的接收字符   enable   error   replacement    
  public   int   fNull;   //   eTRUE时,接收时去掉空(0值)字节   enable   null   stripping    
  public   int   fRtsControl;   //   RTS   flow   control    
  /*RTS_CONTROL_DISABLE时,RTS置为OFF  
   RTS_CONTROL_ENABLE时,   RTS置为ON  
    RTS_CONTROL_HANDSHAKE时,  
    当接收缓冲区小于半满时RTS为ON  
    当接收缓冲区超过四分之三满时RTS为OFF  
    RTS_CONTROL_TOGGLE时,  
    当接收缓冲区仍有剩余字节时RTS为ON   ,否则缺省为OFF*/  
   
  public   int   fAbortOnError;   //   TRUE时,有错误发生时中止读和写操作   abort   on   error    
  public   int   fDummy2;   //   未使用   reserved    
   
  public   uint   flags;  
  public   ushort   wReserved;   //   未使用,必须为0   not   currently   used    
  public   ushort   XonLim;   //   指定在XON字符发送这前接收缓冲区中可允许的最小字节数   transmit   XON   threshold    
  public   ushort   XoffLim;   //   指定在XOFF字符发送这前接收缓冲区中可允许的最小字节数   transmit   XOFF   threshold    
  public   byte   ByteSize;   //   指定端口当前使用的数据位number   of   bits/byte,   4-8    
  public   byte   Parity;   //   指定端口当前使用的奇偶校验方法,可能为:EVENPARITY,MARKPARITY,NOPARITY,ODDPARITY   0-4=no,odd,even,mark,space    
  public   byte   StopBits;   //   指定端口当前使用的停止位数,可能为:ONESTOPBIT,ONE5STOPBITS,TWOSTOPBITS   0,1,2   =   1,   1.5,   2    
  public   char   XonChar;   //   指定用于发送和接收字符XON的值   Tx   and   Rx   XON   character    
  public   char   XoffChar;   //   指定用于发送和接收字符XOFF值   Tx   and   Rx   XOFF   character    
  public   char   ErrorChar;   //   本字符用来代替接收到的奇偶校验发生错误时的值   error   replacement   character    
  public   char   EofChar;   //   当没有使用二进制模式时,本字符可用来指示数据的结束   end   of   input   character    
  public   char   EvtChar;   //   当接收到此字符时,会产生一个事件   received   event   character    
  public   ushort   wReserved1;   //   未使用   reserved;   do   not   use    
  }  
   
  [StructLayout(LayoutKind.Sequential)]  
  private   struct   COMMTIMEOUTS   {    
    public   int   ReadIntervalTimeout;    
    public   int   ReadTotalTimeoutMultiplier;    
    public   int   ReadTotalTimeoutConstant;    
    public   int   WriteTotalTimeoutMultiplier;    
    public   int   WriteTotalTimeoutConstant;    
  }    
   
  [StructLayout(LayoutKind.Sequential)]  
  private   struct   OVERLAPPED   {    
    public   int   Internal;    
    public   int   InternalHigh;    
    public   int   Offset;    
    public   int   OffsetHigh;    
    public   int   hEvent;    
  }    
   
  [DllImport("kernel32.dll")]  
  private   static   extern   int   CreateFile(  
    string   lpFileName,   //   要打开的串口名称  
    uint   dwDesiredAccess,   //   指定串口的访问方式,一般设置为可读可写方式  
    int   dwShareMode,   //   指定串口的共享模式,串口不能共享,所以设置为0  
    int   lpSecurityAttributes,   //   设置串口的安全属性,WIN9X下不支持,应设为NULL  
    int   dwCreationDisposition,   //   对于串口通信,创建方式只能为OPEN_EXISTING  
    int   dwFlagsAndAttributes,   //   指定串口属性与标志,设置为FILE_FLAG_OVERLAPPED(重叠I/O操作),指定串口以异步方式通信  
    int   hTemplateFile   //   对于串口通信必须设置为NULL  
  );  
  [DllImport("kernel32.dll")]  
  private   static   extern   bool   GetCommState(  
    int   hFile,   //通信设备句柄  
    ref   DCB   lpDCB   //   设备控制块DCB  
  );  
  [DllImport("kernel32.dll")]  
  private   static   extern   bool   BuildCommDCB(  
    string   lpDef,   //   设备控制字符串  
    ref   DCB   lpDCB   //   设备控制块  
  );  
  [DllImport("kernel32.dll")]  
  private   static   extern   bool   SetCommState(  
    int   hFile,   //   通信设备句柄  
    ref   DCB   lpDCB   //   设备控制块  
  );  
  [DllImport("kernel32.dll")]  
  private   static   extern   bool   GetCommTimeouts(  
    int   hFile,   //   通信设备句柄   handle   to   comm   device  
    ref   COMMTIMEOUTS   lpCommTimeouts   //   超时时间   time-out   values  
  );  
  [DllImport("kernel32.dll")]  
  private   static   extern   bool   SetCommTimeouts(  
    int   hFile,   //   通信设备句柄   handle   to   comm   device  
    ref   COMMTIMEOUTS   lpCommTimeouts   //   超时时间   time-out   values  
  );  
  [DllImport("kernel32.dll")]  
  private   static   extern   bool   ReadFile(  
    int   hFile,   //   通信设备句柄   handle   to   file  
    byte[]   lpBuffer,   //   数据缓冲区   data   buffer  
    int   nNumberOfBytesToRead,   //   多少字节等待读取   number   of   bytes   to   read  
    ref   int   lpNumberOfBytesRead,   //   读取多少字节   number   of   bytes   read  
    ref   OVERLAPPED   lpOverlapped   //   溢出缓冲区   overlapped   buffer  
  );  
  [DllImport("kernel32.dll")]  
  private   static   extern   bool   WriteFile(  
    int   hFile,   //   通信设备句柄   handle   to   file  
    byte[]   lpBuffer,   //   数据缓冲区   data   buffer  
    int   nNumberOfBytesToWrite,   //   多少字节等待写入   number   of   bytes   to   write  
    ref   int   lpNumberOfBytesWritten,   //   已经写入多少字节   number   of   bytes   written  
    ref   OVERLAPPED   lpOverlapped   //   溢出缓冲区   overlapped   buffer  
  );  
  [DllImport("kernel32.dll")]  
  private   static   extern   bool   CloseHandle(  
    int   hObject   //   handle   to   object  
  );  
  [DllImport("kernel32.dll")]  
  private   static   extern   uint   GetLastError();  
   
  public   void   Open()  
  {  
   
    DCB   dcbCommPort   =   new   DCB();  
    COMMTIMEOUTS   ctoCommPort   =   new   COMMTIMEOUTS();  
       
  Top

2 楼fsdy2000(乡愁)回复于 2005-11-02 20:08:18 得分 0

  //   打开串口   OPEN   THE   COMM   PORT.  
    hComm   =   CreateFile(PortNum   ,GENERIC_READ   |   GENERIC_WRITE,0,   0,OPEN_EXISTING,0,0);  
    //   如果串口没有打开,就打开   IF   THE   PORT   CANNOT   BE   OPENED,   BAIL   OUT.  
  if(hComm   ==   INVALID_HANDLE_VALUE)    
  {  
    throw(new   ApplicationException("非法操作,不能打开串口!"));  
  }  
   
  //   设置通信超时时间   SET   THE   COMM   TIMEOUTS.  
  GetCommTimeouts(hComm,ref   ctoCommPort);  
  ctoCommPort.ReadTotalTimeoutConstant   =   ReadTimeout;  
  ctoCommPort.ReadTotalTimeoutMultiplier   =   0;  
  ctoCommPort.WriteTotalTimeoutMultiplier   =   0;  
  ctoCommPort.WriteTotalTimeoutConstant   =   0;    
  SetCommTimeouts(hComm,ref   ctoCommPort);  
   
  //   设置串口   SET   BAUD   RATE,   PARITY,   WORD   SIZE,   AND   STOP   BITS.  
  GetCommState(hComm,   ref   dcbCommPort);  
  dcbCommPort.BaudRate=BaudRate;  
  dcbCommPort.flags=0;  
  //dcb.fBinary=1;  
  dcbCommPort.flags|=1;  
  if   (Parity>0)  
  {  
      //dcb.fParity=1  
    dcbCommPort.flags|=2;  
  }  
  dcbCommPort.Parity=Parity;  
  dcbCommPort.ByteSize=ByteSize;  
  dcbCommPort.StopBits=StopBits;  
  if   (!SetCommState(hComm,   ref   dcbCommPort))  
  {  
    //uint   ErrorNum=GetLastError();  
    throw(new   ApplicationException("非法操作,不能打开串口!"));  
  }  
    //unremark   to   see   if   setting   took   correctly  
    //DCB   dcbCommPort2   =   new   DCB();  
    //GetCommState(hComm,   ref   dcbCommPort2);  
  Opened   =   true;  
  }  
   
  public   void   Close()   {  
  if   (hComm!=INVALID_HANDLE_VALUE)   {  
  CloseHandle(hComm);  
  }  
  }  
   
  public   byte[]   Read(int   NumBytes)   {  
  byte[]   BufBytes;  
  byte[]   OutBytes;  
  BufBytes   =   new   byte[NumBytes];  
  if   (hComm!=INVALID_HANDLE_VALUE)   {  
  OVERLAPPED   ovlCommPort   =   new   OVERLAPPED();  
  int   BytesRead=0;  
  ReadFile(hComm,BufBytes,NumBytes,ref   BytesRead,ref   ovlCommPort);  
  OutBytes   =   new   byte[BytesRead];  
  Array.Copy(BufBytes,OutBytes,BytesRead);  
  }    
  else   {  
  throw(new   ApplicationException("串口未打开!"));  
  }  
  return   OutBytes;  
  }  
   
  public   void   Write(byte[]   WriteBytes)   {  
  if   (hComm!=INVALID_HANDLE_VALUE)   {  
  OVERLAPPED   ovlCommPort   =   new   OVERLAPPED();  
  int   BytesWritten   =   0;  
  WriteFile(hComm,WriteBytes,WriteBytes.Length,ref   BytesWritten,ref   ovlCommPort);  
  }  
  else   {  
  throw(new   ApplicationException("串口未打开!"));  
  }  
  }  
  }  
  }