using System;
using System.Runtime.InteropServices;
using System.Collections.Generic;
using System.Text;
namespace NewPortTest
{
public class CommPort
{
public string Port = "COM1";
public int BaudRate = 115200;
public byte ByteSize = 8;
public byte Parity = 0;
public byte StopBits = 0;
public int ReadTimeout = 200;
public bool Opened = false;
private int hComm = -1;
#region "API相关定义"
private const string DLLPATH = "//windows//coredll.dll";
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;
private const int PURGE_RXABORT = 0x2;
private const int PURGE_RXCLEAR = 0x8;
private const int PURGE_TXABORT = 0x1;
private const int PURGE_TXCLEAR = 0x4;
[StructLayout(LayoutKind.Sequential)]
public struct DCB
{
public int DCBlength;
public int BaudRate;
public uint flags;
public ushort wReserved;
public ushort XonLim;
public ushort XoffLim;
public byte ByteSize;
public byte Parity;
public byte StopBits;
public byte XonChar;
public byte XoffChar;
public byte ErrorChar;
public byte EofChar;
public byte EvtChar;
public ushort wReserved1;
}
[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(DLLPATH)]
private static extern int CreateFile(string lpFileName, uint dwDesiredAccess, int dwShareMode,
int lpSecurityAttributes, int dwCreationDisposition, int dwFlagsAndAttributes, int hTemplateFile);
[DllImport(DLLPATH)]
private static extern bool GetCommState(int hFile, ref DCB lpDCB);
[DllImport(DLLPATH)]
private static extern bool SetCommState(int hFile, ref DCB lpDCB);
[DllImport(DLLPATH)]
private static extern bool GetCommTimeouts(int hFile, ref COMMTIMEOUTS lpCommTimeouts);
[DllImport(DLLPATH)]
private static extern bool SetCommTimeouts(int hFile, ref COMMTIMEOUTS lpCommTimeouts);
[DllImport(DLLPATH)]
private static extern bool ReadFile(int hFile, byte[] lpBuffer, int nNumberOfBytesToRead,
ref int lpNumberOfBytesRead, ref OVERLAPPED lpOverlapped);
[DllImport(DLLPATH)]
private static extern bool WriteFile(int hFile, byte[] lpBuffer, int nNumberOfBytesToWrite,
ref int lpNumberOfBytesWritten, ref OVERLAPPED lpOverlapped);
[DllImport(DLLPATH, SetLastError = true)]
private static extern bool FlushFileBuffers(int hFile);
[DllImport(DLLPATH, SetLastError = true)]
private static extern bool PurgeComm(int hFile, uint dwFlags);
[DllImport(DLLPATH)]
private static extern bool CloseHandle(int hObject);
[DllImport(DLLPATH)]
private static extern uint GetLastError();
#endregion
internal void SetDcbFlag(int whichFlag, int setting, DCB dcb)
{
uint num;
setting = setting << whichFlag;
if ((whichFlag == 4) || (whichFlag == 12))
{
num = 3;
}
else if (whichFlag == 15)
{
num = 0x1ffff;
}
else
{
num = 1;
}
dcb.flags &= ~(num << whichFlag);
dcb.flags |= (uint)setting;
}
public int Open()
{
DCB dcb = new DCB();
COMMTIMEOUTS ctoCommPort = new COMMTIMEOUTS();
hComm = CreateFile(Port, GENERIC_READ | GENERIC_WRITE, 0, 0, OPEN_EXISTING, 0, 0);
if (hComm == INVALID_HANDLE_VALUE)
{
return -1;
}
GetCommTimeouts(hComm, ref ctoCommPort);
ctoCommPort.ReadTotalTimeoutConstant = ReadTimeout;
ctoCommPort.ReadTotalTimeoutMultiplier = 0;
ctoCommPort.WriteTotalTimeoutMultiplier = 0;
ctoCommPort.WriteTotalTimeoutConstant = 0;
SetCommTimeouts(hComm, ref ctoCommPort);
GetCommState(hComm, ref dcb);
dcb.DCBlength = Marshal.SizeOf(dcb);
dcb.BaudRate = BaudRate;
dcb.flags = 0;
dcb.ByteSize = (byte)ByteSize;
dcb.StopBits = StopBits;
dcb.Parity = (byte)Parity;
SetDcbFlag(0, 1, dcb);
SetDcbFlag(1, (Parity == 0) ? 0 : 1, dcb);
SetDcbFlag(2, 0, dcb);
SetDcbFlag(3, 0, dcb);
SetDcbFlag(4, 0, dcb);
SetDcbFlag(6, 0, dcb);
SetDcbFlag(9, 1, dcb);
SetDcbFlag(8, 0, dcb);
SetDcbFlag(10, 0, dcb);
SetDcbFlag(11, 0, dcb);
SetDcbFlag(12, 0, dcb);
SetDcbFlag(14, 0, dcb);
dcb.wReserved = 0;
dcb.XonLim = 0;
dcb.XoffLim = 0;
dcb.XonChar = 0;
dcb.XoffChar = 0;
dcb.ErrorChar = 0;
dcb.EofChar = 0;
dcb.EvtChar = 0;
dcb.wReserved1 = 0;
if (!SetCommState(hComm, ref dcb))
{
return -2;
}
Opened = true;
return 0;
}
public void Close()
{
if (hComm != INVALID_HANDLE_VALUE)
{
CloseHandle(hComm);
}
}
public int Read(ref byte[] bytData, int NumBytes)
{
if (hComm != INVALID_HANDLE_VALUE)
{
OVERLAPPED ovlCommPort = new OVERLAPPED();
int BytesRead = 0;
ReadFile(hComm, bytData, NumBytes, ref BytesRead, ref ovlCommPort);
return BytesRead;
}
else
{
return -1;
}
}
public byte[] Readport(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 int Write(byte[] WriteBytes, int intSize)
{
if (hComm != INVALID_HANDLE_VALUE)
{
OVERLAPPED ovlCommPort = new OVERLAPPED();
int BytesWritten = 0;
WriteFile(hComm, WriteBytes, intSize, ref BytesWritten, ref ovlCommPort);
return BytesWritten;
}
else
{
return -1;
}
}
public void ClearReceiveBuf()
{
if (hComm != INVALID_HANDLE_VALUE)
{
PurgeComm(hComm, PURGE_RXABORT | PURGE_RXCLEAR);
}
}
public void ClearSendBuf()
{
if (hComm != INVALID_HANDLE_VALUE)
{
PurgeComm(hComm, PURGE_TXABORT | PURGE_TXCLEAR);
}
}
}
}