C # serial port operation

xiaoxiao2021-04-09  360

The previous game saw a class that manages the serial port from the foreign website. Download and tried it, I feel good. Share it.

/ *

* 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 common. stream version.

*

* Version: 2.4

*

* /

#Region Using

Using system;

Using system.io;

Using system.threading;

Using system.Runtime.InteropServices;

Using system.componentmodel;

#ndregion 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 (m_hfile, out status) {

Throw new win32exception ();

}

Return (Status & MS_DSR_ON)> 0;

}

}

Public bool ring {

Get {

Uint status;

IF (! getcommodemstatus (m_hfile, out status) {

Throw new win32exception ();

}

Return (Status & MS_RING_ON)> 0;

}

}

Public bool rlsd {

Get {

Uint status;

IF (! getcommodemstatus (m_hfile, out status) {

Throw new win32exception ();

}

Return (status & ms_rlsd_on)> 0;

}

}

#ndregion property

#Region Constructionors

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 ocompletioncallback; asyncfscallback;

}

}

Public SerialStream (String Port): this (fileAccess.readwrite) {

Open (port);

}

Public SerialStream (String Port, FileAccess Access): this (access) {

Open (port);

}

#ndregion constructors

#Region Methods

Public void open (string port) {

IF (m_hfile! = INTPTR.ZERO) {

Throw new oException ("stream already opened.");

}

m_sport = port;

M_HFILE = CREATEFILE (port, (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, NUFL);

}

Public Override IasyncResult Beginread (Byte [] Buffer, Int Offset, Int Count, AsyncCallback Callback, Object State {

Gchandle gchbuffer = gchaldle.alloc (buffer, gchandletype.pinned);

SerialasyncResult Sar = New SerialAlasyncResult (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 = (Byte *) ((int) gchbuffer.addrofpinnedObject () offset; uint read = 0;

IF (readfile (M_HFile, Data, (UINT) Count, Out Read, NOV) {

SAR.M_BCOMPLETEDSYNCHRONOMSLY = true;

Return SAR;

}

ELSE IF (getLastError () == error_io_pending) {

Return SAR;

}

Else

Throw New Exception ("Unable to Initialize Read. Errorcode:" getLastError (). TOSTRING ());

}

}

Public IASYNCRESULT BeginWrite (byte [] buffer {

Return Beginwrite (Buffer, 0, Buffer.length, Null, NUFFER);

}

Public Override IasyncResult Beginwrite (Byte [] Buffer, Int Offset, Int Count, AsyncCallback Callback, Object State {

Gchandle gchbuffer = gchaldle.alloc (buffer, gchandletype.pinned);

SerialasyncResult Sar = New SerialAlasyncResult (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, (UINT) Count, Out Written, NOV) {

SAR.M_BCOMPLETEDSYNCHRONOMSLY = true;

Return SAR;

}

ELSE IF (getLastError () == error_io_pending) {

Return SAR;

}

Else

Throw New Exception ("Unable to Initialize Write. ErrorCode:" getLastError (). TOSTRING ());

}

}

Private int endoperation (isresult asyncRESult, Bool IsRead) {

SERIALASYNCRESULT SAR = (serialasyncResult) asyncResult;

IF (SAR.M_BISREAD! = Isread)

Throw New IOException ("INVALID Parameter: IASYNCRESULT IS NOT FROM A (IsRead?" ied ":" write ");

IF (sar.endotoperationcalled) {

THROW NEW IOEXCEPTION ("END" (IsRead? "r": "WRITE") "Called TWICE for the Same Operation.");}

Else {

SAR.M_BENDOPERATIONCALLED = TRUE;

}

While (! SAR.M_BCOMPLED) {

Sar.asyncwaithandle.waitone ();

}

SAR.Dispose ();

IF (SAR.M_NERRORCODE! = Error_Success && Sar.m_NerrorCode! = Error_Operation_aborted) {

Throw new oException ("Operation Finished with ErrorCode:" SAR.M_NERRORCODE);

}

Return sar.m_nreadwritten;

}

Public override int end (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 {(byte [] buffer, int offset, int count) {

Return Endread (Beginread (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 (Buffer, Offset, Count, Null, NULL);

}

Public int {(Byte [] buffer {

Return Endread (Beginread (Buffer, 0, Buffer.length, Null, Null);

}

Public int Write (byte [] buffer {

Return Endoperation (BeGinWrite (Buffer, 0, Buffer.length, Null, Null), False;

}

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 nongth) {

Throw New NotSupportedException ("SETLENGTH ISN '@");

}

Public Override Long Seek (long offset, seekorigin origin) {

Throw New NotSupportedException ("Seek isn't Supported on Serial Ports.");

}

Public void setTimeouts (int Readintervaltimeout,

Int ReadTotalTimeoutmultiplier,

Int ReadtotalTimeoutConstant,

Int WriteTotalTimeoutmultiplier,

INT WRITETOTIMEOUTCONSTANT) {

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 DataS, 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 == fluontrol.hardware)? 1U: 0U;

Dcb.foutx = dcb.finx = (flowcontrol == fluontrol.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 error ", nativeoverlapped * poounts) {

SerialasyncResult SAR = (SerialAlasyncResult) overlapped.unpack (PoverLapped) .asyncResult;

SAR.M_NERRORCODE = ErrorCode;

SAR.M_NREADWRITEN = (int) Numbytes;

SAR.M_BCOMPLETED = TRUE;

IF (SAR.CALLBACK! = NULL)

Sar.callback.invoke (sar);

Overlapped.free (Poverlapped);

}

#ndregion methods

#Region Constants

Private const uint purge_txabort = 0x0001; // kill the pending / current Writes to the CommM port.

Private const uint purge_rxabort = 0x0002; // kill the pending / current reads to the commit.

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 receivedprivate const uint set = 3; // set rts high

Private const uint crarts = 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.

Private const uint clrbreak = 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;

#ndregion constants

#Region enums

Public Enum Parity {None, ODD, Even, Mark, Space};

Public enum stopbits {one, oneandhalf, two};

Public enum flowcontrol {none, xonxoff, hardware};

#ndregion 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);}}

#ndregion property

#Region Methods

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 "

FDSRSENSITIVITY: 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:" BYTESIZE "/ R / N"

"Parity:" Parity "/ R / N"

"Stopbits:" StopBits "/ R / N"

"Xonchar:" Xonchar "/ r / n"

Xoffchar: " Xoffchar " / R / N "

"EOFCHAR:" EOFCHAR "/ R / N"

"Evtchar:" evtchar "/ r / n";

}

#ndregion methods

}

Private Class SerialAlasyncResult: 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_BCOMPLETEDSYNCHRONOSLY = FALSE;

INTERNAL UINT M_NERRORCODE = Error_Success;

PRIVATE OBJECT M_ASYNCOBJECT;

PRIVATE OBJECT M_STATEOBJECT;

Private manualReveTevent M_WaitHandle = New ManualRetevent (false);

Private asyncCallback m_callback;

PRIVATE GCHANDLE M_GCHBUFFER;

#ENDREGION Attributes

#Region Properties

INTERNAL BOOL endOperationcalled {get {return m_bendopertycalled;}}

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 MANUALRESEVENT WAITHANDLE {Get {Return M_WaitHandle;}} PUBLIC AsyncCallback Callback {get {return m_callback;}}

#ndregion property

#Region Constructionors

Public SerialAlasyncResult (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;

}

#ndregion constructors

#Region Methods

Public void dispose () {

m_WaitHandle.Close ();

m_gchbuffer.free ();

}

#ndregion methods

}

#ndregion classes

#Region Imports

[DLLIMPORT ("kernel32.dll", entrypoint = "createfilew", setLastError = true,

Charset = charset.unicode, exactspelling = true)]

Static 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 BOOLE (INTPTR HFILE, BYTE * LPBuffer, uint nnumberofbyteoread, out uint lpnumberofbytesread, nativeoverlapped * lpoverlapped);

[DLLIMPORT ("kernel32.dll", setLastError = true)]

Static Extern UNSAFE BOOL WRITEFILE (INTPTR HFILE, BYTE * LPBUFFER, UINT NNUMBYTESTOWRITE, OUT UINT LPNUMBYTESWRITEN, NATIVEOVERLAPPED * LPOVERLAPPED);

[DLLIMPORT ("kernel32.dll", setLastError = true)]

Static Extern Bool Setcommtimeouts (INTPTR HFILE, REF SerialTimeouts);

[DLLIMPORT ("kernel32.dll", setLastError = true)]

Static Extern Bool SetCommState (INTPTR HFILE, RECB 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);

#ndregion imports

}

[Structlayout (layoutkind.sequential)]

Public struct serialtimeouts {

#Region Attributes

Public int tentintervaltimeout;

Public int tenttotaltimeoutmultiplier;

Public int intTotalTimeoutConstant;

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;

}

#ndregion 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";

}

#ndregion 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 ("COM4"); // I called the cat

}

Catch (Exception E) {

Console.writeline ("Error:" E.MESSAGE);

Return;

}

// set port settings

SS.SETPORTSETTINGS (9600);

// set Timeout So Reads 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);

// Create The Thread Used to Read Responses

Thread responseReaderthread = new thread (New Threadstart (ReadResponseTHRead);

ResponseReaderthread.start ();

// read all returned Lines

For (;;) {

// r r c f

String command = console.readline ();

// Check for EXIT COMMAND

IF (Command.trim (). TOLOWER () == "exit") {

ResponseReaderthread.abort ();

Break;

}

// Write Command to Modem

SW.WRITELINE (Command);

Sw.flush ();

}

}

// main loop forreading responses

Static void readResponsethread () {

StreamReader SR = New StreamReader (SS, System.Text.Encoding.ascii);

Try {

For (;;) {

// read response from modem

String response = sr.readline ();

Console.writeline ("Response:" response);

}

Catch (threadabortexception) {

}

}

}

}

Once the program is run, you can instruct the device to operate. (Directive accepted by specific equipment)

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

New Post(0)