A practical serial communication class

zhaozj2021-02-17  57

Forget it, I have been registered on 9CBS for four years. I didn't expect that they still saved this document. Now organize the blog and put it it. This is a class that sends and receives data through the computer serial port. It is an immature class. Now I have not used it, but it uses the serial API operation. If you are very familiar, I want You can't take time again, the code is written as "Rubbsh" as you think, because this code has completed other features, not a separate module. In fact, such a code, I want to remove it, but I've been reluctant, it is a memory ...

// ******************************************************** ********************************** / / / ** FILE NAME: Saimio.h: Interface for the csaimio class. Author (Author): Wenjin Hu Hu Wenjin (EG. Saimen Hu) Version (Version): 1.0 Date: 2000.10.10 Description (Description): Read and write class for COM port, complete For the choice of COM port, the initialization of the COM port. Read and write to the COM port.

TYPEDEF STRUCT TAGIOINFO {Handle IDCOMDEV; BYTE BPORT; BOOL FCONNECTED, FXONXOFF; BYTE BBYTESIZE, BFLOWCTRL, BPARITY, BSTOPBITS; DWORD DWBAUDRATE; OVERLAPPED OSWRITE, OSREAD;} Ioinfo;

Configure the data structure of serial communication

HANDLE idComDev serial port to handle BYTE bPort serial number BOOL fConnected to whether the connection BYTE bByteSize number of bytes BYTE bFlowCtrl flow control BYTE bParity proof type BYTE bStopBits stop bit DWORD dwBaudRate baud OVERLAPPED osWrite, osRead literacy events and time ** /// ********************************************************* ******************************************** //

// Flow Control Flags Traffic Control Type //

#define fc_dtrdsr 0x01 # define fc_rtscts 0x02 # define fc_xonxoff 0x04 // ASCII Definitions traffic control character // # define ascii_xon 0x11 # define ascii_xoff 0x13

TYPEDEF STRUCT TAGIOINFO {Handle IDCOMDEV; BYTE BPORT; BOOL FCONNECTED, FXONXOFF; BYTE BBYTESIZE, BFLOWCTRL, BPARITY, BSTOPBITS; DWORD DWBAUDRATE; OVERLAPPED OSWRITE, OSREAD;} Ioinfo;

//

#if! defined (AFX_SAIMIO_H__A2648CC2_9DBF_11D4_96BD_E54AFA740DAA__INCLUDED _) #DINE AFX_SAIMIO_H__A2648CC2_9DBF_11D4_96BD_E54AFA740DAA__INCLUDED_

#if _MSC_VER> 1000 # prgma overce # endif //_MSC_VER> 1000

#define msg_new_iodata WM_USER 100

class CSaimIO: public CFile {public: CSaimIO (); virtual ~ CSaimIO (); public: void ResumeThread (); void SuspandThread (); BOOL ConnectCom (LPTSTR initStr); BOOL EndListern (); BOOL BeginListen (); void ClearIObuffer ( ); CString HexToStr (unsigned char * lpDataBuffer, int Total); void StrToHex (unsigned char * lpBuffer, int * Total); void InitaiseIO (); void SetIO (IOINFO SetIoInfo); BOOL DisConnect (); DWORD GetData (unsigned char * DataBuffer, DWORD DATALENGTH); BOOL Senddata (unsigned char * lpcommand, dword cmdlength); bool connect ();

IOINFO IOINFODATA;

protected:

// Listen to thread data private: Bool threadISRun (); handle hlistenthread; dword dwthreadid; // dword winapi listenread (lpvoid lpparameter);

// Monitor thread DWORD WINAPI LISTENTHREAD (LPVOID LPPARETER);

#ENDIF / /! Defined (AFX_SAIMIO_H__A2648CC2_9DBF_11D4_96BD_E54AFA740DAA__INCLUDED_)

// ******************************************************** ********************************** / / / ** FILE NAME: saimio.cpp: Implementation of the csaimio class. Author (Author): Wenjin Hu Hu Wenjin (EG. Saimen Hu) Version (Version): 1.0 Date: 2000.10.10 Description (Introduction): Read and write class for COM port, complete For the choice of COM port, the initialization of the COM port. Read and write to the COM port. Other (Other Remarks): Complete two cases of reading and writing to the serial port: 1. Computer communication 2. Computer and other device communication For both cases, pay attention to the DCB structure of the COM, the member is different. The effect of communication is different after childbirth, maybe it is very serious. Example:

If the value of the following two members is the following

DCB.fdtrControl = DTR_CONTROL_ENABLE;

Dcb.frtscontrol = RTS_Control_enable;

You cannot communicate between computers and other devices at this time.

Change to the following values ​​can be completed and other devices can be credited.

Dcb.fdtr introl = dtr_control_disable; dcb.frtscontrol = RTS_Control_enable;

FUNTION LIST: 1. Void initaiseio () is used to initialize the serial port IOINFO data structure to the default value 2. Void setio (IoInfo SetioInfo) calls the function to modify the IoInfo data structure, configure the serial port Description: This function is in Connect Previous call. 3. Bool connect () is used to connect the serial port, use the data structure in IOINFO, if you successfully return true; not successfully returning false; 4. Bool Disconnect () Close the connection to the serial port, successfully returns: true 5. Bool sendData (unsigned char * lpcommand, dword cmdlength) sends data to the serial port, the data length is cmdlength, lpcommand is a pointer to this command. 6. Bool getData (Unsigned Char * DataBuffer, INT DATALENGTH) Reads the data in the serial port buffer.

History: 1.Date: 2000.10.11 author: 胡 文晋 (Eg. Saim Hu) Modification: Add function: CString Csaimio :: Hextostr (unsigned char * lpdataBuffer) function: Convert the entry parameter unsigned char * dataBuffer to CSTRING string 2.Date: 2000.11.10 Author: Hu Wenjin (Eg. Saim Hu) ModiFcation:

** /// ****************************************************** ******************************** / / / / /

#include "stdafx.h" #include "saimio.h"

#ifdef _debug # undef this_filestatic char this_file [] = __ file __; # Define new debug_new # Endif

Extern Bool KillListenthread;

//// construction / destruction //

Csaimio :: csaimio () {initaiseio (); hlistenthread = null;}

CSAIMIO :: ~ csaimio () {

} // default initialize the serial void CSaimIO :: InitaiseIO () {IoInfoData.idComDev = 0; IoInfoData.bByteSize = 8; IoInfoData.fConnected = FALSE; IoInfoData.bPort = 1; IoInfoData.dwBaudRate = CBR_4800; IoInfoData.bFlowCtrl = FALSE; // FC_XONXOFF; // FC_RTSCTS; // FC_XONXOFF; IoInfoData.bParity = EVENPARITY; // MARKPARITY; SPACEPARITY; ODDPARITY; IoInfoData.bStopBits = ONESTOPBIT; // ONE5STOPBITS; TWOSTOPBITS IoInfoData.osWrite.Offset = 0; IoInfoData.osWrite .OffseThigh = 1024; IOINFODATA.OSREAD.OFFSET = 0; IOINFODATA.OSREAD.OFFSETHIGH = 1024; IOINFODATA.OSREAD.HEVENT = NULL; IOINFODATA.OSWRITE.HEVENT = null;}

// modify the serial data structures void CSaimIO :: SetIO (IOINFO SetIoInfo) {IoInfoData.idComDev = SetIoInfo.idComDev; IoInfoData.bByteSize = SetIoInfo.bByteSize; IoInfoData.fConnected = SetIoInfo.fConnected; IoInfoData.bPort = SetIoInfo.bPort; IoInfoData. dwBaudRate = SetIoInfo.dwBaudRate; IoInfoData.bFlowCtrl = SetIoInfo.bFlowCtrl; IoInfoData.bParity = SetIoInfo.bParity; IoInfoData.bStopBits = SetIoInfo.bStopBits; IoInfoData.osWrite.Offset = SetIoInfo.osWrite.Offset; IoInfoData.osWrite.OffsetHigh = SetIoInfo. osWrite.OffsetHigh; IoInfoData.osRead.Offset = SetIoInfo.osRead.Offset; IoInfoData.osRead.OffsetHigh = SetIoInfo.osRead.OffsetHigh;} // Connect IO before use it.// open string open BOOL CSaimIO :: Connect () { Bool FretVal; Byte Bset; DCB DCB; Char Szport [10];

MEMSET (Szport, 0, 10);

WSPRINTF (Szport, "COM% D:", IOINFODATA.BPORT);

IOINFODATA.IDCOMDEV = CREATEFILE (szport, generic_read | generic_write, 0, null, open_existing, file_attribute_normal | file_flag_overlapped, null);

IF (! IOINFODATA.IDCOMDEV) RETURN FALSE;

If (! setcommmask (Ioinfodata.idComdev, ev_rxflag)) // EV_RXCHAR) RETURN FALSE;

// Alloc The Buffer for Read and Write. IF (SetupComm (IOINFODATA.IDCOMDEV, 4096, 4096) == 0) RETURN FALSE;

// setup for overlapped I / o Commtimeouts CommTimeSouts;

CommTimeSouts.Readintervaltimeout = 100; CommTimeSouts.ReadtotaltimeoutMultiPlier = 20; commandsouts.ReadtotalTimeoutConstant = 1000;

CommTimeSOutMultiPlier = 2 * CBR_9600 / IOINFODATA.DWBAUDRATE; CommTimeSOuts.WritetAltimeoutConstant = 1000; setcommtimeouts (IoinFodata.idComDev, & CommTimeSouts);

// Initise the CoM port. Dcb.dcblength = sizeof (dcb);

Getcommstate (IOINFODATA.IDCOMDEV, & DCB);

Dcb.baudrate = IOINFODATA.DWBAUDRATE; DCB.BYTESIZE = IOINFODATA.BBYTESIZE; DCB.PARITY = IOINFODATA.BPARITY; DCB.STOPBITS = IOINFODATA.BSTOPBITS;

// setup Hardware Flow Control

Bset = (Byte) ((fc_rtscts & fc_dtrdsr)! = 0); dcb.foutxdsrflow = bset;

DCB.FDTRCONTROL = DTR_CONTROL_DISABLE; // Give a power supply, the new 485 does not need to provide dcb.frtscontrol = RTS_Control_enable;

bset = (byte) fc_rtscts; dcb.foutxctsflow = bset;

// setup Software Flow Control

bset = (byte) fc_xonxoff;

Dcb.finx = dcb.foutx = bset; dcb.xonchar = ascii_xon; dcb.xoffchar = ASCII_xoff; dcb.xonlim = 100; dcb.xofflim = 100;

// Other Various settings

Dcb.fbinary = true; dcb.fparity = 1; // ENALBLE PARITY

Fretval = setcommstate (IOINFODATA.IDCOMDEV, & DCB);

IF (FRETVAL! = false) IOINFODATA.FCONNECTED = true; Else Return FretVal

// Ceate I / O Event Used for overlapped reads / Writes IoinFodata.osread.hevent = CreateEvent (null, // no security true, // explicit reset req false); // init at reset null; // no name

IOINFODATA.OSREAD.HEVENT == NULL) {Return False;}

IoInfoData.osWrite.hEvent = CreateEvent (NULL, // no security TRUE, // explicit reset req FALSE, // initial event reset NULL); // no name if (IoInfoData.osWrite.hEvent == NULL) {CloseHandle (IoInfoData .osread.hevent; Return False;} // Clear Read and Send Io Buffer

IF (PurgeComm (IOINFODATA.IDCOMDEV, PURGE_RXCLEAR) == 0) Return False; if (purgecomm (IOINFODATA.IDCOMDEV, PURGE_TXCLEAR) == 0) Return False;

// set the dataset is ready to get data escapecommfunction (IOINFODATA.IDCOMDEV, SETDTR | SETRTS);

// set connection flag to TRUE

IOINFODATA.FCONNECTED = TRUE;

Return (True);

// Close IO WHEN EXIT The program :: disconnect () {== false Return True;

// stop the listen thread endlistern ();

// set connection flag to false Ioinfodata.fconnected = false;

// disable time notification and wait for thread // to halt setcommmask (IOINFODATA.IDCOMDEV, 0);

// Drop DTR EscapeCommfunction (IOINFODATA.IDCOMDEV, CLRDTR | CLRTS);

// purge any outstanding reads / writes and close device handle if (PurgeComm (IoInfoData.idComDev, PURGE_TXABORT | PURGE_RXABORT | PURGE_TXCLEAR | PURGE_RXCLEAR) == 0) return TRUE; CloseHandle (IoInfoData.osRead.hEvent); CloseHandle (IoInfoData.osWrite. HEVENT); RETURN CLOSEHANDLE (IOINFODATA.IDCOMDEV);

}

// Send the Datas.// write data to the serial BOOL CSaimIO :: SendData (unsigned char * lpCommand, DWORD dwBytesToWrite) {BOOL fWriteStat; DWORD dwBytesWritten; DWORD dwErrorFlags; DWORD dwError; DWORD dwBytesSent = 0; COMSTAT ComStat; char szError [ 128]; IOINFODATA.FCONNECTED == false) Return (false);

FWRITESTAT = Writefile (IOINFODATA.IDCOMDEV, LPCOMMAND, DWBYTESTOWRITE, & DWBYTESWRITEN, NULL); // & IOINFODATA.OSWRITE

IF (dwbyteswritten! = dwbytestowrite) Return False;

if (fWriteStat!) {if (GetLastError () == ERROR_IO_PENDING) {while {dwError = GetLastError () (GetOverlappedResult (IoInfoData.idComDev, & IoInfoData.osWrite, & dwBytesWritten, TRUE)!); if (dwError == ERROR_IO_INCOMPLETE) {/ / Normal Result if not finished dwbytessent = dwbyteswritten; continue;} else {// an error Occurred, Try to Recover WSPrintf (Szerror, "To serial port, error code:% u", dwerror);

MessageBox (NULL, SZERROR, "Send Data Error", MB_ICONEXCLAMATION;

Clearcommerror (IOINFODATA.IDCOMDEV, & DWERROLLAGS, & Comstat); Break;}}} else {// Some Other Error Occurred Clearcommeror (IOINFODATA.IDCOMDEV, & DWERRORFLAGS, & Comstat);

IF (dwerrorflags> 0) {WSPrintf (Szerror, "send data error to serial port, error code:% u", dwerrorflags;

MessageBox (NULL, SZERROR, "Send Data Error", MB_ICONEXCLAMATION;

Return (false);}}}}} // end of senddata ()

// Read the Datas.// data is read from the serial port DWORD CSaimIO :: GetData (unsigned char * DataBuffer, DWORD DataLength) {BOOL fReadStat; COMSTAT ComStat; DWORD dwErrorFlags; DWORD dwLength = DataLength; DWORD dwError; char szError [128 ]; If (IOINFODATA.FCONNECTED == false) Return (false);

// setcommmask (IOINFODATA.IDCOMDEV, EV_RXCHAR); // Set to generate an interrupt when receiving the first character

// unsigned long dwflg; // Waitcommevent (IOINFODATA.IDCOMDEV, & DWFLG, & IOINFODATA.OSREAD); // Waiting for the first character event to occur // if ((DWFLG & (EV_RXFLAG | EV_RXCHAR)) == (EV_RXFLAG | Ev_rxchar)) {// only try to read number of bytes in queue clearcommerror (IOINFODATA.IDCOMDEV, & DWERRORFLAGS, & COMSTAT); DWLENGTH = min (128, comstat.cbinque);

if (dwLength> 0) {fReadStat = ReadFile (IoInfoData.idComDev, DataBuffer, dwLength, & dwLength, & IoInfoData.osRead); if (! fReadStat) {if (GetLastError () == ERROR_IO_PENDING) {// We have to wait for read to complete. // This function will timeout according to the // CommTimeOuts.ReadTotalTimeoutConstant variable // Every time it times out, check for port errors while (! GetOverlappedResult (IoInfoData.idComDev, & IoInfoData.osRead, & dwLength, TRUE)) {dwError = GetLastError (); if (dwerror == error_io_incumplete) // Normal Result if not finished continue; Else {// an Error Occurred, Try To Recover Wsprintf (Szerror, "Send data error, error code:% u", Dwerror); MessageBox (NULL, SZERROR, "Send Data Error", MB_ICONEXCLAMATION;

ClearcomMerror (IOINFODATA.IDCOMDEV, & DWERRORFLAGS, & Comst); if (dwerrorflags> 0) {WSPrintf (Szerror, "sending data error to serial port, error code:% u", dwerror);

MessageBox (NULL, szError, "data transmission error", MB_ICONEXCLAMATION);} break;}}} else {// some other error occurred dwLength = 0; ClearCommError (IoInfoData.idComDev, & dwErrorFlags, & ComStat); if (dwErrorFlags> 0) {WSPRINTF (Szerror, "sending data error to the serial port, error code:% u", dwerrorflags;

MessageBox (NULL, SZERROR, "Send Data Error, MB_ICONEXCLAMATION);}}}}}}}}}}}}}}}

// Convert the string to hex data void csaimio :: stratohex (unsigned char * lpbuffer, int * total) {if ((* total)% 2)! = 0) {strat ((char *) lpbuffer , "0"); (* TOTAL) ;}

Unsigned char HEXBUFFER [1024];

MEMSET (HEXBUFFER, '/ 0', 1024);

INT i; for (i = 0; i <(* total); i ) {IF (lpbuffer [i]> 0x39) lpbuffer [i] - = 0x37; else lpbuffer [i] - = 0x30;}

For (i = 0; i <(* total); i = 2) {HEXBUFFER [I / 2] = lpbuffer [i]; hexbuffer [I / 2] << = 4;

HEXBUFFER [I / 2] | = lpbuffer [i 1];

Memcpy (lpbuffer, hexbuffer, (* total) / 2);

// Translate hexadecimal data into string cstring csaimio :: hextostr (unsigned char * lpdatabuffer, int total) {cstract returnstr; char Onenumber [5];

Returnstr.empty (); MEMSET (OneNumber, 0, 5);

For (int i = 0; i

IF (Strlen (OneNumber) <2) {OneNumber [2] = OneNumber [1]; OneNumber [1] = OneNumber [0]; OneNumber [0] = '0';} returnstr = Onenumber; Returnstr = ","; memset (OneNumber, 0,5);} return ReturnStr;} // serial buffer empty void CSaimIO :: ClearIObuffer () {if (PurgeComm (IoInfoData.idComDev, PURGE_RXCLEAR) == 0) return; if (PurgeComm (IoInfoData.idComDev , Purge_txclear) == 0) return;}

// Start the serial port listener BOOL CSAIMIO :: BeGinListen () {if (IOINFODATA.FCONNECTED == false) returnial false; // Judgment thread is still still running if (threadisrun ()) return true;

hListenThread = CreateThread ((LPSECURITY_ATTRIBUTES) NULL, 0, (LPTHREAD_START_ROUTINE) ListenThread, (LPVOID) & IoInfoData, 0, & dwThreadID); if (hListenThread == NULL) {DWORD dwError = GetLastError (); CString Msg; Msg.Format ( "Error Code:% D ", DWERROR); AFXMessageBox (MSG);

Return false;} else {return true;}}

// Stop the serial port monitor bool csaimio :: endListern () {if (IOINFODATA.FCONNECTED == false) Return True;

IF (hlistenthread == null) Return True;

// Judgment the thread is still still running if (! Threadisrun ()) Return TRUE;

KillListenThread = true; sleep (100);

// If the thread is still running an exception termination listening thread if (! TerminateTHREAD (HListentHread, 0)) {dword dwerror = getLastError (); cstring msg; msg.format ("Error Code:% D", DWERROR); afxMessageBox (MSG );

Else Return CloseHandle (HLISTENTHREAD);

} // Open the serial port, for example: COM1, 9600, N, 8, 1BOOL CSAIMIO :: Connectcom (LPTSTSTSTSTR) {char strTemp [10]; int i = 3; int J = 0;

// Read the serial number while (INITSTR [I]! = ',' && intendstr [i]! = '/ 0') {straTemp [j] = initstr [i]; i ; j ; if (j> 3) Return False;} stratemp [j] = '/ 0'; IOINFODATA.BPORT = ATOI (Strtemp);

// Read the baud rate I ; j = 0; while (INITSTR [I]! = ',' && intendstr [i]! = '/ 0') {strTemp [J] = INITSTER [i]; i ; J ; If (j> 6) Return False;} strTemp [J] = '/ 0';

if (strstr (strTemp, "256000") = NULL!) {IoInfoData.dwBaudRate = CBR_256000;} else if (! strstr (strTemp, "128000") = NULL) {IoInfoData.dwBaudRate = CBR_128000;} else if (strstr ( strTemp, "115200") = NULL) {IoInfoData.dwBaudRate = CBR_115200;}! else if (strstr (strTemp, "57600") = NULL) {IoInfoData.dwBaudRate = CBR_57600;}! else if (strstr (strTemp, "56000 ")! = NULL) {IOINFODATA.DWBAUDRATE = CBR_56000;} else IF (strstr (strTemp," 38400 ")! = Null) {IOINFODATA.DWBAUDRATE = CBR_38400;} else IF (strstr (strTemtr (str (strtemp," 19200 ")! = NULL) {IoInfoData.dwBaudRate = CBR_19200;}! else if (strstr (strTemp, "14400") = NULL) {IoInfoData.dwBaudRate = CBR_14400;}! else if (strstr (strTemp, "9600") = NULL) {IoInfoData .dwBaudRate = CBR_9600;} else if (strstr (strTemp, "4800") = NULL!) {IoInfoData.dwBaudRate = CBR_4800;} else if (! strstr (strTemp, "2400") = NULL) {IoInfoData.dwBaudRate = CBR_2400 ELSE IF (strstr (strTemp, "1200")! = Null) {IOINFODATA.DWBAUDRATE = CBR_1200;} else} (strstr (strTemt (strTemp, "600")! = Nu LL) {IOINFODATA.DWBAUDRATE = CBR_600;} else IF (strstr (strTemp, "300")! = Null) {IOINFODATA.DWBAUDRATE = CBR_300;} Else IF (strstr (strTemp, "110")! = Null) {IONFODATA .dwbaudrate = CBR_110;} else {IOINFODATA.DWBAUDRATE = CBR_9600;} // Read the check method i ; strTemp [0] = INITSTR [I]; strTemp [1] = '/ 0';

IF (StRTEMP, "N")! = null) {IOINFODATA.BPARITY = NOPARITY;} else if (StRTEMP, "E")! = null) {IOINFODATA.BPARITY = EVENPARITY;} else IF Strtemp, "O")! = null) {IOINFODATA.BPARITY = ODDPARITY;} else if (strTemtr (strstr (strTemp, "m")! = null) {IOINFODATA.BPARITY = MarkParity;} else if (str (strTemp, "s ")! = Null) {IOINFODATA.BPARITY = SpaceParity;} else {IOINFODATA.BPARITY = Noparity;} // read the number of data bits i ; i ; strTemp [0] = initstr [i]; IOINFODATA.BBYTESIZE = Atoi ( Strtemp); // Read the stop bit I ; j = -1; do {i ; J ; strTemp [j] = initstr [i];} while (INITSTR [i] == '/ 0');

IF (StRTEMP, "1")! = null) {IOINFODATA.BSTOPBIPBITS = onestopbit;} else IF (strTemtr (strTemtr (strTemp, "2")! = null) {IOINFODATA.BSTOPBITS = twostopbits;} else IF Strtemp, "1.5")! = null) {IOINFODATA.BSTOPBITS = one5stopbits;} else {IOINFODATA.BSTOPBITS = onestopbit;}

Return connect ();

// determines whether the thread is still running BOOL CSaimIO :: ThreadIsRun () {DWORD lpExitCode; GetExitCodeThread (hListenThread, & lpExitCode); if (lpExitCode == STILL_ACTIVE) {return TRUE;} else {return FALSE;}

} // Hanging thread void csaimio :: susndthread () {:: susndthread (hlistenthread);} // Wake up thread void csaimio :: resumeth () {:: resumethread (hlistenthread);}

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

New Post(0)