1. API description
In the WIN32 API, the serial port is accessed using file mode, and its API is basically consistent with the API of the file operation.
Open the serial port
The API function for opening the serial port in Win32 is CreateFile, and its prototype is:
HANDLE CreateFile ( LPCTSTR lpFileName,//serial logical name to be opened, such as COM1 or COM2 DWORD dwaccess,//Specifies the type of serial access that can be read, write, or both DWORD dwShareMode,//Specify shared properties, this parameter must be set to 0 because the serial port cannot be shared Lpsecurity_attributes LPSA,//reference security attribute structure, default value is null DWORD dwcreate,//Create flag, for serial operation This parameter must be set to open EXISTING A DWORD dwattrsandflags,//Property description that specifies whether the serial port can be asynchronously operated, File_flag_overlapped: can use asynchronous I/O HANDLE hTemplateFile//Handle to the template file, this parameter must be set to NULL for the serial port ); |
For example, the following program is used to open the serial port COM1 in synchronous read and write mode:
HANDLE HCom; DWORD dwerror; Hcon = CreateFile ("COM1", Generic_read | Generic_write, 0, NULL, open_existing, 0, NULL); if (HCom = = (HANDLE) 0xFFFFFFFF) { dwerror = GetLastError (); MessageBox (dwerror); } |
For the Dwattrsandflags parameter and the origin of the FILE_FLAG_OVERLAPPED flag, it can be explained as follows: The Windows file operations are divided into synchronous I/O and overlapped I/O (Overlapped I/O), in the synchronous I/O mode, The API blocks until the operation is complete (in multithreaded mode, although it does not block the main thread, but still blocks the listener), and in the overlapped I/O mode, the API returns immediately and the operation is done in the background to avoid thread blocking. Overlapping I/O is very flexible, it can also be blocked (for example, we can set to read to a data to proceed to the next operation). If the API for the I/O operation is returned without completing the operation, we can go back by calling the GetOverlappedResult () function to block until the I/O operation is complete.
Configuring the serial port
The configuration of the serial port is achieved by changing the value of the member variable of the device control block DCB, and the size of the receive buffer and the send buffer can be set by the Setupcomm function.
The DCB struct is defined as:
typedef struct _DCB {//DCB DWORD dcblength; sizeof (DCB) DWORD baudrate; Current baud rate DWORD fbinary:1; Binary mode, no EOF check DWORD fparity:1; Enable parity checking DWORD foutxctsflow:1; CTS Output Flow Control DWORD foutxdsrflow:1; DSR Output Flow Control DWORD Fdtrcontrol:2; DTR Flow control type DWORD fdsrsensitivity:1; DSR Sensitivity DWORD ftxcontinueonxoff:1; XOFF continues Tx DWORD foutx:1; Xon/xoff Out Flow control DWORD finx:1; Xon/xoff in Flow control DWORD ferrorchar:1; Enable error replacement DWORD fnull:1; Enable NULL stripping DWORD Frtscontrol:2; RTS Flow Control DWORD fabortonerror:1; Abort reads/writes On Error DWORD fdummy2:17; Reserved WORD wreserved; Not currently used WORD Xonlim; Transmit XON threshold WORD Xofflim; Transmit XOFF threshold BYTE ByteSize; Number of Bits/byte, 4-8 BYTE Parity; 0-4=no,odd,even,mark,space BYTE stopbits; 0,1,2 = 1, 1.5, 2 Char XonChar; Tx and Rx XON character Char XoffChar; Tx and Rx XOFF character Char ErrorChar; Error replacement character Char EofChar; End of input character Char Evtchar; Received event character WORD wReserved1; Reserved Do not use } DCB; The prototype of the Setupcomm function is: BOOL Setupcomm ( HANDLE hfile,//HANDLE to communications device DWORD Dwinqueue,//size of input buffer DWORD dwoutqueue//size of output buffer ); |
The following programs set the serial port to: Baud rate is 9600, the number of data bits is 7 bits, the stop bit is 2 bits, parity, receive buffer and send buffer size are 1024 bytes, and finally use the PurgeComm function to terminate all background read and write operations and empty the receive buffer and send buffer:
DCB DCB; Dcb. BaudRate = 9600; Baud rate is 9600 Dcb. ByteSize = 7; The number of data bits is 7 bits Dcb. Parity = evenparity; Even check Dcb. StopBits = 2; Two Stop bits Dcb.fbinary = TRUE; dcb.fparity = TRUE; if (! SetCommState (HCom, &DCB)) { MessageBox ("Error in serial port settings!"); } Setupcomm (HCom, 1024, 1024); PurgeComm (HCom, Purce_txabort | Purge_rxabort | Purge_txclear | Purge_rxclear); |
Timeout settings
The timeout setting is implemented by changing the value of the member variable of the commtimeouts struct, and the Commtimeouts prototype is:
typedef struct _COMMTIMEOUTS { DWORD ReadIntervalTimeout; Defines the maximum time interval, in milliseconds, that two characters arrive: When a character is read, the ReadIntervalTimeout is exceeded and the next character is not read, it Timeout occurred DWORD ReadTotalTimeoutMultiplier; DWORD ReadTotalTimeoutConstant; The relationships that are met at each time are as follows: Readtotaltimeout = readtotaltimeoutmultiplier* Bytestoread + readtotaltimeoutconstant DWORD WriteTotalTimeoutMultiplier; DWORD writetotaltimeoutconstant; } commtimeouts, *lpcommtimeouts; |
The function that sets the timeout is setcommtimeouts, and the pointer that receives COMMTIMEOUTS in its prototype is a parameter:
BOOL SetCommTimeouts ( HANDLE hfile,//HANDLE to communications device Lpcommtimeouts lpcommtimeouts//Pointer to Comm time-out structure ); |
The following program sets the timeout for the serial read operation to 10 milliseconds:
Commtimeouts to; memset (&to, 0, sizeof (to)); To. ReadIntervalTimeout = 10; SetCommTimeouts (HCom, &to); |
The prototype of the Getcommtimeouts () function corresponding to the setcommtimeouts is:
BOOL Getcommtimeouts ( HANDLE hfile,//HANDLE of communications device Lpcommtimeouts lpcommtimeouts//Pointer to Comm time-out structure ); |
Event settings
Before reading and writing the serial port, you need to use the Setcommmask () function to set the event mask to monitor events on the specified communication port, which is modeled as:
BOOL Setcommmask ( HANDLE hfile,//handle that identifies the communication port DWORD Dwevtmask//ability to enable communication events ); |
With set, of course, there will be get, and the prototype of the Getcommmask () function corresponding to Setcommmask is:
BOOL Getcommmask ( HANDLE hfile,//handle that identifies the communication port Lpdword Lpevtmask//Address of variable to get event mask ); |
Events that can occur on the serial port can be one or any combination of the following list of events: Ev_break, Ev_cts, EV_DSR, Ev_err, ev_ring, EV_RLSD, Ev_rxchar, Ev_rxflag, Ev_txempty.
We can use the waitcommevent () function to wait for the event that we set with the Setcommmask () function on the serial port:
BOOL Waitcommevent ( HANDLE hfile,//handle that identifies the communication port Lpdword Lpevtmask,//Address of variable for event that occurred lpoverlapped lpoverlapped,//address of OVERLAPPED structure ); |
The waitcommevent () function blocks until the communication event that we set with the Setcommmask () function occurs on the serial port. In general, when Waitcommevent () returns, programmers can get the category of events that occur by analyzing *lpevtmask, and then handle them accordingly.
Read serial
The function used to read the serial port is the same as the function used to read the file, and the Read function prototype is as follows:
BOOL ReadFile ( HANDLE hfile,//HANDLE of file to read LPVOID lpbuffer,//pointer to buffer that receives data DWORD nNumberOfBytesToRead,//number of bytes to read Lpdword lpnumberofbytesread,//Pointer to number of bytes read lpoverlapped lpoverlapped//Pointer to structure for overlapped I/O ); |
Write serial
The function used to write the serial port is the same as the function used to write the file, and the Write function prototype is as follows:
BOOL WriteFile ( HANDLE hfile,//HANDLE to file to write to Lpcvoid lpbuffer,//pointer to data to write to file DWORD Nnumberofbytestowrite,//number of bytes to write Lpdword Lpnumberofbyteswritten,//Pointer to number of bytes written lpoverlapped lpoverlapped//Pointer to structure for overlapped I/O ); |
Close the serial port
The use of API functions to achieve serial communication is very simple to close the serial port, simply use the handle returned by the CreateFile function as a parameter call CloseHandle can:
BOOL CloseHandle ( HANDLE hobject//HANDLE to object to close );
|
The Win32 API based on VC + + serial Programming