A simple asynchronous serial class

xiaoxiao2021-03-06  80

/ * A simple asynchronous serial class (Win32), this is my own use of serial classes

This asynchronous class only implements some simple features. Pay attention to the following: 1. The serial port-related parameters need to be set before Open, after opening, you cannot set up 2. Read serial port data takes query 3. Sending a data function to the serial port to perform a certain time, know that it is returned. 4. The default is no hardware handshake, if you want to shake hands, you need to call the function setflowctrl5. The serial portlet rate can be directly transmitted, such as 9600. If you have any questions, please contact me. Email: stevecrise@163.com9cbs on the account: SteveCrisewu Description: 1. Send data with a WRITE function until success is returned (if there is no other error) 2. Reading the data use read function, you can return it immediately, you need to call us. Of course, you can also use the message notification, you can create a thread to send your application to your application. 3. Get the line-control status function with the getLstatus function, as shown below, you can return the status of the lines of DSR, CTS, RI, and CDs. Value = getLstatus (); dsr = value & s_dsr; cts = value & s_cts; ri = value & s_ri; cd = value & s_cd; * / # include

/ * MODEM control setting * / # define c_dtr 0x01 # define c_rts 0x02

/ * MODEM line status * / # define s_cts 0x01 # define s_dsr 0x02 # define s_ri 0x04 # define s_cd 0x08

#define SiO_ok 0 # define sio_error -1

Class Casyncomm {public: // Constructor Casyncomm (); // Destructor Virtual ~ Casyncomm (); protected: // Serial number volatile int nport; // serial handle Volatile Handle Comhandle; // DCB structure DCB MYDCB; / / Input Output Buffer Size INT Inbufsize, OutbufSize; // Timeout Parameters Commtimeouts Cotimeout; // Overlapped Structure Overlapped Ro, Wo; // Initialization Function Void Init (); // Determine whether the serial port opens function bool isopen (); public: // Read a character from the serial port, return SiO_ERROR to the failure, otherwise a number INT getch () between 0-255; // Write a character to the serial port, return SiO_Error means a failure, SiO_ok means successfully writes Int Putch ( CHAR CH); // Read the LEN character from the serial port and put it in the buffer BUF, return to the SiO_ERROR to fail, otherwise return the actual number of characters Int read (char * buf, int LEN); / / write to the serial port Into the LEN character, returning to the SiO_Error indicates failure, otherwise returns the character number INT WRETE (CHAR * BUF, INT LEN); // turn off the serial port, Port is the serial number, the default Open 9600, N, 8, 1, no hardware handshake Virtual int open (int port); // set serial communication parameters int setsetting (int Baudrate, int Bytesize = 8, int parity = noparity, int stopbits = onestopbit); // Set hardware handshake int setflowctrl (); // read control line status int getLstatus (); // Set DTR state int setdtr (bool enable); // Set RTS status int sets (bool enable); // Set timeout time int SetTimeout (unsigned long ultimeout); // Settings Input Output Buffer Size Functions INT SE Tiosize (int isize, int size);}; CPP files are as follows: #include "asyncomm.h" // Initialization serial port casyncomm :: casync () {init ();

// Close the serial port and release the resource Casyncomm :: ~ Casyncomm () {close (); if (ro.hevent! = Invalid_handle_value) CloseHandle (RO. HEVENT);

IF (wo.hevent! = invalid_handle_value) CloseHandle (wo.hevent);

// Initialization function void casyncomm :: init () {memset (& mydcb, 0, sizeof (mydcb)); mydcb.dcblength = sizeof (mydcb); mydcb.baudrate = 9600; // communication rate Mydcb.bytesize = 8; / / Better mydcb.parity = noparity; // parity bit mydcb.stopbits = onestopbit; // Stop bit COMHANDLE = INVALID_HANDLE_VALUE; // Initialization is invalid handle InbufSize = 8192; // Default input buffer 8k outbufsize = 8192; // default output buffer is 8k memset (& coTimeOut, 0, sizeof (coTimeOut)); // define a timeout, default is 5 seconds coTimeOut.ReadIntervalTimeout = 0xFFFFFFFF; coTimeOut.ReadTotalTimeoutMultiplier = 0; coTimeOut.ReadTotalTimeoutConstant = 0; coTimeOut.WriteTotalTimeoutMultiplier = 0; cotimeout.writeTotalTimeoutConstant = 5000; MEMSET (& RO, 0, SIZEOF (RO)); // Read the overlapping structure MEMSET (& WO, 0, SIZEOF (WO)); // Write the overlapping structure RO. HEVENT = CREATEEVENT (NULL, TRUE, FALSE, NULL); wo.Hevent = CreateEvent (NULL, TRUE, FALSE, NULL);} // Returns True Indicates the serial port in the OPEN state BOOL CASYNCOMM :: Isopen () {Return (Comhandle! = INVALID_HANDLE_VALUE);

// Close the serial INT Casyncomm :: Close () {if (isopen ()) CloseHandle (Comhandle); Comhandle = INVALID_HANDLE_VALUE; RETURN SIO_OK;}

// Asynchronous Read Function // BUF provides the user with a temporary buffer, and LEN returns a SiO_Error to the buffer size / / function indicates that the read fails, the reason may be that the serial port is not open, etc. // function returns to non-negative numbers means successful reading Number Int Casyncomm :: Read (! Isopen ()) {if (! Isopen ()) Return SiO_ERROR; // Serial port does not open MEMSET (BUF, 0, LEN);

COMSTAT Stat; DWORD ERROR;

IF (ClearcomMerror (Comhandle, & Error, & Stat) && Error> 0) // Clear error {purgecomm (Comhandle, Purge_Rxabort | PURGE_RXCLEAR); RETURN SIO_ERROR;} if (! stat.cbinque) Return SiO_ERROR; // If there is no data in the buffer , Return directly

Unsigned long count = 0; len = min (int) (il - 1), (int) stat.cbinque); // Take the actual data and LEN minimum

If (! Readfile (Comhandle, BUF, LEN, & Count, & Ro)) // If the call fails, look at the error type, and Count contains read acquisition actual bytes {if (getLastError () == error_io_pending) {if (! GetoverlappedResult (COMHANDLE, & RO, & COUNT, FALSE) {IF (GetLaster_Incomplete) count = 0;}} else count = 0;}}}}}}}}} {buf [count] = '/ 0'; return Count;}}}} // Read a one-byte function from the buffer int Casyncomm :: getch () {if (! isopen ()) Return SiO_ERROR; / / The serial port is not open Comstat Stat; DWORD Error; Char Buf [2];

IF (ClearcomMerror (Comhandle, & Error, & Stat) && Error> 0) // Clear error {purgecomm (Comhandle, Purge_Rxabort | PURGE_RXCLEAR); RETURN SIO_ERROR;} if (! stat.cbinque) Return SiO_ERROR; // If there is no data in the buffer Return to unsigned long count = 0 directly;

If (! Readfile (Comhandle, BUF, 1, & Count, & RO)) // If the call fails, the error type is read, and the count contains reading actual bytes {if (getLastError () == Error_io_pending) {if (! GetoverlappedResult (ComHandle, & ro, & count, false)) {! if (GetLastError () = ERROR_IO_INCOMPLETE) count = 0;}} else count = 0;} if (count> 0) {return ((int) (buf [0]) } Return SiO_ERROR;

// The asynchronous write function // BUF is written to the data buffer, and the LEN returns the SiO_EO_EO_EO_EO_EO_EO_ERROR in the length, otherwise it returns the actual write to the number of bytes /// here, we take timeout mechanism, I know that the data successful writes returned, and the timeout can be set to set int Casyncomm :: Write (CHAR * BUF, INT LEN) {if (! Isopen ()) Return SiO_ERROR; // The serial port is not open

if (buf == NULL) return SIO_ERROR; DWORD error; if (ClearCommError (ComHandle, & error, NULL) && error> 0) // clear the error {PurgeComm (ComHandle, PURGE_TXABORT | PURGE_TXCLEAR);} unsigned long count = 0; unsigned Long value = 0; if (! Writefile (COMHANDLE, BUF, LEN, & COUNT, & WO)) // If the call failed, the error type {value = getLastError (); if (value! = error_io_pending) count = 0; / / Return Else {if (! GetOverlappedResult (COMHANDLE, & WO, & COUNT, TRUE)) {if (GetLasterror ()! = Error_io_incumplete) count = 0;}}} =}}}}} Return SiO_ERROR;} // Write a byte function to the buffer INT Casyncomm :: Putch (char CH) {if (! isopen ()) return sio_error; // Serial port does not open DWORD Error; Char BUF [2]; IF Clearcommrror (Comhandle, & Error, NULL) && error> 0) // Clear error {purgecomm (Comhandle, Purge_txabort | Purge_txclear);} BUF [0] = CH; buf [1] = 0; unsigned long count = 0; IF Writefile (COMHANDLE, BUF, 1, & Count, & WO)) // If the call fails, look at the error type {if (getLastError ()! = Error_io_pending) count = 0; Else {if (! GetoverlappedResu LT (COMHANDLE, & WO, & Count, True) {IF (get (GetLastError ()! = error_io_incumplete) count = 0;}}} f (count> 0) Return SiO_OK; RETURN SIO_ERROR;}

/ / The serial port opening function can only be specified that the port number can // For the serial port, the system is default 9600, n, 8, 1 and no hardware handshake // If you want to adjust the parameters, please open the serial port to call set setting, setTimeout , Setflowctrl, setiosize, etc. INT Casyncomm :: Open (int port) {if (port> 1024 || port <1) returnid sio_error; // illegal port number IF (isopen ()) close (); // If you have already opened , Then close nport = port; char STR [10]; if (ro.hevent == invalid_handle_value || wo.Hevent == invalid_handle_value) Return SiO_ERROR; STRCPY (STR, "COM"); LTOA (port, Str 3, 10); ComHandle = CreateFile (// open the serial str, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED, // overlap flag NULL); if (IsOpen (!)) return SIO_ERROR; // open failure, directly Back SetupComm (ComHandle, InbufSize, OutbufSize); // set the buffer size SetCommState (ComHandle, & MyDcb); // set up the communication parameters SetCommTimeouts (ComHandle, & coTimeOut); // set the timeout PurgeComm (ComHandle, PURGE_TXABORT | PURGE_RXABORT | PURGE_TXCLEAR | PURGE_RXCLEAR ); // Clear Error Return SiO_OK;} // Set communication parameters // Do not allow // baudRate to be set after the serial port is open, such as 9600, 19200, 38400, etc. : setSetting (int Baudrate, Int bytesi Ze, Int Parity, Int Stopbits {IF (ISOpen ()) Return SiO_ERROR; mydcb.baudrate = baudrate; mydcb.bytesize = bytesize; mydcb.parity = parity; mydcb.stopbits = stopbits; return sio_ok;}

// Setting timeout // Do not allow INT Casyncomm :: setTimeout (isopen ()) Return SiO_ERROR; Cotimeout.WritTotalTimeoutConstant = Ultimeout; Return SiOK;}

// Set the hardware handshake, traffic control // does not allow INT Casyncomm :: setFlowCtrl () {if (isopen ()) Return SiO_ERror; mydcb.foutxctsflow = true; iedcb.futxctsflow = true; iedcb.frtscontrol = true; return sio_ok }

// Get line status int Casyncomm :: getlstatus () {dWord dWEEVTMASK; int RET = 0; if (! Isopen ()) Return SiO_ERROR; IF (getcommmodemstatus (comb) = 0) {Return SiO_ERROR;} Ret = DWEVTMASK; RETURN RET;}

// Set the DTR line status int Casyncomm :: setdtr (bool enable) {if (! Isopen ()) Return SiO_ERROR; DWORD DATA = Clrdtr; if (enable) Data = setdtr; if (EscapeCommfunction (CoMHandle, Data)) RETURN SIO_OK RETURN SIO_ERROR;}

// Set RTS line status int Casyncomm :: setRTS (BOOL Enable) {if (! Isopen ()) Return SiO_ERROR; DWORD DATA = CLRTS; if (Enable) Data = setRTS; if (EscapeCommfunction (COMHANDLE, DATA) RETURN SIO_OK RETURN SIO_ERROR;}

// Setting the buffer parameter function // Do not allow int Casyncomm :: setiosize (ISOPEN ()) Return SiO_ERROR; if (ISIZE <= 0) Return SiO_ERROR; IF (Osize <= 0) Return SiO_ERROR; Inbufsize = isize; outbufsize = iSize; Return SiO_ok;}

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

New Post(0)