1. API description
In Win32 API, the serial port uses the file access method, and its operation API is basically the same as the file operation API.
Open serial port
In Win32, the API function used to open the serial port is createfile, and its prototype is:
Handle createfile ( Lptstr lpfilename, // name of the serial port to be opened, such as COM1 or com2 DWORD dwaccess, // specifies the serial access type, which can be read, write, or parallel DWORD dw1_mode, // specify the sharing attribute. This parameter must be set to 0 because the serial port cannot be shared. Lpsecurity_attributes lpsa, // reference the Security Attribute structure. The default value is null. DWORD dwcreate, // create a flag. For serial port operations, this parameter must be set to open existing. DWORD dwattrsandflags, // attribute description, used to specify whether asynchronous operations can be performed on the serial port, // File_flag_overlapped: asynchronous I/O can be used. Handle htemplatefile // The handle pointing to the template file. For the serial port, this parameter must be set to null. ); |
For exampleProgramUsed to open the serial port COM1 in synchronous read/write mode:
Handle hcom; DWORD dwerror; Hcon = createfile ("COM1", generic_read | generic_write, 0, null, open_existing, 0, null ); If (hcom = (handle) 0 xffffffff) { Dwerror = getlasterror (); MessageBox (dwerror ); } |
The dwattrsandflags parameter and the file_flag_overlapped flag are described as follows: Windows file operations are divided into synchronous I/O and overlapping I/O (overlapped I/O) methods, in synchronous I/O mode, the API will be blocked until the operation is complete (in multi-threaded mode, although the main thread will not be blocked, the listener thread will still be blocked ); in the overlapping I/O mode, the API will return immediately and the operation will be performed in the background to avoid thread blocking. Overlapping I/O is flexible, and it can also implement blocking (for example, we can set that we must read a data before proceeding to the next operation ). If the I/O operation is returned when the API does not complete the operation, we can call the getoverlappedresult () function to block the operation and return the result.
Configure serial port
The serial port configuration is implemented by changing the member variable value of the device control block DCB (Device Control Block). The size of the receiving buffer and sending buffer can be set through the setupcomm function.
DCB struct is defined:
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 fdsrsensiti.pdf: 1; // DSR sensiti.pdf 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; // encoded ed 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 Program sets the serial port as follows: the baud rate is 9600, the number of data digits is 7 bits, the Stop bits are 2 bits, the parity check, the size of the receiving buffer and the sending buffer are both 1024 bytes, finally, use the purgecomm function to terminate all background read/write operations and clear the receiving and sending buffers:
DCB; DCB. baudrate = 9600; // The baud rate is 9600. DCB. bytesize = 7; // The number of data digits is 7 digits. DCB. Parity = evenparity; // parity check DCB. stopbits = 2; // two stop bits DCB. fbinary = true; DCB. fparity = true; If (! Setcommstate (hcom, & DCB )) { MessageBox ("An error occurred while setting the serial port! "); } Setupcomm (hcom, 1024,102 4 ); Purgecomm (hcom, purce_txabort | purge_rxabort | purge_txclear | purge_rxclear ); |
Timeout settings
Timeout settings are implemented by changing the value of the member variable of the commtimeouts struct. The prototype of commtimeouts is:
Typedef struct _ commtimeouts { DWORD readintervaltimeout; // defines the maximum time interval between two characters, in milliseconds // When the value of readintervaltimeout is exceeded after one character is read, it will // Timeout DWORD readtotaltimeoutmultiplier; DWORD readtotaltimeoutconstant; // The relationship between each time is as follows: // Readtotaltimeout = readtotaltimeoutmultiplier * bytestoread + readtotaltimeoutconstant DWORD writetotaltimeoutmultiplier; DWORD writetotaltimeoutconstant; } Commtimeouts, * lpcommtimeouts; |
Set the timeout function to setcommtimeouts. In its prototype, the pointer to receive commtimeouts is a parameter:
Bool setcommtimeouts ( Handle hfile, // handle to communications device Lpcommtimeouts // pointer to comm time-out Structure ); |
The following procedure sets the serial port read operation timeout to 10 milliseconds:
Commtimeouts; Memset (& to, 0, sizeof ()); To. readintervaltimeout = 10; Setcommtimeouts (hcom, & ); |
The prototype of the getcommtimeouts () function corresponding to setcommtimeouts is:
Bool getcommtimeouts ( Handle hfile, // handle of communications device 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 the events on the specified communication port. Its prototype is:
Bool setcommmask ( Handle hfile, // The handle that identifies the communication port DWORD dwevtmask // communication event that can be enabled ); |
With set, get will also be available. The prototype of the getcommmask () function corresponding to setcommmask is:
Bool getcommmask ( Handle hfile, // The 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 events: ev_break, ev_cts, ev_dsr, ev_err, ev_ring, ev_rlsd, ev_rxchar, ev_rxflag, and ev_txempty.
We can use the waitcommevent () function to wait for the event we set using the setcommmask () function on the serial port:
Bool waitcommevent ( Handle hfile, // The handle that identifies the communication port Lpdword lpevtmask, // address of variable for event that occurred Lpoverlapped, // address of overlapped Structure ); |
The waitcommevent () function is blocked until a communication event set by the setcommmask () function occurs on the serial port. Generally, when waitcommevent () returns an event, the programmer can analyze * lpevtmask to obtain the event type and then process it accordingly.
Read serial port
The functions used to read the serial port are the same as those used to read the file. The READ function is prototype as follows:
Bool readfile ( Handle hfile, // handle of file to read Lpvoid lpbuffer, // pointer to buffer that records es data DWORD nnumberofbytestoread, // number of bytes to read Lpdword lpnumberofbytesread, // pointer to number of bytes read Lpoverlapped // pointer to structure for overlapped I/O ); |
Serial Port writing
The functions used for writing data to the serial port are the same as those used for writing data to the file. The writing function is prototype as follows:
Bool writefile ( Handle hfile, // handle to file to write Lpvoid lpbuffer, // pointer to data to write to file DWORD nnumberofbytestowrite, // number of bytes to write Lpdword lpnumberofbyteswritten, // pointer to number of bytes written Lpoverlapped // pointer to structure for overlapped I/O ); |
Close serial port
It is very easy to disable the serial port when using the API function for serial communication. You only need to use the handle returned by the createfile function as the parameter to call closehandle:
Bool closehandle ( Handle hobject // handle to object to close ); |