Serial port is a commonly used computer and external serial device data transmission channel, because the serial communication is convenient and easy, so the application is widespread. We can use the communication functions provided by the Windows API to write a highly portable serial communication program.
In Win16, you can use functions such as Opencomm, Closecomm, and Writecomm to open, close, and read and write serial ports. But in the Win32, the serial port and other communication devices are treated as file, the serial port is opened, closed and read and write the same API function as the operation file function. Through the CreateFile function to open the serial port, through the CloseFile function to close the serial port, through the Commprop, DCB structure, getcommproperties, Setcommproperties, Getcommstate and SetCommState function set serial port state, through function ReadFile and writfile read and write serial port.
VC + + 6.0 is one of the most popular languages in Windows application development, it has a good graphic design interface and supports object-oriented program design methods. This paper describes how to use the Win32 API to realize serial communication program in VC + + 6.0 with an example.
Implementation principle
The example of this paper comes from a cement delivery system, in which the warehouse weights collected through the total sensor need to be passed into the computer so that the system can make corresponding processing. This requires the use of serial communication to complete the collection of data transfer work.
For serial communication devices, the Win32 API supports both synchronous and asynchronous I/O operations. The design of the synchronous operation is relatively simple, but the I/O operation function cannot return until the I/O operation is finished, which suspends the calling thread until I/O operation is finished. Asynchronous operations are relatively complex, but it allows time-consuming I/O operations to be done in the background and does not suspend the calling thread, which is quite effective for improving the response speed of the calling thread in the case of large data traffic. Asynchronous operation is particularly suitable for simultaneous I/O operations on multiple serial devices and simultaneous read/write operations on a serial device. The basic idea of the two modes of operation is similar, in this paper, we will give the specific communication program design for the synchronous operation, and explain how to implement the asynchronous I/O operation.
Initialization of serial devices
The initialization of the serial device is realized by using the CreateFile function. The function obtains the serial device handle and communicates parameter settings to it, including setting the output/Receive buffer size, timeout control, and event monitoring.
serial device handle;
HANDLE hcomdev=0;
Serial port to open the logo;
BOOL Bopen=false;
Thread synchronization event handle;
HANDLE hevent=0;
BOOL setupsyncom ()
{
DCB DCB;
Commtimeouts timeouts;
Device is turned on
if (bopen) return FALSE;
Open COM1
if (Hcomdev=createfile ("COM1", genericread| genericwrite,0,null,openexisting,fileattributenormal,null)) = =
Invalidhandlevalue)
return FALSE;
Set Timeout control
SetCommTimeouts (hcomdev,&timeouts);
Set the size of the receive buffer and output buffer
Setupcomm (hcomdev,1024,512);
Gets the value of the default DCB structure
Getcommstate (HCOMDEV,&DCB);
Set baud rate to 9600 bps
Dcb. baudrate=cbr9600;
Set no parity
dcb.fparity=noparity;
Set data bits to 8
Dcb. bytesize=8;
Set a stop bit
Dcb. Stopbits=onestopbit;
Monitor serial port errors and receive characters in both events
Setcommmask (hcomdev,everr| Evrxchar);
Setting serial Device Control parameters
SetCommState (HCOMDEV,&DCB);
Device is turned on
Bopen=true;
Create manually reset, not signaled events
Hevent=createevent (Null,false,false,
"Watchevent");
Create an event monitor thread to monitor serial port events
AfxBeginThread (Commwatchproc,pparam);
}
When you set parameters for a serial port DCB structure, you do not have to set each value. First read out DCB default parameter settings, and then only modify the necessary parameters, the other parameters are the default values. Because a synchronous I/O operation is performed on the serial port, the Waitcommevent function does not return unless a monitored event is specified to occur. At the end of the serial device initialization, a separate monitoring thread is set up to monitor the serial event to avoid suspending the current calling thread, where pparam can be a window class pointer that handles the event.
If an asynchronous I/O operation is to be performed, the 6th parameter of the CreateFile should increase the FILEFLAGOVERLAPPED flag when the device handle is opened.
Data send
Data sending is implemented using the WriteFile function. For synchronous I/O operations, its last argument is nullable, and for asynchronous I/O operations, its last parameter must be a pointer to the overlapped structure, and the current operation state is obtained through the overlapped structure.
BOOL Writecomm (lpcvoid Lpsndbuffer,dword
Dwbytestowrite)
{//lpsndbuffer for sending data buffer pointers,
Dwbytestowrite the length of bytes to be sent
Device is turned on
BOOL bwritestate;
The actual number of bytes sent
DWORD dwBytesWritten;
Device not open
if (!bopen) return FALSE;
Bwritestate=writefile (Hcomdev,lpsndbuffer,
Dwbytestowrite,&dwbyteswritten,null);
if (!bwritestate | | dwbytestowrite!=dwbyteswritten)
Send failed
return FALSE;
Else
Send success
return TRUE;
}
Data reception
The task of receiving data is completed by the ReadFile function. This function reads the data from the receiving buffer of the serial port before reading the data, using the Clearcommerror function to obtain the number of bytes in the receive buffer. When receiving data, the difference between synchronous and asynchronous reads is the same as sending data.
DWORD Readcomm (LPVOID Lpinbuffer,dword
Dwbytestoread)
{//lpinbuffer is the buffer pointer to receive data, dwbytestoread the length of the data to be read (bytes)
Serial Device State structure
Comstat Comstat;
DWORD Dwbytesread,dwerrorflags;
Device not open
if (!bopen) return 0;
Read the current status of the serial device
Clearcommerror (Hcomdev,&dwerrorflags,&comstat);
The length of data that should be read
Dwbytesread=min (Dwbytestoread,comstat.cbinque);
if (dwbytesread>0)
Reading data
if (! ReadFile (Hcomdev,lpinbuffer,dwbytesread,&dwbytesread,null))
Dwbytesread=0;
return dwbytesread;
}
Event Monitoring Threads
Event Monitoring threads monitor serial events and, when monitored events occur, the monitoring thread can send this event (SendMessage) or enlistment (PostMessage) to the window class (specified by Pparam) that handles the event.
UINT Commwatchproc (LPVOID pparam)
{DWORD dweventmask=0;//events occurring;
while (bopen)
{//waiting for monitored events to occur
Waitcommevent (Hcomdev, &dweventmask,
NULL);
if ((Dweventmask & evrxchar) = =
Evrxchar)
...//After receiving a character event, you can register this message with a specified window class in Pparam
if (Dweventmask & Everr) ==everror)
...//handling when an error occurs
}
SetEvent (hevent);
Signals the end of the monitoring thread
return 0;
}
Turn off serial devices
When the entire application finishes or no longer uses the serial device, the serial device should be turned off, including event monitoring cancellation, bopen the device open flag to false so that the event monitoring thread ends, clears the Send/receive buffer, and closes the device handle.
void Closesyncomm ()
{
if (!bopen) return;
End Event Monitor Thread
Bopen=false;