C # serial port operation

xiaoxiao2021-04-09  308

* * Author: Marcus Lorentzon, 2001 * d98malor@dtek.chalmers.se * * Freeware: Please do not remove this header * * File: SerialStream.cs * * Description:. Implements a Stream for asynchronous * transfers and COMM Stream version. * * Version: 2.4 * * / #region Using using System; using System.IO; using System.Threading; using System.Runtime.InteropServices; using System.ComponentModel; #endregion Using namespace LoMaN.IO {public class SerialStream: Stream { #region Attributes private IOCompletionCallback m_IOCompletionCallback; private IntPtr m_hFile = IntPtr.Zero; private string m_sPort; private bool m_bRead; private bool m_bWrite; #endregion Attributes #region Properties public string Port {get {return m_sPort;} set {if (m_sPort =! Value) {close (); open (value); }} Public override bool CanRead {get {return m_bRead;}} public override bool CanWrite {get {return m_bWrite;}} public override bool CanSeek {get {return false;}} public bool Closed {get {return m_hFile.ToInt32 () 0;}} public bool dsr {get {uint status; if (! Getcommodemstatus) {throw new win32exception ();} return (status & ms_dsr_on)> 0;

}} Public bool Ring {get {uint status; (! GetCommModemStatus (m_hFile, out status)) if {throw new Win32Exception ();} return (status & MS_RING_ON)> 0;}} public bool Rlsd {get {uint status; (! GetCommModemStatus (m_hFile, out status)) if {throw new Win32Exception ();} return (status & MS_RLSD_ON)> 0;}} #endregion Properties #region Constructors public SerialStream (): this (FileAccess.ReadWrite) {} public SerialStream (FileAccess access) {m_bRead = ((int) access & (int) FileAccess.Read) = 0;! m_bWrite = ((int) access & (int) FileAccess.Write) = 0;! unsafe {m_IOCompletionCallback = new IOCompletionCallback (Asyncfscallback);}} PUBLIC SerialStream (string port): this (FileAccess.ReadWrite) {Open (port);} public SerialStream (string port, FileAccess access): this (access) {Open (port);} #endregion Constructors #region Methods public void Open ( String port) {if (m_hfile! = INTPTR.ZERO) {Throw new oException ("stream already open oException);} m_sport = port; m_hfile = cretefile (port, (uint) ((m_bread? generic_read: 0) | M_bwrite? generic_write: 0)), 0, 0, Open_EXISTING, FILE_FLAG_OVERLAPPED, 0); if (m_hfile.toint32 () ==

INVALID_HANDLE_VALUE) {m_hFile = IntPtr.Zero; throw new FileNotFoundException ( "Unable to open" port);} ThreadPool.BindHandle (m_hFile); SetTimeouts (0, 0, 0, 0, 0);} public override void Close () {CloseHandle (m_hFile); m_hFile = IntPtr.Zero; m_sPort = null;} public IAsyncResult BeginRead (byte [] buffer) {return BeginRead (buffer, 0, buffer.Length, null, null);} public override IAsyncResult BeginRead (byte [] buffer, int offset, int count, AsyncCallback callback, object state) {GCHandle gchBuffer = GCHandle.Alloc (buffer, GCHandleType.Pinned); SerialAsyncResult sar = new SerialAsyncResult (this, state, callback, true, gchBuffer); Overlapped ov = New overlapped (0, 0, sar.asyncwaithandle.handle.toint32 (), sar); unsafe {nativeOverlapped * nov = ov.pack (m_iocompletioncallback); Byte * data = ((int) gchbuffer.addrofpinnedObject () offset; uint read = 0; if (readfile (m_hfile, data, (uint) count, out read, nov) {sar.m_bcompletedsynchronously = Else IF ("unable to initialize read. Erse throw new exception (" unable to initialize read. Erse throw new exception).

}} Public IAsyncResult BeginWrite (byte [] buffer) {return BeginWrite (buffer, 0, buffer.Length, null, null);} public override IAsyncResult BeginWrite (byte [] buffer, int offset, int count, AsyncCallback callback, object state ) {GCHandle gchBuffer = GCHandle.Alloc (buffer, GCHandleType.Pinned); SerialAsyncResult sar = new SerialAsyncResult (this, state, callback, false, gchBuffer); Overlapped ov = new Overlapped (0, 0, sar.AsyncWaitHandle.Handle.ToInt32 (), sar); unsafe {NativeOverlapped * nov = ov.Pack (m_IOCompletionCallback); byte * data = (byte *) ((int) gchBuffer.AddrOfPinnedObject () offset); uint written = 0; if (WriteFile (m_hFile , DATA, OUT WRITTEN, NOV) {sar.m_bcompletedsynchronously = true; return sar;} else}} else}} else}}} else return sar;} else throw new Exception ( "Unable to initialize write Errorcode:." GetLastError () ToString ().);}} private int EndOperation (IAsyncResult asyncResult, bool isRead) {SerialAsyncResult sar = (SerialAsyncResult) asyncResult; if (SAR.M_BISREAD! = Isread) Throw new oException ("ISRID Parameter: IASYNCRESULT IS NOT": "Write"); if (sar.endoperationcalled) {throw new oException ("end" (Isread? "Read": "Write") "

Called twice for the same operation. ");} else {sar.m_bendopertycalled = true;} while (! sar.m_bcompleted) {sar.asyncwaithandle.waitone ();} sar.dispose (); if (sar.m_nerrorcode! = ERROR_SUCCESS && sar.m_nErrorCode = ERROR_OPERATION_ABORTED) {throw new IOException ( "Operation finished with errorcode:" sar.m_nErrorCode);}! return sar.m_nReadWritten;} public override int EndRead (IAsyncResult asyncResult) {return EndOperation (asyncResult, true) ;} public override void EndWrite (IAsyncResult asyncResult) {EndOperation (asyncResult, false);} public int EndWriteEx (IAsyncResult asyncResult) {return EndOperation (asyncResult, false);} public override int Read (byte [] buffer, int offset, int Count) {RETURN Endread (Beginrea D (buffer, offset, count, null, null);} public override void write (byte [] buffer, int offset, int count) {endwrite (Buffer, Offset, Count, Null, Null);} PUBLIC int WriteEx (byte [] buffer, int offset, int count) {return EndWriteEx (BeginWrite (buffer, offset, count, null, null));} public int Read (byte [] buffer) {return EndRead (BeginRead (buffer, 0, buffer.length, null, null);} public int Write (Byte [] buffer) {Return Endoperation (Buffer, 0, Buffer.length, Null, Null);} public override void flush () () PUBLIC OVERRIDE VOID FLUSH ) {Flushfilebuffers; m_hfile;

} Public bool PurgeRead () {return PurgeComm (m_hFile, PURGE_RXCLEAR);} public bool PurgeWrite () {return PurgeComm (m_hFile, PURGE_TXCLEAR);} public bool Purge () {return PurgeRead () && PurgeWrite ();} public bool CancelRead () {return PurgeComm (m_hFile, PURGE_RXABORT);} public bool CancelWrite () {return PurgeComm (m_hFile, PURGE_TXABORT);} public bool CancelAll () {return CancelRead () && CancelWrite ();} public override void SetLength (long nLength ) {throw new NotSupportedException ( "SetLength is not supported on serial ports.");} public override long Seek (long offset, SeekOrigin origin) {throw new NotSupportedException ( "Seek is not supported on serial ports.");} Public void setTimeouts (int ReadTotAltimeout, Int Readtotaltimeoutmultipli er, int ReadTotalTimeoutConstant, int WriteTotalTimeoutMultiplier, int WriteTotalTimeoutConstant) {SerialTimeouts Timeouts = new SerialTimeouts (ReadIntervalTimeout, ReadTotalTimeoutMultiplier, ReadTotalTimeoutConstant, WriteTotalTimeoutMultiplier, WriteTotalTimeoutConstant); unsafe {SetCommTimeouts (m_hFile, ref Timeouts);

}} Public bool SetPortSettings (uint baudrate) {return SetPortSettings (baudrate, FlowControl.Hardware);} public bool SetPortSettings (uint baudrate, FlowControl flowControl) {return SetPortSettings (baudrate, flowControl, Parity.None);} public bool SetPortSettings (uint baudrate, flowControl flowControl, Parity parity) {return SetPortSettings (baudrate, flowControl, parity, 8, StopBits.One);} public bool SetPortSettings (uint baudrate, flowControl flowControl, Parity parity, byte databits, StopBits stopbits) {unsafe {DCB dcb = New DCB (); dcb.dcblength = sizeof (dcb); dcb.baudrate = baudrate; dcb.bytesize = dataBits; dcb.stopbits = (byte) stopbits; dcb.parity = (byte) Parity; dcb.fparity = Parity> 0)? 1U: 0u; dcb.fbinary = dcb.fdtrControl = dcb.ftxcontinueonxoff = 1; dcb.fOutxCtsFlow = dcb.fAbortOnError = (flowControl == FlowControl.Hardware) 1U: 0U; dcb.fOutX = dcb.fInX = (flowControl == FlowControl.XOnXOff) 1U:? 0U; dcb.fRtsControl = (flowControl? == FlowControl.hardware)? 2U: 1U; dcb.xonlim = 2048; dcb.xOfflim = 512; dcb.xonchar = 0x11; // Ctrl-q dcb.xoffchar = 0x13; // ctrl-s return setcommstate (m_hfile, Ref dcb);}} public bool setPortSettings (DCB DCB) {Return setcommstate (M_HFILE, REF DCB);

} Public Bool getPortSettings (Out DCB DCB) {Unsafe {DCB DCB2 = New DCB (); DCB2.DCBLENGTH = SIZEOF (DCB); BOOL RET = getcommstate (M_HFILE, REF DCB2); DCB = DCB2; Return Ret;}} PUBLIC bool SetXOn () {return EscapeCommFunction (m_hFile, SETXON);} public bool SetXOff () {return EscapeCommFunction (m_hFile, SETXOFF);} private unsafe void AsyncFSCallback (uint errorCode, uint numBytes, NativeOverlapped * pOverlapped) {SerialAsyncResult sar = (SerialAsyncResult ) Overlapped.Unpack (pOverlapped) .AsyncResult; sar.m_nErrorCode = errorCode; sar.m_nReadWritten = (int) numBytes; sar.m_bCompleted = true;! if (sar.Callback = null) sar.Callback.Invoke (sar); Overlapped .Free (Poverlapped);} #endregion methods #Region Constants private const uint PURGE_TXABORT = 0x0001; // Kill the pending / current writes to the comm port private const uint PURGE_RXABORT = 0x0002;. // Kill the pending / current reads to the comm port private const uint PURGE_TXCLEAR = 0x0004;. // Kill . the transmit queue if there private const uint PURGE_RXCLEAR = 0x0008;. // Kill the typeahead buffer if there private const uint SETXOFF = 1; // Simulate XOFF received private const uint SETXON = 2; // Simulate XON received private const uint SETRTS = 3; // set RTS High Private const uint CLRTS = 4;

// SET RTS LOW private const uint setdtr = 5; // set DTR high private const uint clrdtr = 6; // set DTR low private const uint setbreak = 8; // set the device break line line. Private const uint crarbreak = 9 ;. // Clear the device break line private const uint MS_CTS_ON = 0x0010; private const uint MS_DSR_ON = 0x0020; private const uint MS_RING_ON = 0x0040; private const uint MS_RLSD_ON = 0x0080; private const uint FILE_FLAG_OVERLAPPED = 0x40000000; private const uint OPEN_EXISTING = 3 ; private const int INVALID_HANDLE_VALUE = -1; private const uint GENERIC_READ = 0x80000000; private const uint GENERIC_WRITE = 0x40000000; private const uint ERROR_SUCCESS = 0; private const uint ERROR_OPERATION_ABORTED = 995; private const uint ERROR_IO_PENDING = 997; #endregion Constants #region Enums Public Enum Parity {None, ODD, Even, Mark , Space}; public enum StopBits {One, OneAndHalf, Two}; public enum FlowControl {None, XOnXOff, Hardware}; #endregion Enums #region Classes [StructLayout (LayoutKind.Sequential)] public struct DCB {#region Attributes public int DCBlength ; public uint BaudRate; public uint Flags; public ushort wReserved; public ushort XonLim; public ushort XoffLim; public byte ByteSize; public byte Parity; public byte StopBits; public sbyte XonChar; public sbyte XoffChar; public sbyte ErrorChar;

public sbyte EofChar; public sbyte EvtChar; public ushort wReserved1; #endregion Attributes #region Properties public uint fBinary {get {return Flags & 0x0001;} set {Flags = Flags & ~ 1U | value;}} public uint fParity {get {return (Flags >> 1) & 1;} set {Flags = Flags & ~ (1U> 2) & 1;} set {flags = flags & ~ (1u> 3) & 1;} set {flags = flags & ~ (1u> 4) & 3 } Set {flags = flags & ~ (3U> 6) & 1;} set {flags = flags & ~ (1u> 7) & 1;} set {flags = flags & ~ (1u> 8) & 1;} set {Flags = Flags & ~ (1U> 9) & 1;} set {flags = flags & ~ (1u> 10) & 1;} set {flags = flags & ~ (1u> 11) & 1;} Set {Flags = Flags & ~ (1U> 12) & 3;} set {flags = flags & ~ (3u> 14) & 1;} set {flags = flags & ~ (1u << 14) | (value << 14) }} #Endregion Properties #REGONMETHODS PUBLIC OVERRIDE STRING TOSTRING () {Return "Dcblength:" DCBLENGTH "/ R / N" "BAUDRATE:" BAUDRATE "/ R / N" "fbinary:"

FBINARY "/ R / N" "FPARITY:" FPARITY "/ R / N" "foutxctsflow:" foutxctsflow "/ r / n" "foutxdsrflow:" foutxdsrflow "/ r / n" "FDTRCONTROL:" FDTRCONTROL "/ R / N" "fdsrsitivity:" fdsrsensitivity "/ r / n" "ftxcontinueonxoff:" ftxcontinueonxoff "/ r / n" "foutx:" foutx "/ r / n" "FINX:" FINX "/ R / N" "FERRORCHAR:" FERRORCHAR "/ R / N" "fnull:" fnull "/ r / n" " FRTSCONTROL: " FRTSCONTROL " / R / N " " Fabortonerror: " Fabortonerror " / R / N " " XONLIM: " XONLIM " / R / N " " Xofflim: " Xofflim " / R / N " " bytesize: " " "Parity:" Parity "/ R / N" "Stopbits:" Stopbits "/ R / N" "x OnChar: " Xonchar " / R / N " " Xoffchar: " Xoffchar " / R / N " " EOFCHAR: " EOFCHAR " / R / N " "

EvtChar: " EvtChar " / r / n ";} #endregion Methods} private class SerialAsyncResult: IAsyncResult, IDisposable {#region Attributes internal bool m_bEndOperationCalled = false; internal bool m_bIsRead; internal int m_nReadWritten = 0; internal bool m_bCompleted = false ; internal bool m_bCompletedSynchronously = false; internal uint m_nErrorCode = ERROR_SUCCESS; private object m_AsyncObject; private object m_StateObject; private ManualResetEvent m_WaitHandle = new ManualResetEvent (false); private AsyncCallback m_Callback; private GCHandle m_gchBuffer; #endregion Attributes #region Properties internal bool EndOperationCalled {get {Return M_BendOperationCalled;}} public bool iScompleted {get {return m_bcompleted;}} public bool completedsynchronously {Get {return m_bCompletedSynchronously;}} public object AsyncObject {get {return m_AsyncObject;}} public object AsyncState {get {return m_StateObject;}} public WaitHandle AsyncWaitHandle {get {return m_WaitHandle;}} internal ManualResetEvent WaitHandle {get {return m_WaitHandle; }}} Public asyncCallback callback {get {return m_callback;

}} #Endregion Properties #region Constructors public SerialAsyncResult (object asyncObject, object stateObject, AsyncCallback callback, bool bIsRead, GCHandle gchBuffer) {m_AsyncObject = asyncObject; m_StateObject = stateObject; m_Callback = callback; m_bIsRead = bIsRead; m_gchBuffer = gchBuffer;} #endregion Constructors #region Methods public void Dispose () {m_WaitHandle.Close (); m_gchBuffer.Free ();} #endregion Methods} #endregion Classes #region Imports [DllImport ( "kernel32.dll", EntryPoint = "CreateFileW", SetLastError = True, Charset = charset.unicode, extern INTPTR CREATEFILE (STRING FILENAME, UINT Access, Uint Sharemode, Uint Security_ attributes, uint creation, uint flags, uint template); [DllImport ( "kernel32.dll", SetLastError = true)] static extern bool CloseHandle (IntPtr handle); [DllImport ( "kernel32.dll", SetLastError = true)] static extern unsafe bool ReadFile (IntPtr hFile, byte * lpBuffer, uint nNumberOfBytesToRead, out uint lpNumberOfBytesRead, NativeOverlapped * lpOverlapped); [DllImport ( "kernel32.dll", SetLastError = true)] static extern unsafe bool WriteFile (IntPtr hFile, byte * lpBuffer , uint nnumberofbytestowrite, out uint lpnumberofbyteswritten, nativeoverlapped * lpoverlapped; [DLLIMPORT ("kernel32.dll"

, SetLastError = true)] static extern bool SetCommTimeouts (IntPtr hFile, ref SerialTimeouts lpCommTimeouts); [DllImport ( "kernel32.dll", SetLastError = true)] static extern bool SetCommState (IntPtr hFile, ref DCB lpDCB); [DllImport ( " kernel32.dll ", SetLastError = true)] static extern bool GetCommState (IntPtr hFile, ref DCB lpDCB); [DllImport (" kernel32.dll ", SetLastError = true)] static extern bool BuildCommDCB (string def, ref DCB lpDCB); [DllImport ( "kernel32.dll", SetLastError = true)] static extern int GetLastError (); [DllImport ( "kernel32.dll", SetLastError = true)] static extern bool FlushFileBuffers (IntPtr hFile); [DllImport ( "kernel32. dll ", SetLastError = true)] static extern bool PurgeComm (IntPtr hFile, uint dwFlags); [DllImport (" kernel32.dll ", SetLastError = true)] static extern bool EscapeCommFunction (IntPtr hFile, uint dwFunc); [DllImport (" Kernel32.dll ", setLastError = true)] static extern bool GetCommModemStatus (IntPtr hFile, out uint modemStat); #endregion Imports} [StructLayout (LayoutKind.Sequential)] public struct SerialTimeouts {#region Attributes public int ReadIntervalTimeout; public int ReadTotalTimeoutMultiplier; public int ReadTotalTimeoutConstant; public int WriteTotalTimeoutMultiplier; public int WriteTotalTimeoutConstant; #endregion Attributes #Region Constructionors Public SerialTimeouts (int R1, Int R2, Int R3, Int W1, INT W2) {readintervaltimeout = r1; readtotalTimeoutMultiplier =

r2; ReadTotalTimeoutConstant = r3; WriteTotalTimeoutMultiplier = w1; WriteTotalTimeoutConstant = w2;} #endregion Constructors #region Methods public override string ToString () {return "ReadIntervalTimeout:" ReadIntervalTimeout "/ r / n" "ReadTotalTimeoutMultiplier:" ReadTotalTimeoutMultiplier "/ r / n" "ReadTotalTimeoutConstant:" ReadTotalTimeoutConstant "/ r / n" "WriteTotalTimeoutMultiplier:" WriteTotalTimeoutMultiplier "/ r / n" "WriteTotalTimeoutConstant:" WriteTotalTimeoutConstant "/ r / n";} #endregion Methods}} using System; using System.IO; using System.Threading; using LoMaN.IO; namespace SerialStreamReader {class App {// The main serial stream static SerialStream ss; [STAThread] static void main (string [] args ) {// Create a Serial Port SS = new serialStream (); try {ss.open ("COM3");} catch (exception e) {console.writeline ("Error:" E.MESSAGE); Return;} // set port set settings ss.setportSettings (9600); // set Timeout So Readings After 20ms of Silence After a Response Ss.SetTimeouts (20, 0, 0, 0, 0); // Create The streamwriter Used to send commands streamwriter sw = new streamwriter (SS, System.Text.Encoding.ascii);

转载请注明原文地址:https://www.9cbs.com/read-133081.html

New Post(0)