C#串口操作

前一阵,从国外网站看到一个用C#来操作串口的类。下载下来试了一下,觉得不错。共享一下。

/*
* Author: Marcus Lorentzon, 2001
*         d98malor@dtek.chalmers.se

* Freeware: Please do not remove this header

* File: SerialStream.cs

* Description: Implements a Stream for asynchronous
*              transfers and COMM. Stream version.
*
* Version: 2.4

*/

#region  Using

using  System;
using  System.IO;
using  System.Threading;
using  System.Runtime.InteropServices;
using  System.ComponentModel;

#endregion  Using

namespace  LoMaN.IO {

    
public   class  SerialStream : Stream {
        
        
#region  Attributes

        
private  IOCompletionCallback m_IOCompletionCallback;
        
private  IntPtr m_hFile  =  IntPtr.Zero;
        
private   string  m_sPort;
        
private   bool  m_bRead;
        
private   bool  m_bWrite;

        
#endregion  Attributes

        
#region  Properties

        
public   string  Port {
            
get  {
                
return  m_sPort;
            }
            
set  {
                
if  (m_sPort  !=  value) {
                    Close();
                    Open(value);
                }
            }
        }

        
public   override   bool  CanRead {
            
get  {
                
return  m_bRead;
            }
        }

        
public   override   bool  CanWrite {
            
get  {
                
return  m_bWrite;
            }
        }

        
public   override   bool  CanSeek {
            
get  {
                
return   false ;
            }
        }

        
public   bool  Closed  {
            
get  {
                
return  m_hFile.ToInt32()   0 ;
            }
        }

        
public   bool  Dsr {
            
get  {
                
uint  status;
                
if  ( ! GetCommModemStatus(m_hFile,  out  status)) {
                    
throw   new  Win32Exception();
                }
                
return  (status  &  MS_DSR_ON)  >   0 ;
            }
        }

        
public   bool  Ring {
            
get  {
                
uint  status;
                
if  ( ! GetCommModemStatus(m_hFile,  out  status)) {
                    
throw   new  Win32Exception();
                }
                
return  (status  &  MS_RING_ON)  >   0 ;
            }
        }

        
public   bool  Rlsd {
            
get  {
                
uint  status;
                
if  ( ! GetCommModemStatus(m_hFile,  out  status)) {
                    
throw   new  Win32Exception();
                }
                
return  (status  &  MS_RLSD_ON)  >   0 ;
            }
        }

        
#endregion  Properties

        
#region  Constructors

        
public  SerialStream() :  this (FileAccess.ReadWrite) {
        }

        
public  SerialStream(FileAccess access) {
            m_bRead  
=  (( int )access  &  ( int )FileAccess.Read)  !=   0 ;
            m_bWrite 
=  (( int )access  &  ( int )FileAccess.Write)  !=   0 ;
            
unsafe  {
                m_IOCompletionCallback 
=   new  IOCompletionCallback(AsyncFSCallback);
            }
        }

        
public  SerialStream( string  port) :  this (FileAccess.ReadWrite) {
            Open(port);
        }

        
public  SerialStream( string  port, FileAccess access) :  this (access) {
            Open(port);
        }

        
#endregion  Constructors

        
#region  Methods

        
public   void  Open( string  port) {
            
if  (m_hFile  !=  IntPtr.Zero) {
                
throw   new  IOException( " Stream already opened. " );
            }
            m_sPort 
=  port;
            m_hFile 
=  CreateFile(port, ( uint )((m_bRead ? GENERIC_READ: 0 ) | (m_bWrite ? GENERIC_WRITE: 0 )),  0 0 , OPEN_EXISTING, FILE_FLAG_OVERLAPPED,  0 );
            
if  (m_hFile.ToInt32()  ==  INVALID_HANDLE_VALUE) {
                m_hFile 
=  IntPtr.Zero;
                
throw   new  FileNotFoundException( " Unable to open  "   +  port);
            }

            ThreadPool.BindHandle(m_hFile);

            SetTimeouts(
0 0 0 0 0 );
        }

        
public   override   void  Close() {
            CloseHandle(m_hFile);
            m_hFile 
=  IntPtr.Zero;
            m_sPort 
=   null ;
        }

        
public  IAsyncResult BeginRead( byte [] buffer) {
            
return  BeginRead(buffer,  0 , buffer.Length,  null null );
        }

        
public   override  IAsyncResult BeginRead( byte [] buffer,  int  offset,  int  count, AsyncCallback callback,  object  state) {
            GCHandle gchBuffer 
=  GCHandle.Alloc(buffer, GCHandleType.Pinned);
            SerialAsyncResult sar 
=   new  SerialAsyncResult( this , state, callback,  true , gchBuffer);
            Overlapped ov 
=   new  Overlapped( 0 0 , sar.AsyncWaitHandle.Handle.ToInt32(), sar);
            
unsafe  {
                NativeOverlapped
*  nov  =  ov.Pack(m_IOCompletionCallback);
                
byte *  data  =  ( byte * )(( int )gchBuffer.AddrOfPinnedObject()  +  offset);

                
uint  read  =   0 ;
                
if  (ReadFile(m_hFile, data, ( uint )count,  out  read, nov)) {
                    sar.m_bCompletedSynchronously 
=   true ;
                    
return  sar;
                }
                
else   if  (GetLastError()  ==  ERROR_IO_PENDING) {
                    
return  sar;
                }
                
else
                    
throw   new  Exception( " Unable to initialize read. Errorcode:  "   +  GetLastError().ToString());
            }
        }

        
public  IAsyncResult BeginWrite( byte [] buffer) {
            
return  BeginWrite(buffer,  0 , buffer.Length,  null null );
        }

        
public   override  IAsyncResult BeginWrite( byte [] buffer,  int  offset,  int  count, AsyncCallback callback,  object  state) {
            GCHandle gchBuffer 
=  GCHandle.Alloc(buffer, GCHandleType.Pinned);
            SerialAsyncResult sar 
=   new  SerialAsyncResult( this , state, callback,  false , gchBuffer);
            Overlapped ov 
=   new  Overlapped( 0 0 , sar.AsyncWaitHandle.Handle.ToInt32(), sar);
            
unsafe  {
                NativeOverlapped
*  nov  =  ov.Pack(m_IOCompletionCallback);
                
byte *  data  =  ( byte * )(( int )gchBuffer.AddrOfPinnedObject()  +  offset);

                
uint  written  =   0 ;
                
if  (WriteFile(m_hFile, data, ( uint )count,  out  written, nov)) {
                    sar.m_bCompletedSynchronously 
=   true ;
                    
return  sar;
                }
                
else   if  (GetLastError()  ==  ERROR_IO_PENDING) {
                    
return  sar;
                }
                
else
                    
throw   new  Exception( " Unable to initialize write. Errorcode:  "   +  GetLastError().ToString());
            }
        }

        
private   int  EndOperation(IAsyncResult asyncResult,  bool  isRead) {
            SerialAsyncResult sar 
=  (SerialAsyncResult)asyncResult;
            
if  (sar.m_bIsRead  !=  isRead)
                
throw   new  IOException( " Invalid parameter: IAsyncResult is not from a  "   +  (isRead  ?   " read "  :  " write " ));
            
if  (sar.EndOperationCalled) {
                
throw   new  IOException( " End "   +  (isRead  ?   " Read "  :  " Write " +   "  called twice for the same operation. " );
            }
            
else  {
                sar.m_bEndOperationCalled 
=   true ;
            }

            
while  ( ! sar.m_bCompleted) {
                sar.AsyncWaitHandle.WaitOne();
            }

            sar.Dispose();

            
if  (sar.m_nErrorCode  !=  ERROR_SUCCESS  &&  sar.m_nErrorCode  !=  ERROR_OPERATION_ABORTED) {
                
throw   new  IOException( " Operation finished with errorcode:  "   +  sar.m_nErrorCode);
            }

            
return  sar.m_nReadWritten;
        }
        
        
public   override   int  EndRead(IAsyncResult asyncResult) {
            
return  EndOperation(asyncResult,  true );
        }
        
        
public   override   void  EndWrite(IAsyncResult asyncResult) {
            EndOperation(asyncResult, 
false );
        }

        
public   int  EndWriteEx(IAsyncResult asyncResult) {
            
return  EndOperation(asyncResult,  false );
        }

        
public   override   int  Read( byte [] buffer,  int  offset,  int  count) {
            
return  EndRead(BeginRead(buffer, offset, count,  null null ));
        }

        
public   override   void  Write( byte [] buffer,  int  offset,  int  count) {
            EndWrite(BeginWrite(buffer, offset, count, 
null null ));
        }

        
public   int  WriteEx( byte [] buffer,  int  offset,  int  count) {
            
return  EndWriteEx(BeginWrite(buffer, offset, count,  null null ));
        }

        
public   int  Read( byte [] buffer) {
            
return  EndRead(BeginRead(buffer,  0 , buffer.Length,  null null ));
        }

        
public   int  Write( byte [] buffer) {
            
return  EndOperation(BeginWrite(buffer,  0 , buffer.Length,  null null ),  false );
        }

        
public   override   void  Flush() {
            FlushFileBuffers(m_hFile);
        }

        
public   bool  PurgeRead() {
            
return  PurgeComm(m_hFile, PURGE_RXCLEAR);
        }

        
public   bool  PurgeWrite() {
            
return  PurgeComm(m_hFile, PURGE_TXCLEAR);
        }

        
public   bool  Purge() {
            
return  PurgeRead()  &&  PurgeWrite();
        }

        
public   bool  CancelRead() {
            
return  PurgeComm(m_hFile, PURGE_RXABORT);
        }

        
public   bool  CancelWrite() {
            
return  PurgeComm(m_hFile, PURGE_TXABORT);
        }

        
public   bool  CancelAll() {
            
return  CancelRead()  &&  CancelWrite();
        }

        
public   override   void  SetLength( long  nLength) {
            
throw   new  NotSupportedException( " SetLength isn't supported on serial ports. " );
        }

        
public   override   long  Seek( long  offset, SeekOrigin origin) {
            
throw   new  NotSupportedException( " Seek isn't supported on serial ports. " );
        }

        
public   void  SetTimeouts( int  ReadIntervalTimeout,
                                
int  ReadTotalTimeoutMultiplier,
                                
int  ReadTotalTimeoutConstant, 
                                
int  WriteTotalTimeoutMultiplier,
                                
int  WriteTotalTimeoutConstant) {
            SerialTimeouts Timeouts 
=   new  SerialTimeouts(ReadIntervalTimeout,
                                                         ReadTotalTimeoutMultiplier,
                                                         ReadTotalTimeoutConstant, 
                                                         WriteTotalTimeoutMultiplier,
                                                         WriteTotalTimeoutConstant);
            
unsafe  { SetCommTimeouts(m_hFile,  ref  Timeouts); }
        }

        
public   bool  SetPortSettings( uint  baudrate) {
            
return  SetPortSettings(baudrate, FlowControl.Hardware);
        }

        
public   bool  SetPortSettings( uint  baudrate, FlowControl flowControl) {
            
return  SetPortSettings(baudrate, flowControl, Parity.None);
        }

        
public   bool  SetPortSettings( uint  baudrate, FlowControl flowControl, Parity parity) {
            
return  SetPortSettings(baudrate, flowControl, parity,  8 , StopBits.One);
        }

        
public   bool  SetPortSettings( uint  baudrate, FlowControl flowControl, Parity parity,  byte  databits, StopBits stopbits) {
            
unsafe  {
                DCB dcb 
=   new  DCB();
                dcb.DCBlength 
=   sizeof (DCB);
                dcb.BaudRate 
=  baudrate;
                dcb.ByteSize 
=  databits;
                dcb.StopBits 
=  ( byte )stopbits;
                dcb.Parity 
=  ( byte )parity;
                dcb.fParity 
=  (parity  >   0 ) ?   1U  :  0U ;
                dcb.fBinary 
=  dcb.fDtrControl  =  dcb.fTXContinueOnXoff  =   1 ;
                dcb.fOutxCtsFlow 
=  dcb.fAbortOnError  =  (flowControl  ==  FlowControl.Hardware) ?   1U  :  0U ;
                dcb.fOutX 
=  dcb.fInX  =  (flowControl  ==  FlowControl.XOnXOff) ?   1U  :  0U ;
                dcb.fRtsControl 
=  (flowControl  ==  FlowControl.Hardware) ?   2U  :  1U ;
                dcb.XonLim 
=   2048 ;
                dcb.XoffLim 
=   512 ;
                dcb.XonChar 
=   0x11 //  Ctrl-Q
                dcb.XoffChar  =   0x13 //  Ctrl-S
                 return  SetCommState(m_hFile,  ref  dcb);
            }
        }

        
public   bool  SetPortSettings(DCB dcb) {
            
return  SetCommState(m_hFile,  ref  dcb);
        }

        
public   bool  GetPortSettings( out  DCB dcb) {
            
unsafe  {
                DCB dcb2 
=   new  DCB();
                dcb2.DCBlength 
=   sizeof (DCB);
                
bool  ret  =  GetCommState(m_hFile,  ref  dcb2);
                dcb 
=  dcb2;
                
return  ret;
            }
        }

        
public   bool  SetXOn() {
            
return  EscapeCommFunction(m_hFile, SETXON);
        }

        
public   bool  SetXOff() {
            
return  EscapeCommFunction(m_hFile, SETXOFF);
        }

        
private   unsafe   void  AsyncFSCallback( uint  errorCode,  uint  numBytes, NativeOverlapped *  pOverlapped) {
            SerialAsyncResult sar 
=  (SerialAsyncResult)Overlapped.Unpack(pOverlapped).AsyncResult;

            sar.m_nErrorCode 
=  errorCode;
            sar.m_nReadWritten 
=  ( int )numBytes;
            sar.m_bCompleted 
=   true ;

            
if  (sar.Callback  !=   null )
                sar.Callback.Invoke(sar);

            Overlapped.Free(pOverlapped);
        }

        
#endregion  Methods

        
#region  Constants

        
private   const   uint  PURGE_TXABORT  =   0x0001 ;   //  Kill the pending/current writes to the comm port.
         private   const   uint  PURGE_RXABORT  =   0x0002 ;   //  Kill the pending/current reads to the comm port.
         private   const   uint  PURGE_TXCLEAR  =   0x0004 ;   //  Kill the transmit queue if there.
         private   const   uint  PURGE_RXCLEAR  =   0x0008 ;   //  Kill the typeahead buffer if there.

        
private   const   uint  SETXOFF   =   1 ;     //  Simulate XOFF received
         private   const   uint  SETXON    =   2 ;     //  Simulate XON received
         private   const   uint  SETRTS     =   3 ;     //  Set RTS high
         private   const   uint  CLRRTS     =   4 ;     //  Set RTS low
         private   const   uint  SETDTR     =   5 ;     //  Set DTR high
         private   const   uint  CLRDTR     =   6 ;     //  Set DTR low
         private   const   uint  SETBREAK     =   8 ;     //  Set the device break line.
         private   const   uint  CLRBREAK     =   9 ;     //  Clear the device break line.

        
private   const   uint  MS_CTS_ON   =   0x0010 ;
        
private   const   uint  MS_DSR_ON   =   0x0020 ;
        
private   const   uint  MS_RING_ON  =   0x0040 ;
        
private   const   uint  MS_RLSD_ON  =   0x0080 ;

        
private   const   uint  FILE_FLAG_OVERLAPPED  =   0x40000000 ;

        
private   const   uint  OPEN_EXISTING  =   3 ;

        
private   const   int   INVALID_HANDLE_VALUE  =   - 1 ;

        
private   const   uint  GENERIC_READ  =   0x80000000 ;
        
private   const   uint  GENERIC_WRITE  =   0x40000000 ;

        
private   const   uint  ERROR_SUCCESS  =   0 ;
        
private   const   uint  ERROR_OPERATION_ABORTED  =   995 ;
        
private   const   uint  ERROR_IO_PENDING  =   997 ;

        
#endregion  Constants

        
#region  Enums

        
public   enum  Parity {None, Odd, Even, Mark, Space};
        
public   enum  StopBits {One, OneAndHalf, Two};
        
public   enum  FlowControl {None, XOnXOff, Hardware};

        
#endregion  Enums

        
#region  Classes

        [StructLayout(LayoutKind.Sequential)]
        
public   struct  DCB {

            
#region  Attributes

            
public   int  DCBlength;
            
public   uint  BaudRate;
            
public   uint  Flags;
            
public   ushort  wReserved;
            
public   ushort  XonLim;
            
public   ushort  XoffLim;
            
public   byte  ByteSize;
            
public   byte  Parity;
            
public   byte  StopBits;
            
public   sbyte  XonChar;
            
public   sbyte  XoffChar;
            
public   sbyte  ErrorChar;
            
public   sbyte  EofChar;
            
public   sbyte  EvtChar;
            
public   ushort  wReserved1;

            
#endregion  Attributes

            
#region  Properties

            
public   uint  fBinary {  get  {  return  Flags & 0x0001 ; } 
                                  
set  { Flags  =  Flags  &   ~ 1U   |  value; } }
            
public   uint  fParity {  get  {  return  (Flags >> 1 ) & 1 ; }
                                  
set  { Flags  =  Flags  &   ~ ( 1U   > 2 ) & 1 ; }
                                  
set  { Flags  =  Flags  &   ~ ( 1U   > 3 ) & 1 ; }
                                  
set  { Flags  =  Flags  &   ~ ( 1U   > 4 ) & 3 ; }
                                  
set  { Flags  =  Flags  &   ~ ( 3U   > 6 ) & 1 ; }
                                  
set  { Flags  =  Flags  &   ~ ( 1U   > 7 ) & 1 ; }
                                  
set  { Flags  =  Flags  &   ~ ( 1U   > 8 ) & 1 ; }
                                  
set  { Flags  =  Flags  &   ~ ( 1U   > 9 ) & 1 ; }
                                  
set  { Flags  =  Flags  &   ~ ( 1U   > 10 ) & 1 ; }
                                  
set  { Flags  =  Flags  &   ~ ( 1U   > 11 ) & 1 ; }
                                  
set  { Flags  =  Flags  &   ~ ( 1U   > 12 ) & 3 ; }
                                  
set  { Flags  =  Flags  &   ~ ( 3U   > 14 ) & 1 ; }
                                  
set  { Flags  =  Flags  &   ~ ( 1U   <<   14 |  (value  <<   14 ); } }

            
#endregion  Properties

            
#region  Methods

            
public   override   string  ToString() {
                
return   " DCBlength:  "   +  DCBlength  +   " \r\n "   +
                    
" BaudRate:  "   +  BaudRate  +   " \r\n "   +
                    
" fBinary:  "   +  fBinary  +   " \r\n "   +
                    
" fParity:  "   +  fParity  +   " \r\n "   +
                    
" fOutxCtsFlow:  "   +  fOutxCtsFlow  +   " \r\n "   +
                    
" fOutxDsrFlow:  "   +  fOutxDsrFlow  +   " \r\n "   +
                    
" fDtrControl:  "   +  fDtrControl  +   " \r\n "   +
                    
" fDsrSensitivity:  "   +  fDsrSensitivity  +   " \r\n "   +
                    
" fTXContinueOnXoff:  "   +  fTXContinueOnXoff  +   " \r\n "   +
                    
" fOutX:  "   +  fOutX  +   " \r\n "   +
                    
" fInX:  "   +  fInX  +   " \r\n "   +
                    
" fErrorChar:  "   +  fErrorChar  +   " \r\n "   +
                    
" fNull:  "   +  fNull  +   " \r\n "   +
                    
" fRtsControl:  "   +  fRtsControl  +   " \r\n "   +
                    
" fAbortOnError:  "   +  fAbortOnError  +   " \r\n "   +
                    
" XonLim:  "   +  XonLim  +   " \r\n "   +
                    
" XoffLim:  "   +  XoffLim  +   " \r\n "   +
                    
" ByteSize:  "   +  ByteSize  +   " \r\n "   +
                    
" Parity:  "   +  Parity  +   " \r\n "   +
                    
" StopBits:  "   +  StopBits  +   " \r\n "   +
                    
" XonChar:  "   +  XonChar  +   " \r\n "   +
                    
" XoffChar:  "   +  XoffChar  +   " \r\n "   +
                    
" EofChar:  "   +  EofChar  +   " \r\n "   +
                    
" EvtChar:  "   +  EvtChar  +   " \r\n " ;
            }

            
#endregion  Methods
        }

        
private   class  SerialAsyncResult : IAsyncResult, IDisposable {

            
#region  Attributes

            
internal   bool  m_bEndOperationCalled  =   false ;
            
internal   bool  m_bIsRead;
            
internal   int  m_nReadWritten  =   0 ;
            
internal   bool  m_bCompleted  =   false ;
            
internal   bool  m_bCompletedSynchronously  =   false ;
            
internal   uint  m_nErrorCode  =  ERROR_SUCCESS;

            
private   object  m_AsyncObject;
            
private   object  m_StateObject;
            
private  ManualResetEvent m_WaitHandle  =   new  ManualResetEvent( false );
            
private  AsyncCallback m_Callback;
            
private  GCHandle m_gchBuffer;

            
#endregion  Attributes

            
#region  Properties

            
internal   bool  EndOperationCalled {  get  {  return  m_bEndOperationCalled; } }

            
public   bool  IsCompleted {  get  {  return  m_bCompleted; } }

            
public   bool  CompletedSynchronously {  get  {  return  m_bCompletedSynchronously; } }

            
public   object  AsyncObject {  get  {  return  m_AsyncObject; } }

            
public   object  AsyncState {  get  {  return  m_StateObject; } }

            
public  WaitHandle AsyncWaitHandle {  get  {  return  m_WaitHandle; } }
            
internal  ManualResetEvent WaitHandle {  get  {  return  m_WaitHandle; } }

            
public  AsyncCallback Callback {  get  {  return  m_Callback; } }

            
#endregion  Properties

            
#region  Constructors

            
public  SerialAsyncResult( object  asyncObject,
                
object  stateObject, 
                AsyncCallback callback, 
                
bool  bIsRead, 
                GCHandle gchBuffer) {

                m_AsyncObject 
=  asyncObject;
                m_StateObject 
=  stateObject;
                m_Callback 
=  callback;
                m_bIsRead 
=  bIsRead;
                m_gchBuffer 
=  gchBuffer;
            }

            
#endregion  Constructors

            
#region  Methods

            
public   void  Dispose() {
                m_WaitHandle.Close();
                m_gchBuffer.Free();
            }

            
#endregion  Methods
        }

        
#endregion  Classes

        
#region  Imports

        [DllImport(
" kernel32.dll " , EntryPoint = " CreateFileW " ,  SetLastError = true ,
            CharSet
= CharSet.Unicode, ExactSpelling = true )]
        
static   extern  IntPtr CreateFile( string  filename,  uint  access,  uint  sharemode,  uint  security_attributes,  uint  creation,  uint  flags,  uint  template);

        [DllImport(
" kernel32.dll " , SetLastError = true )]
        
static   extern   bool  CloseHandle(IntPtr handle);

        [DllImport(
" kernel32.dll " , SetLastError = true )]
        
static   extern   unsafe   bool  ReadFile(IntPtr hFile,  byte *  lpBuffer,  uint  nNumberOfBytesToRead,  out   uint  lpNumberOfBytesRead, NativeOverlapped *  lpOverlapped);

        [DllImport(
" kernel32.dll " , SetLastError = true )]
        
static   extern   unsafe   bool  WriteFile(IntPtr hFile,  byte *  lpBuffer,  uint  nNumberOfBytesToWrite,  out   uint  lpNumberOfBytesWritten, NativeOverlapped *  lpOverlapped);

        [DllImport(
" kernel32.dll " , SetLastError = true )]
        
static   extern   bool  SetCommTimeouts(IntPtr hFile,  ref  SerialTimeouts lpCommTimeouts);

        [DllImport(
" kernel32.dll " , SetLastError = true )]
        
static   extern   bool  SetCommState(IntPtr hFile,  ref  DCB lpDCB);

        [DllImport(
" kernel32.dll " , SetLastError = true )]
        
static   extern   bool  GetCommState(IntPtr hFile,  ref  DCB lpDCB);

        [DllImport(
" kernel32.dll " , SetLastError = true )]
        
static   extern   bool  BuildCommDCB( string  def,  ref  DCB lpDCB);

        [DllImport(
" kernel32.dll " , SetLastError = true )]
        
static   extern   int  GetLastError();

        [DllImport(
" kernel32.dll " , SetLastError = true )]
        
static   extern   bool  FlushFileBuffers(IntPtr hFile);

        [DllImport(
" kernel32.dll " , SetLastError = true )]
        
static   extern   bool  PurgeComm(IntPtr hFile,  uint  dwFlags);

        [DllImport(
" kernel32.dll " , SetLastError = true )]
        
static   extern   bool  EscapeCommFunction(IntPtr hFile,  uint  dwFunc);

        [DllImport(
" kernel32.dll " , SetLastError = true )]
        
static   extern   bool  GetCommModemStatus(IntPtr hFile,  out   uint  modemStat);

        
#endregion  Imports
    }

    [StructLayout(LayoutKind.Sequential)]
    
public   struct  SerialTimeouts {

        
#region  Attributes

        
public   int  ReadIntervalTimeout;
        
public   int  ReadTotalTimeoutMultiplier;
        
public   int  ReadTotalTimeoutConstant;
        
public   int  WriteTotalTimeoutMultiplier;
        
public   int  WriteTotalTimeoutConstant;

        
#endregion  Attributes

        
#region  Constructors

        
public  SerialTimeouts( int  r1,  int  r2,  int  r3,  int  w1,  int  w2) {
            ReadIntervalTimeout 
=  r1;
            ReadTotalTimeoutMultiplier 
=  r2;
            ReadTotalTimeoutConstant 
=  r3;
            WriteTotalTimeoutMultiplier 
=  w1;
            WriteTotalTimeoutConstant 
=  w2;
        }

        
#endregion  Constructors

        
#region  Methods

        
public   override   string  ToString() {
            
return   " ReadIntervalTimeout:  "   +  ReadIntervalTimeout  +   " \r\n "   +
                   
" ReadTotalTimeoutMultiplier:  "   +  ReadTotalTimeoutMultiplier  +   " \r\n "   +
                   
" ReadTotalTimeoutConstant:  "   +  ReadTotalTimeoutConstant  +   " \r\n "   +
                   
" WriteTotalTimeoutMultiplier:  "   +  WriteTotalTimeoutMultiplier  +   " \r\n "   +
                   
" WriteTotalTimeoutConstant:  "   +  WriteTotalTimeoutConstant  +   " \r\n " ;
        }

        
#endregion  Methods
    }
}



using  System;
using  System.IO;
using  System.Threading;

using  LoMaN.IO;

namespace  SerialStreamReader {

    
class  App {

        
//  The main serial stream
         static  SerialStream ss;

        [STAThread]
        
static   void  Main( string [] args) {

            
//  Create a serial port
            ss  =   new  SerialStream();
            
try  {
                ss.Open(
" COM4 " );  // 我对猫进行了调用
            }
            
catch  (Exception e) {
                Console.WriteLine(
" Error:  "   +  e.Message);
                
return ;
            }

            
//  Set port settings
            ss.SetPortSettings( 9600 );

            
//  Set timeout so read ends after 20ms of silence after a response
            ss.SetTimeouts( 20 0 0 0 0 );

            
//  Create the StreamWriter used to send commands
            StreamWriter sw  =   new  StreamWriter(ss, System.Text.Encoding.ASCII);

            
//  Create the Thread used to read responses
            Thread responseReaderThread  =   new  Thread( new  ThreadStart(ReadResponseThread));
            responseReaderThread.Start();

            
//  Read all returned lines
             for  (;;) {
                
//  Read command from console
                 string  command  =  Console.ReadLine();

                
//  Check for exit command
                 if  (command.Trim().ToLower()  ==   " exit " ) {
                    responseReaderThread.Abort();
                    
break ;
                }

                
//  Write command to modem
                sw.WriteLine(command);
                sw.Flush();
            }
        }

        
//  Main loop for reading responses
         static   void  ReadResponseThread() {
            StreamReader sr 
=   new  StreamReader(ss, System.Text.Encoding.ASCII);
            
try  {
                
for  (;;) {
                    
//  Read response from modem
                     string  response  =  sr.ReadLine();
                    Console.WriteLine(
" Response:  "   +  response);
                }
            }
            
catch  (ThreadAbortException) {
            }
        }
    }
}

 

程序运行后,你可以对设备进行指令操作。(具体设备接受的指令)
 

转载于:https://www.cnblogs.com/jxnclyk/archive/2010/06/07/1753246.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值