📄 serialportstream.cs
字号:
/// </summary>
/// <param name="fileName">Name of file to Create</param>
/// <param name="desiredAccessFlags">How to access the file</param>
/// <param name="shareModeFlats">What is the sharing mode?</param>
/// <param name="securityAttributes">Security Descriptor</param>
/// <param name="creationDisposition"></param>
/// <param name="flagsAndAttributes">Creation Flags</param>
/// <param name="handleToTemplateFile">File handle to a file template.</param>
/// <returns>Handle to the file, -1 if the file could not be created.</returns>
[DllImport ("coredll.dll")]
private static extern int CreateFile(
string fileName,
int desiredAccessFlags,
int shareModeFlats,
int securityAttributes,
int creationDisposition,
int flagsAndAttributes,
int handleToTemplateFile);
/// <summary>
/// This function writes data to a file. WriteFile starts writing data to
/// the file at the position indicated by the file pointer. After the write
/// operation has been completed, the file pointer is adjusted by the number
/// of bytes actually written.
/// </summary>
/// <param name="handle">The handle to the file.</param>
/// <param name="buffer">The buffer to write.</param>
/// <param name="numberOfBytesToWrite">Number of bytes to write.</param>
/// <param name="numberOfBytesWritten">Number of bytes actually written.</param>
/// <param name="overlapped">An Overlapped structure (not important.)</param>
/// <returns>HRESULT on whether this worked.</returns>
[DllImport ("coredll.dll")]
private static extern int WriteFile(
int handle,
byte[] buffer,
int numberOfBytesToWrite,
ref int numberOfBytesWritten,
ref OVERLAPPED overlapped);
/// <summary>
/// This function reads data from a file, starting at the position indicated
/// by the file pointer. After the read operation has been completed, the
/// file pointer is adjusted by the number of bytes actually read.
/// </summary>
/// <param name="handle">The handle to the file.</param>
/// <param name="buffer">The buffer to read to.</param>
/// <param name="numberOfBytesToRead">Number of bytes to read.</param>
/// <param name="numberOfBytesRead">Number of bytes actually read.</param>
/// <param name="makeThisValueZero">Simple, just keep this value at 0.</param>
/// <returns>HRESULT on whether this worked.</returns>
[DllImport ("coredll.dll")]
private static extern int ReadFile(
int handle,
byte[] buffer,
int numberOfBytesToRead,
ref int numberOfBytesRead,
int makeThisValueZero);
#endregion
public SerialPortStream(int port, PARITY parity, DATABITS dataBits, STOPBITS stopBits, BAUDRATE baudRate)
{
if(port <= 0)
{
throw new ArgumentException("The port number must be > 0");
}
this.port = port;
this.parity = parity;
this.dataBits = dataBits;
this.stopBits = stopBits;
this.baudRate = baudRate;
}
/// <summary>
/// Uses the CoreDLL.dll methods to open the COM port.
/// </summary>
public void Open()
{
int HRESULT; //error codes and such are called HRESULTS in Windows parlance.
COMM_TIMEOUTS serialPortTimeout;
DCB dcb;
if(this.IsOpen)
{
throw new Exception(String.Format("Error: COM Port {0} is already open!",this.port));
}
this.handle = CreateFile("COM" + port.ToString() + ":", GENERIC_READ | GENERIC_WRITE, 0, 0, OPEN_EXISTING, 0, 0);
if(!this.IsOpen)
{
throw new Exception(String.Format("Error when opening COM {0}",port));
}
HRESULT = PurgeComm(this.handle, PURGEFLAGS.RECIEVE_CLEAR | PURGEFLAGS.TRANSMIT_CLEAR);
HRESULT = GetCommState(this.handle, out dcb);
//----- set required comm port configuration
dcb.Binary = 1; // binary mode, so no EOF check
dcb.ParityEnabled = 0; // enable parity checking
dcb.OutxCtsFlow = 0; // No CTS output flow control
dcb.OutxDsrFlow = 0; // No DSR output flow control
dcb.DtrControl = 0; // DTR_CONTROL_ENABLE = 1 // DTR flow control type
dcb.DsrSensitivity = 0; // DSR sensitivity
dcb.TXContinueOnXoff = 1; // XOFF continues Tx
dcb.OutX = 0; // No XON/XOFF out flow control
dcb.InX = 0; // No XON/XOFF in flow control
dcb.ErrorCharEnabled = 0; // Disable error replacement
dcb.Null = 0; // Disable null stripping
dcb.RtsControl = 0; // RTS_CONTROL_ENABLE = 1 // RTS flow control
dcb.AbortOnError = 0; // Do not abort reads/writes on error
dcb.StopBits = (byte)this.stopBits; // 0, 1, 2 = 1, 1.5, 2
dcb.ByteSize = (byte)this.dataBits; // Number of bits/byte, 4-8
dcb.ParityScheme = (byte)this.parity; // 0-4 = no, odd, even, mark, space
dcb.BaudRate = (int)this.baudRate; // baud rate (port speed)
dcb.XonChar = '1';
// XonChar may not equal XoffChar to prevent SetCommState from failing.
// I picked a random character. Perhaps this should be something else.
HRESULT = SetCommState(this.handle, ref dcb);
//----- set comm port buffer size in number of bytes
HRESULT = SetupComm(this.handle,this.RecieveBufferSize,this.TransmitBufferSize);
//----- set comm port timeouts mintTimeout miliseconds
serialPortTimeout.ReadIntervalTimeout = 0;
serialPortTimeout.ReadTotalTimeoutMultiplier = 0;
serialPortTimeout.ReadTotalTimeoutconstant = this.CommunicationTimeout;
serialPortTimeout.WriteTotalTimeoutMultiplier = 10;
serialPortTimeout.WriteTotalTimeoutconstant = 100;
HRESULT = SetCommTimeouts(this.handle, ref serialPortTimeout);
}
public void Close()
{
int HRESULT;
if (handle != INVALID_HANDLE_VALUE)
{
HRESULT = CloseHandle(handle);
if (HRESULT < 0)
{
throw new Exception("Unable to close serial port.");
}
this.handle = INVALID_HANDLE_VALUE;
}
}
// TODO: Add HRESULT error checking
public int WriteString(string message)
{
ASCIIEncoding asciiEncoder = new ASCIIEncoding();
byte[] messageToBytes = asciiEncoder.GetBytes(message);
return this.Write(messageToBytes,0,messageToBytes.Length);
}
public int Write(byte[] bytes, int offset, int count)
{
int HRESULT;
int numberOfBytesWritten = 0;
byte[] transmitBuffer;
OVERLAPPED overlapped = new OVERLAPPED();
if(offset != 0)
{
transmitBuffer = new byte[count];
Array.Copy(bytes,offset,transmitBuffer,0,count);
}
else
{
transmitBuffer = bytes;
}
if(this.IsOpen)
{
HRESULT = WriteFile(this.handle,transmitBuffer,count,ref numberOfBytesWritten,ref overlapped);
}
else
{
throw new Exception("Serial Port is not open.");
}
return numberOfBytesWritten;
}
// TODO: Didn't check for silly mistakes due to a bad serial cable.
public int Read(byte[] bytes, int offset, int count)
{
int HRESULT;
int numberOfBytesRead = 0;
byte[] recieveBuffer = new byte[count];
if(this.IsOpen)
{
HRESULT = ReadFile(this.handle,recieveBuffer,recieveBuffer.Length,ref numberOfBytesRead,0);
}
else
{
throw new Exception("Serial Port is not open.");
}
Array.Copy(recieveBuffer,0,bytes,offset,numberOfBytesRead);
return numberOfBytesRead;
}
public bool IsOpen
{
get
{
return (this.handle != INVALID_HANDLE_VALUE);
}
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -