📄 serialport.cs
字号:
/// </summary>
/// <return>A value of the enumeration <see cref="Handshake"/>.</return>
#if DESIGN
[DefaultValue(0x0)]
#endif
public Handshake Handshake
{
get {
return this.mHandshake;
}
set {
if ((value < Handshake.None) || (value > Handshake.RequestToSendXOnXOff)) {
throw new ArgumentOutOfRangeException("Handshake. Use the enum");
}
this.mHandshake = value;
if (this.IsOpen) {
this.UpdateSettings();
}
}
}
/// <summary>
/// Gets the open or closed status of the <see cref="SerialPort"/> object.
/// </summary>
/// <return>true if the serial port is open, otherwise false.</return>
#if DESIGN
[Browsable(false)]
#endif
public bool IsOpen
{
get {
return this.mIsOpen;
}
}
/// <summary>
/// Gets or sets the parity-checking protocol.
/// </summary>
/// <return>A <see cref="Parity"/> object that represents the parity-checking protocol.</return>
#if DESIGN
[DefaultValue(0x0)]
#endif
public Parity Parity {
get
{
return this.mParity;
}
set {
if ((value < Parity.None) || (value > Parity.Space)) {
throw new ArgumentOutOfRangeException("Parity. Use the enum");
}
this.mParity = value;
if (this.IsOpen) {
this.UpdateSettings();
}
}
}
/// <summary>
/// Gets or sets the byte that is used to replace invalid characters in a data stream when a parity error occurs.
/// </summary>
/// <return>A byte used to replace invalid characters.</return>
#if DESIGN
[DefaultValue(63)]
#endif
public byte ParityReplace {
get
{
return this.mErrorChar;
}
set {
this.mErrorChar = value;
if (this.IsOpen) {
this.UpdateSettings();
}
}
}
/// <summary>
/// Gets or sets the port for communications, including but not limited to all available COM ports.
/// </summary>
/// <value>A string object representing the communications port e.g. "COM1", "COM10" etc.</value>
#if DESIGN
[DefaultValue("COM1")]
#endif
public string PortName {
get
{
//trim the last colon if present
return this.mPortName.Trim(new char[]{'\\','.',':'});
//return this.mPortName.TrimEnd(new char[]{':'});
}
set {
if(! CommAPI.FullFramework) {
if(! value.EndsWith(":")) {
//append the colon
this.mPortName = "\\\\.\\" + value + ":";
return;
//throw new ApplicationException("On WinCE comm port must end with :");
}
}
this.mPortName = "\\\\.\\" + value;
}
}
/// <summary>
/// Gets or sets the number of bytes in the internal input buffer before a OpenNETCF.IO.Ports.SerialPort.ReceivedEvent is fired.
/// </summary>
/// <return>An integer object.</return>
#if DESIGN
[DefaultValue(1)]
#endif
public int ReceivedBytesThreshold
{
get {
return this.mRthreshold;
}
set {
this.mRthreshold = value;
}
}
/// <summary>
/// Gets or sets the standard number of stopbits per byte.
/// </summary>
/// <return>A value of the enumeration <see cref="StopBits"/>.</return>
#if DESIGN
[DefaultValue(1)]
#endif
public StopBits StopBits {
get
{
return this.mStopBits;
}
set {
if ((value < StopBits.One) || (value > StopBits.OnePointFive)) {
throw new ArgumentOutOfRangeException("StopBits. Use the Enum");
}
this.mStopBits = value;
if (this.IsOpen) {
this.UpdateSettings();
}
}
}
/// <summary>
/// Gets or sets whether the Request to Transmit (RTS) signal is enabled during serial communication.
/// </summary>
/// <return>true to enable RTS, otherwise false.</return>
#if DESIGN
[DefaultValue(false)]
#endif
public bool RtsEnable {
get
{
return (this.mRts == 1);
}
set {
if(this.mRts < 0) return;
if(hPort == (IntPtr)CommAPI.INVALID_HANDLE_VALUE) return;
if (value) {
if (m_CommAPI.EscapeCommFunction(hPort, CommEscapes.SETRTS))
this.mRts = 1;
else
throw new ApplicationException("Failed to set RTS!");
}
else {
if (m_CommAPI.EscapeCommFunction(hPort, CommEscapes.CLRRTS))
this.mRts = 0;
else
throw new ApplicationException("Failed to clear RTS!");
}
}
}
/// <summary>
/// Gets or sets the number of milliseconds before a timeout occurs when a write operation does not finish.
/// </summary>
/// <return>An integer object.</return>
#if DESIGN
[DefaultValue(-1)]
#endif
public int WriteTimeout {
get
{
return this.mWriteTimeout;
}
set {
if ((value == 0) || (value < InfiniteTimeout)) {
throw new ArgumentOutOfRangeException("WriteTimeout. Only valid negative value is -1");
}
this.mWriteTimeout = value;
if (this.IsOpen) {
this.UpdateTimeouts();
}
}
}
/// <summary>
/// Gets or sets the number of milliseconds before a timeout occurs when a read operation does not finish.
/// </summary>
/// <return>An integer object.</return>
#if DESIGN
[DefaultValue(-1)]
#endif
public int ReadTimeout {
get
{
return this.mReadTimeout;
}
set {
if (value < InfiniteTimeout) {
throw new ArgumentOutOfRangeException("ReadTimeout. Cannot be 0 or <-1");
}
this.mReadTimeout = value;
if (this.IsOpen) {
this.UpdateTimeouts();
}
}
}
/// <summary>
/// Gets or sets the size of the serial port output buffer.
/// </summary>
/// <return>An integer value representing the size of the output buffer. The default value is 2048.</return>
#if DESIGN
[DefaultValue(2048)]
#endif
public int WriteBufferSize {
get
{
return this.mTxBufferSize;
}
set {
if (value <= 0) {
throw new ArgumentOutOfRangeException("WriteBufferSize must be > 0");
}
this.mTxBufferSize = value;
if (this.IsOpen) {
throw new InvalidOperationException("WriteBufferSize cannot be set when open");
}
}
}
/// <summary>
/// Gets or sets the size of the <see cref="SerialPort"/> input buffer.
/// </summary>
/// <return>An integer value representing the buffer size The default value is 4096..</return>
#if DESIGN
[DefaultValue(4096)]
#endif
public int ReadBufferSize {
get
{
return this.mRxBufferSize;
}
set {
if (value <= 0) {
throw new ArgumentOutOfRangeException("ReadBufferSize must be > 0");
}
this.mRxBufferSize = value;
if (this.IsOpen) {
throw new InvalidOperationException("ReadBufferSize cannot be set when open");
}
}
}
/// <summary>
/// Gets or sets the character encoding for pre- and post-transmission conversion of text.
/// </summary>
/// <return>A <see cref="System.Text.Encoding"/> object.</return>
#if DESIGN
[Browsable(false)]
#endif
public Encoding Encoding
{
get {
return this.mEncoding;
}
set {
if (value == null) {
throw new ArgumentNullException("Encoding");
}
this.mEncoding = value;
this.mDecoder = this.mEncoding.GetDecoder();
}
}
#endregion
#region Public Methods
/// <summary>
/// Not Currently Supported. Gets an array of serial port names for the current machine.
/// </summary>
/// <returns>An array of serial port names for the current machine.</returns>
public static string[] GetPortNames() {
// TODO iterate over reg key and return array of port names
// @"HARDWARE\DEVICEMAP\SERIALCOMM"
throw new NotSupportedException("not yet");
}
/// <summary>
/// Discards data from the serial driver's receive buffer.
/// </summary>
public void DiscardInBuffer() {
if (!this.IsOpen) {
throw new InvalidOperationException("Port is not open");
}
if (m_CommAPI.PurgeComm(hPort, 10) != 0 ) {
throw new ApplicationException("could not discard in buffer");
}
this.mReadLen = 0;
this.mReadPos = 0;
}
/// <summary>
/// Discards data from the serial driver's transmit buffer.
/// </summary>
public void DiscardOutBuffer() {
if (!this.IsOpen) {
throw new InvalidOperationException("Port is not open");
}
if (m_CommAPI.PurgeComm(hPort, 5) != 0 ) {
throw new ApplicationException("could not discard out buffer");
}
}
/// <summary>
/// Opens a new serial port connection.
/// </summary>
public void Open() {
if(this.mIsOpen) throw new InvalidOperationException("Comm Port is already open!");
if(CommAPI.FullFramework) {
// set up the overlapped tx IO
OVERLAPPED o = new OVERLAPPED();
this.mTxOverlapped = LocalAlloc(0x40, Marshal.SizeOf(o));
o.Offset = 0;
o.OffsetHigh = 0;
o.hEvent = IntPtr.Zero;
Marshal.StructureToPtr(o, this.mTxOverlapped, true);
}
hPort = m_CommAPI.CreateFile(this.mPortName);
if(hPort == (IntPtr)CommAPI.INVALID_HANDLE_VALUE) {
int e = Marshal.GetLastWin32Error();
if(e == (int)APIErrors.ERROR_ACCESS_DENIED) {
// port is unavailable
throw new ApplicationException("ERROR_ACCESS_DENIED");
}
// ClearCommError failed!
string error = String.Format("CreateFile Failed: {0}", e);
throw new ApplicationException(error);
}
this.mIsOpen = true;
// clear errors
CommErrorFlags errorFlags = new CommErrorFlags();
CommStat commStat = new CommStat();
if(!m_CommAPI.ClearCommError(hPort, ref errorFlags, commStat)) {
throw new ApplicationException("Failed to clear error/read");
}
// set queue sizes
m_CommAPI.SetupComm(hPort, this.mRxBufferSize, this.mTxBufferSize);
// update dcb
this.UpdateSettings();
// store some state values
this.mInBreak = false;
// read/write timeouts
this.UpdateTimeouts();
// start the receive thread
this.mEventThread = new Thread(new ThreadStart(CommEventThread));
this.mEventThread.Priority = ThreadPriority.Normal; //by design
this.mEventThread.Start();
// wait for the thread to actually get spun up
this.mThreadStarted.WaitOne();
}
/// <summary>
/// Closes the port connection, sets OpenNETCF.IO.Ports.SerialPort.IsOpen to false and disposes of the internal System.IO.Stream object.
/// </summary>
public void Close() {
if(this.mTxOverlapped != IntPtr.Zero) {
LocalFree(this.mTxOverlapped);
this.mTxOverlapped = IntPtr.Zero;
}
if(!this.mIsOpen) return;
this.mIsOpen = false; // to help catch intentional close
if(m_CommAPI.CloseHandle(hPort)) {
m_CommAPI.SetEvent(this.mCloseEvent);
this.mIsOpen = false;
hPort = (IntPtr)CommAPI.INVALID_HANDLE_VALUE;
m_CommAPI.SetEvent(this.mCloseEvent);
}
}
#region Read
/// <summary>
/// Reads a number of bytes from the OpenNETCF.IO.Ports.SerialPort input buffer and writes those bytes into a character array at a given offset.
/// </summary>
/// <param name="buffer">The byte array to which the input is written.</param>
/// <param name="offset">The offset in the buffer array where writing should begin.</param>
/// <param name="count">The number of bytes to be read.</param>
public int Read(byte[] buffer, int offset, int count) {
if (!this.IsOpen) {
throw new InvalidOperationException("Port is not open");
}
if (buffer == null) {
throw new ArgumentNullException("buffer");
}
if (offset < 0) {
throw new ArgumentOutOfRangeException("offset must be > 0");
}
if (count < 0) {
throw new ArgumentOutOfRangeException("count must be > 0");
}
if ((buffer.Length - offset) < count) {
throw new ArgumentException("Failed: ((buffer.Length - offset) < count)");
}
int bytesToRead = 0;
if ((this.mReadLen - this.mReadPos) >= 1) {
bytesToRead = Math.Min((this.mReadLen - this.mReadPos), count);
Buffer.BlockCopy(this.mInBuffer, this.mReadPos, buffer, offset, bytesToRead);
this.mReadPos += bytesToRead;
if (bytesToRead == count) {
if (this.mReadPos == this.mReadLen) {
this.mReadLen = 0;
this.mReadPos = 0;
}
return count;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -