⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 serialport.cs

📁 本源码为OpenNETCF源代码
💻 CS
📖 第 1 页 / 共 3 页
字号:
//==========================================================================================
//
//		OpenNETCF.IO.Ports.SerialPort
//		Copyright (c) 2005, OpenNETCF.org
//
//		This library is free software; you can redistribute it and/or modify it under 
//		the terms of the OpenNETCF.org Shared Source License.
//
//		This library is distributed in the hope that it will be useful, but 
//		WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 
//		FITNESS FOR A PARTICULAR PURPOSE. See the OpenNETCF.org Shared Source License 
//		for more details.
//
//		You should have received a copy of the OpenNETCF.org Shared Source License 
//		along with this library; if not, email licensing@opennetcf.org to request a copy.
//
//		If you wish to contact the OpenNETCF Advisory Board to discuss licensing, please 
//		email licensing@opennetcf.org.
//
//		For general enquiries, email enquiries@opennetcf.org or visit our website at:
//		http://www.opennetcf.org
//
//==========================================================================================

using System;
using System.Runtime.InteropServices;
using System.Threading;
using System.Collections;
using System.Text;
using System.ComponentModel;
using OpenNETCF.IO.Serial;

namespace OpenNETCF.IO.Ports {

	/// <summary>
	/// Represents a serial port resource.
	/// <para><b>New in v1.3</b></para>
	/// </summary>
#if DESIGN
	[ToolboxItemFilter("NETCF",ToolboxItemFilterType.Require),
	ToolboxItemFilter("System.CF.Windows.Forms", ToolboxItemFilterType.Custom)]
#endif
	public class SerialPort : Component, IDisposable 
	{

		#region Events
		public event SerialDataReceivedEventHandler DataReceived;
		public event SerialErrorReceivedEventHandler ErrorReceived;
		public event SerialPinChangedEventHandler PinChanged;
		#endregion

		
		#region Creation Destruction
		/// <summary>
		/// Not Currently Supported. Initializes a new instance of the <see cref="SerialPort"/> class using the <see cref="System.ComponentModel.IContainer"/> object specified.
		/// </summary>
		/// <param name="container">An interface to a container.</param>
		public SerialPort(IContainer container) : this() {
			// add designer support. Low priority as you can still create it in code
			//container.Add(this);
			throw new NotSupportedException("not yet");
		}
		/// <summary>
		/// Initializes a new instance of the <see cref="SerialPort"/> class.
		/// </summary>
		public SerialPort(){
			// create the API class based on the target
			if (System.Environment.OSVersion.Platform != PlatformID.WinCE)
				m_CommAPI = new WinCommAPI();
			else
				m_CommAPI = new CECommAPI();

			// create a system event for synchronizing Closing
			this.mCloseEvent = m_CommAPI.CreateEvent(true, false, CloseEventName);
		}

		/// <summary>
		/// Initializes a new instance of the <see cref="SerialPort"/> class using the specified port name.
		/// </summary>
		/// <param name="portName">A string indicating the port to be used, for example, COM1.</param>
		public SerialPort(string portName) : this(portName, 9600, Parity.None, 8, StopBits.One) {}

		/// <summary>
		/// Initializes a new instance of the <see cref="SerialPort"/> class using the specified port name, baud rate and parity bit.
		/// </summary>
		/// <param name="portName">A string indicating the port to be used, for example, COM1.</param>
		/// <param name="baudRate">An integer indicating the baud rate.</param>
		public SerialPort(string portName, int baudRate) : this(portName, baudRate, Parity.None, 8, StopBits.One) {}
		/// <summary>
		/// Initializes a new instance of the <see cref="SerialPort"/> class using the specified port name, baud rate and parity bit.
		/// </summary>
		/// <param name="portName">A string indicating the port to be used, for example, COM1.</param>
		/// <param name="baudRate">An integer indicating the baud rate.</param>
		/// <param name="parity">A value from the <see cref="Parity"/> enumeration.</param>
		public SerialPort(string portName, int baudRate, Parity parity) : this(portName, baudRate, parity, 8, StopBits.One) {}

		/// <summary>
		/// Initializes a new instance of the <see cref="SerialPort"/> class using the specified port name, baud rate, parity bit and data bits.
		/// </summary>
		/// <param name="portName">A string indicating the port to be used, for example, COM1.</param>
		/// <param name="baudRate">An integer indicating the baud rate.</param>
		/// <param name="parity">A value from the <see cref="Parity"/> enumeration.</param>
		/// <param name="dataBits">An integer indicating the data bits value.</param>
		public SerialPort(string portName, int baudRate, Parity parity, int dataBits) : this(portName, baudRate, parity, dataBits, StopBits.One) {}

		/// <summary>
		/// Initializes a new instance of the <see cref="SerialPort"/> class using the specified port name, baud rate, parity bit, data bits and stop bit.
		/// </summary>
		/// <param name="portName">A string indicating the port to be used, for example, COM1.</param>
		/// <param name="baudRate">An integer indicating the baud rate.</param>
		/// <param name="parity">A value from the <see cref="Parity"/> enumeration.</param>
		/// <param name="dataBits">An integer indicating the data bits value.</param>
		/// <param name="stopBits">A value from the <see cref="StopBits"/> enumeration.</param>
		public SerialPort(string portName, int baudRate, Parity parity, int dataBits, StopBits stopBits) : this() {
			this.PortName = portName;
			this.BaudRate = baudRate;
			this.Parity = parity;
			this.DataBits = dataBits;
			this.StopBits = stopBits;
		}

		/// <summary>
		/// Releases the unmanaged resources used by the <see cref="SerialPort"/> object.
		/// </summary>
		public void Dispose() {
			if(this.mIsOpen)
				this.Close();
			//base.Dispose(true);			
		}
		
		/// <summary>
		/// Class destructor
		/// </summary>
		~SerialPort() {
			if(this.mIsOpen)
				this.Close();
		}
		#endregion

		#region Private Fields
		private Encoding mEncoding = Encoding.ASCII;
		private Decoder mDecoder = Encoding.ASCII.GetDecoder();
		private string mNewLine = @"\n";
		private byte mByteSize = 8;
		private bool mDiscardNull = false;
		private Handshake mHandshake = Handshake.None;
		private byte mErrorChar = 0x3f; //?
		private StopBits mStopBits = StopBits.One;
		private int mWriteTimeout = InfiniteTimeout;
		private int mReadTimeout = InfiniteTimeout;
		private int mRxBufferSize = 4096;
		private int mTxBufferSize = 2048;
		private int	mRts = 0;
		private int mRthreshold = 1;
		private string mPortName = "COM1:";
		private Parity mParity = Parity.None;
		private bool mIsOpen = false;
		private int	mDtr = 1;
		private bool mInBreak = false;
		private int mBaudRate = 9600;
		private IntPtr hPort = (IntPtr)CommAPI.INVALID_HANDLE_VALUE;
		private DCB mDcb = new DCB();
		private Thread mEventThread = null;
		private ManualResetEvent mThreadStarted = new ManualResetEvent(false);
		private IntPtr mCloseEvent;
		private IntPtr mTxOverlapped = IntPtr.Zero;
		private IntPtr mRxOverlapped = IntPtr.Zero;
		private const string CloseEventName = "CloseEvent";
		private CommAPI m_CommAPI = null;
		private int mReadPos = 0;
		private int mReadLen = 0;
		private byte[] mInBuffer = new byte[1024];
		#endregion

		#region Public Properties
		/// <summary>
		/// Indicates that no timeout should occur.
		/// </summary>
#if DESIGN
		[Browsable(false)]
#endif
		public const int InfiniteTimeout = -1; 
		/// <summary>
		/// Gets the underlying System.IO.Stream object for a OpenNETCF.IO.Ports.SerialPort object.
		/// </summary>
		/// <returns>A System.IO.Stream object.</returns>
		public System.IO.Stream BaseStream() {
			// some day in the distant future someone else may want to consider providing this
			throw new NotSupportedException("BaseStream Not supported");
		}
		/// <summary>
		/// Gets or sets the value used to interpret the end of a call to the <see cref="ReadLine"/> and <see cref="WriteLine"/> methods.
		/// </summary>
#if DESIGN
		[Browsable(false)]
#endif
		public string NewLine {
			get {
				return this.mNewLine;
			}
			set {
				if (value == null) {
					throw new ArgumentNullException();
				}
				if (value.Length == 0) {
					throw new ArgumentException("NewLine cannot be empty");
				}
				this.mNewLine = value;
			}
		}

		/// <summary>
		/// Gets or sets the serial baud rate.
		/// </summary>
		/// <returns>An integer object representing the baud rate.</returns>
#if DESIGN
	[DefaultValue(9600)]
#endif
		public int BaudRate 
		{
			get {
				return this.mBaudRate;
			}
			set {
				if (value <= 0) {
					throw new ArgumentOutOfRangeException("BaudRate must be > 0");
				}
				this.mBaudRate = value;
				if (this.IsOpen) {
					this.UpdateSettings();
				}
			}
		}
		/// <summary>
		/// Gets or sets the break signal state.
		/// </summary>
		/// <returns>true to enter a break state; otherwise false.</returns>
#if DESIGN
	[Browsable(false)]
#endif
		public bool BreakState 
		{
			get {
				if (!this.IsOpen) {
					throw new InvalidOperationException("Port is not open");
				}
				return this.mInBreak;
			}
			set {
				if (!this.IsOpen) {
					throw new InvalidOperationException("Port is not open");
				}
				if (value) {
					if (!m_CommAPI.EscapeCommFunction(hPort, CommEscapes.SETBREAK)) {
						throw new ApplicationException("Failed to set break");
					}
					this.mInBreak = true;
				}
				else {
					if (!m_CommAPI.EscapeCommFunction(hPort, CommEscapes.CLRBREAK)) {
						throw new ApplicationException("Failed to clear break");
					}
					this.mInBreak = false;
				}
			}
		}
		/// <summary>
		/// Gets the number of bytes of data in the receive buffer.
		/// </summary>
		/// <return>The number of bytes of data in the receive buffer.</return>
#if DESIGN
	[Browsable(false)]
#endif
		public int BytesToRead 
		{
			get {
				if (!this.IsOpen) {
					throw new InvalidOperationException("Port is not open");
				}
				CommErrorFlags errorFlags = new CommErrorFlags();
				CommStat commStat = new CommStat();				
				if(!m_CommAPI.ClearCommError(hPort, ref errorFlags, commStat)) {
					throw new ApplicationException("Failed to clear error/read");
				}
				return (int)commStat.cbInQue + (this.mReadLen - this.mReadPos);
			}
		}

		/// <summary>
		/// Gets the number of bytes of data in the send buffer.
		/// </summary>
		/// <return>The number of bytes of data in the send buffer.</return>
#if DESIGN
	[Browsable(false)]
#endif
		public int BytesToWrite {
			get {
				if (!this.IsOpen) {
					throw new InvalidOperationException("Port is not open");
				}
				CommErrorFlags errorFlags = new CommErrorFlags();
				CommStat commStat = new CommStat();				
				if(!m_CommAPI.ClearCommError(hPort, ref errorFlags, commStat)) {
					throw new ApplicationException("Failed to clear error/write");
				}
				return (int)commStat.cbOutQue;
			}
		}

		/// <summary>
		/// Gets the state of the Carrier Detect line for the port.
		/// </summary>
		/// <return>true if carrier is detected; otherwise false.</return>
#if DESIGN
	[Browsable(false)]
#endif
		public bool CDHolding 
		{
			get {
				if (!this.IsOpen) {
					throw new InvalidOperationException("Port is not open");
				}
				uint status = 0;
				if (!m_CommAPI.GetCommModemStatus(hPort, ref status)) {
					throw new ApplicationException("Failed to get CD");
				}
				return ((((uint)CommModemStatusFlags.MS_RLSD_ON) & status) != 0);
			}
		}

		/// <summary>
		/// Gets the state of the Clear-to-Send line.
		/// </summary>
		/// <return>true if Clear-to-Send detected; otherwise false.</return>
#if DESIGN
	[Browsable(false)]
#endif
		public bool CtsHolding 
		{
			get {
				if (!this.IsOpen) {
					throw new InvalidOperationException("Port is not open");
				}
				uint status = 0;
				if (!m_CommAPI.GetCommModemStatus(hPort, ref status)) {
					throw new ApplicationException("Failed to get CTS");
				}
				return ((((uint)CommModemStatusFlags.MS_CTS_ON) & status) != 0);
			}
		}


		/// <summary>
		/// Gets or sets the standard length of data bits per byte.
		/// </summary>
		/// <return>An integer object specifying the data bits length.</return>
#if DESIGN
	[DefaultValue(8)]
#endif
		public int DataBits 
		{
			get {
				return this.mByteSize;
			}
			set {
				if ((value < 5) || (value > 8)) {
					throw new ArgumentOutOfRangeException("DataBits must be >=5 <=8");
				}
				this.mByteSize = (byte)value;
				if (this.IsOpen) {
					this.UpdateSettings();
				}
			}
		}
		/// <summary>
		/// Gets or sets whether null bytes are ignored when transmitted between the port and the receive buffer.
		/// </summary>
		/// <return>true if null bytes are ignored; otherwise false. The default value for this property is false.</return>
#if DESIGN
	[DefaultValue(false)]
#endif
		public bool DiscardNull 
		{
			get {
				return this.mDiscardNull;
			}
			set {
				this.mDiscardNull = value;
				if (this.IsOpen) {
					this.UpdateSettings();
				}
			}
		}

		/// <summary>
		/// Gets the state of the Data Set Ready (DSR) signal.
		/// </summary>
		/// <return>true if a Data Set Ready signal has been sent to the port; otherwise false.</return>
#if DESIGN
	[Browsable(false)]
#endif
		public bool DsrHolding 
		{
			get {
				if (!this.IsOpen) {
					throw new InvalidOperationException("Port is not open");
				}
				uint status = 0;
				if (!m_CommAPI.GetCommModemStatus(hPort, ref status)) {
					throw new ApplicationException("Failed to get DSR");
				}
				return ((((uint)CommModemStatusFlags.MS_DSR_ON) & status) != 0);
			}
		}

		/// <summary>
		/// Gets or sets enabling of the Data Terminal Ready (DTR) signal during serial communication.
		/// </summary>
		/// <return>true to enable DTR, otherwise false.</return>
#if DESIGN
	[DefaultValue(false)]
#endif
		public bool DtrEnable {
			get 
			{
				return (this.mDtr == 1);
			}
			set {
				if (value){
					this.mDtr = 1;
				}else{
					this.mDtr = 0;
				}
				if (this.IsOpen){
					this.UpdateSettings();

					if (!m_CommAPI.EscapeCommFunction(hPort, ((this.mDtr == 1) ? CommEscapes.SETDTR : CommEscapes.CLRDTR))){
						throw new ApplicationException("Failed to set/clear DTR!");
					}
				}
			}
		}
		
		/// <summary>
		/// Gets or sets the handshaking protocol for serial port transmission of data.

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -