小李程式™的专栏

有勇气来改变可以改变的事情,有度量接受不可改变的事情,有智慧来分辨两者的不同。
  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

利用Visual C#.NET面向Windows 串口通信编程(API)- -

Posted on 2005-11-17 13:23  尼斯湖李  阅读(3479)  评论(7)    收藏  举报

 

利用API函数封装成的通信类

(单独保存为一个“类”文件,后通过选择“添加现有项”,并到你的项目中)

using System;
using System.Runtime.InteropServices;

namespace BetaBrite {
 class CommPort {

  public int PortNum; //1,2,3,4
  public int BaudRate; //1200,2400,4800,9600
  public byte ByteSize; //7 bits
  public byte Parity; // 0-4=no,odd,even,mark,space
  public byte StopBits; // 0,1,2 = 1, 1.5, 2
  public int ReadTimeout; //10
  
  //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)]
  private struct DCB {
   //taken from c struct in platform sdk
    public int DCBlength;           // sizeof(DCB)
    public int BaudRate;            // current baud rate
    public int fBinary;          // binary mode, no EOF check
    public int fParity;          // enable parity checking
    public int fOutxCtsFlow;      // CTS output flow control
    public int fOutxDsrFlow;      // DSR output flow control
    public int fDtrControl;       // DTR flow control type
    public int fDsrSensitivity;   // DSR sensitivity
    public int fTXContinueOnXoff; // XOFF continues Tx
    public int fOutX;          // XON/XOFF out flow control
    public int fInX;           // XON/XOFF in flow control
    public int fErrorChar;     // enable error replacement
    public int fNull;          // enable null stripping
    public int fRtsControl;     // RTS flow control
    public int fAbortOnError;   // abort on error
    public int fDummy2;        // reserved
    public ushort wReserved;          // not currently used
    public ushort XonLim;             // transmit XON threshold
    public ushort XoffLim;            // transmit XOFF threshold
    public byte ByteSize;           // number of bits/byte, 4-8
    public byte Parity;             // 0-4=no,odd,even,mark,space
    public byte StopBits;           // 0,1,2 = 1, 1.5, 2
    public char XonChar;            // Tx and Rx XON character
    public char XoffChar;           // 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,                         // file name
    uint dwDesiredAccess,                      // access mode
    int dwShareMode,                          // share mode
    int lpSecurityAttributes, // SD
    int dwCreationDisposition,                // how to create
    int dwFlagsAndAttributes,                 // file attributes
    int hTemplateFile                        // handle to template file
  );
  [DllImport("kernel32.dll")]
  private static extern bool GetCommState(
    int hFile,  // handle to communications device
    ref DCB lpDCB    // device-control block
  ); 
  [DllImport("kernel32.dll")]
  private static extern bool BuildCommDCB(
    string lpDef,  // device-control string
    ref DCB lpDCB     // device-control block
  );
  [DllImport("kernel32.dll")]
  private static extern bool SetCommState(
    int hFile,  // handle to communications device
    ref DCB lpDCB    // device-control block
  );
  [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
  );
  
  public void Open() {
  
   DCB dcbCommPort = new DCB();
   COMMTIMEOUTS ctoCommPort = new COMMTIMEOUTS(); 
  
  
    // OPEN THE COMM PORT.

   
    hComm = CreateFile("COM" + 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("Comm Port Can Not Be Opened"));
    }
  
    // 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.
    // THERE ARE OTHER WAYS OF DOING SETTING THESE BUT THIS IS THE EASIEST.
    // IF YOU WANT TO LATER ADD CODE FOR OTHER BAUD RATES, REMEMBER
    // THAT THE ARGUMENT FOR BuildCommDCB MUST BE A POINTER TO A STRING.
    // ALSO NOTE THAT BuildCommDCB() DEFAULTS TO NO HANDSHAKING.
  
    dcbCommPort.DCBlength = Marshal.SizeOf(dcbCommPort);
    GetCommState(hComm, ref dcbCommPort);
    dcbCommPort.BaudRate=BaudRate;
    dcbCommPort.Parity=Parity;
    dcbCommPort.ByteSize=ByteSize;
    dcbCommPort.StopBits=StopBits;
    SetCommState(hComm, ref dcbCommPort);
   
    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("Comm Port Not Open"));
   }
   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("Comm Port Not Open"));
   }  
  }
 }

 class HexCon {
 //converter hex string to byte and byte to hex string
  public static string ByteToString(byte[] InBytes) {
   string StringOut="";
   foreach (byte InByte in InBytes) {
    StringOut=StringOut + String.Format("{0:X2} ",InByte);
   }
   return StringOut;
  }
  public static byte[] StringToByte(string InString) {
   string[] ByteStrings;
   ByteStrings = InString.Split(" ".ToCharArray());
   byte[] ByteOut;
   ByteOut = new byte[ByteStrings.Length-1];
   for (int i = 0;i==ByteStrings.Length-1;i++) {
    //ByteOut[i] = ("0x" + ByteStrings[i]).ToByte();
    ByteOut[i] = Byte.Parse(("0x" + ByteStrings[i]));
   }
   return ByteOut;
  }
 }
}

经实践可以实现RS-232C串口通信。