Realize serial communication with Win32 API

zhaozj2021-02-16  47

The serial port is a data transmission channel between the commonly used computer and the external serial device. Since serial communication is convenient, it is widely used. We can use the communication function provided by the Windows API to write high portability serial communication programs.

In Win16, you can open, close, and read and write serial ports using functions such as OpenComm, CloseComm, and WriteComm. However, in Win32, serial port and other communication devices are used as the function of the operation file as the function file as the operation file, the serial port and other communication devices is used as a file processing, the serial port opening, closing, and reading and writing. The serial port can be opened via the CreateFile function, and the serial port is set by the Closefile function, and the serial port is set by the CommProp, DCB structure, getcommproperties, setcommproperties, getcommstate, and setcommstate, etc., read and write the serial port through the function readfile and Writfile.

VC 6.0 is one of the mainstream languages ​​developed by Windows applications, which has a good graphics design interface and supports object-oriented programming methods. This article combines how an example introduces how to use Win32 API to implement serial communication programs in VC 6.0.

Realization principle

The examples of this paper come from a cement delivery system, in the system, need to be incorporated into the computer through the total number of hungenes collected by the total amount sensor so that the system makes corresponding processing. This requires serial communication to complete the delivery of the data.

For serial communication devices, Win32 API supports two I / O operations for synchronous and asynchronous. The programming of the synchronous operation mode is relatively simple, but the I / O operation function cannot return before the I / O operation end, which will hang the call thread until the I / O operation ends. Asynchronous operation is relatively complex, but it allows time-consuming I / O operations in the background, not hanging the calling thread, which is quite effective in improving the response speed of the calling thread in the case of large data volume. . Asynchronous operations are particularly suitable for both multiple serial devices for I / O operations and simultaneously read / write a serial device. The basic idea of ​​these two operational methods is similar, which gives a specific communication program design for synchronous operations, while briefly explaining how to achieve asynchronous I / O operations.

Initialization of serial equipment

The initialization of serial devices is implemented using the CreateFile function. This function obtains a serial device handle and communicates parameter settings, including setting output / reception buffer size, timeout control, and event monitoring.

// Serial device handle;

Handle hCOMDEV = 0;

// Serial port open sign;

Bool bopen = false;

// Thread synchronization event handle;

Handle HEVENT = 0;

Bool setupsyncom ()

{

DCB DCB;

CommTIMEOUTS TIMEOUTS;

// The device has been opened

IF (Bopen) Return False;

// Open COM1

IF ((hCOMDEV = CREATEFILE ("COM1", GenericRead | genericwrite, 0, null, open eexisting, fileattribute-normal, null) ==

INVALID-Handle-Value

Return False;

/ / Set timeout control

Setcommtimeouts; HCOMDEV, & TIMEOUTS;

/ / Set the size of the receiving buffer and output buffer

SetupComm (HCOMDEV, 1024, 512);

/ / Get the value of the default DCB structure

GetcommState (HCOMDEV, & DCB);

// Set the baud rate is 9600 bps

Dcb.baudrate = CBR9600;

/ / Set no parity check

Dcb.fparity = noparity;

/ / Set the data bit is 8

DCB.BYTESIZE = 8;

// Set a stop bit dcb.stopbits = onestopbit;

/ / Monitor the incorrect of the serial port and receive two events of characters

Setcommmask (HCOMDEV, EVERR | EVRXCHAR);

/ / Set the serial device control parameters

SetCommState (HCOMDEV, & DCB);

// The device has been opened

Bopen = True;

// Create an incident of manual reset, no signal

HEVENT = CREATEEVENT (NULL, FALSE, FALSE,

"Watchevent");

// Create an event monitoring thread to monitor the serial event

AfxBeginThread (CommwatchProc, PParam);

}

When setting the parameters of the serial DCB structure, you do not have to set each value. First read the DCB default parameter settings, and then modify the necessary parameters, and other parameters can be used. Since the synchronization I / O operation is performed on the serial port, the waitCommEvent function will not return unless the event is specified. At the end of the serial device initialized, you must establish a separate monitoring thread to monitor the serial port event so as not to hang the current call thread, where the PPARAM can be a window pointer that processes the event.

If you want to perform an asynchronous I / O operation, when you open the device handle, the 6th parameter of CreateFile should add the file -flag -overlapped flag.

Data transmission

Data transmission utilizes the WriteFile function. For synchronous I / O operations, its last parameter can be null; while the asynchronous I / O operation, its last parameter must be a pointer to the Overlapped structure, to obtain the current operation status through the Overlapped structure.

Bool WriteComm (LPCVOID LPSNDBuffer, DWORD

DWBYTESTOWRITE)

{// lpsndbuffer is the sending data buffer pointer,

DWBYTESTOWRITE is the length of the byte that will be sent.

// The device has been opened

Bool bwritestate;

/ / The number of bytes actually sent

DWORD DWBYTESWRITTEN

// The device is not open

IF (! Bopen) Return False;

BWRITESTATE = Writefile (HCOMDEV, LPSNDBuffer,

Dwbytestowrite, & dwbyteswritten, null;

IF (! bWriteState || dwbytestowrite! = dwbyteswritten)

//Failed to send

Return False;

Else

//Sent successfully

Return True;

}

Data reception

The task of receiving data is completed by the ReadFile function. This function reads data from the serial port receiving buffer, before reading the data, first obtain the number of bytes in the receiving buffer with the ClearcomMerror function. When receiving data, the difference between synchronization and asynchronous reading is the same as sending data.

DWord Readcomm (LPVOID LPINBUFFER, DWORD

DWBYTESTOREAD)

{// lpinbuffer is a buffer pointer to receive data, DWBYTESTOREAD is the data length that is ready to read (byte)

// Serial device status structure

COMSTAT COMSTAT;

DWORD DWBYTESREAD, DWERRORFLAGS;

// The device is not open

IF (! Bopen) Return 0;

// Read the current state of the serial device

Clearcommorror (HCOMDEV, & DWERRORFLAGS, & Comstat);

/ / The length of the data that should be read

DWBYTESREAD = min (dwbytestoread, comstat.cbinque);

IF (DWBYTESREAD> 0)

// read data

IF (! Readfile (HCOMDEV, LPINBUFFER, DWBYTESREAD, & DWBYTESREAD, NULL) DWBYTESREAD = 0;

Return DwbytesRead;

}

Event monitoring thread

The event monitoring thread monitors the serial port event. When the monitoring event occurs, the monitoring thread can send this event or registration to the window class (specified by the PPAram) to the event.

Uint CommWatchProc (LPVOID PPARAM)

{DWORD DWEVENTMASK = 0; // Event incident;

While (Bopen)

{// Waiting for the event of monitoring

Waitcommevent (HCOMDEV, & DWEVENTMASK,

NULL);

IF (DWEventmask & EvRXCHAR) ==

EvRxChar)

After ... // After receiving the character event, you can register this message to the window class with PPARAM.

IF (DWEventmask & Everr) == EVERROR)

... // Processing when an error occurs

}

STEVENT (HEVENT);

// signal, indicate the end of the monitoring thread

Return 0;

}

Close serial device

When the entire application ends or no longer uses a serial device, the serial device should be turned off, including the cancel event monitoring, open the device to False to end, clear the event monitoring thread, clear the send / receive buffer, and shut down the device Handle.

Void CloseSyncomm ()

{

IF (! bopen) return;

// End the event monitoring thread

Bopen = false;

Setcommmask (hCOMDEV, 0);

/ / Cancel event monitoring, at which time Waitcommmevent in the monitoring thread will return

WaitforsingleObject (HEVENT, INFINITE);

// Waiting for the surveillance thread to end

CloseHandle (HEVENT); // Close the event handle

/ / Stop sending and receiving data, and clears the sending and receiving buffer

PurgeComm (HCOMDEV, PURGE-TXABORT |

Purge-RXAbort | Purge-Txclear |

Purgerxclear;

// Close the device handle

CloseHandle (HCOMDEV);

}

Small knot

The basic idea of ​​using the Win32 API design serial communication is given, and the serial communication program for this synchronization I / O operation can be used to perform asynchronous I / O operations. In practical applications, we can add these serial communication functions and member variables to an existing CWND class or derived class to implement serial communication, or design a new serial communication class to include these member functions. And member variables. In summary, the Win32 API can design a serial communication program that meets a variety of needs.

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

New Post(0)