This article uses VC ++ as the platform for serial communication programming
There are many implementation methods for serial communication in VC ++, and the control is naturally the simplest method. However, since the control only supports dialog box programs, it is not required for some occasions, therefore, using Windows APIS is a better method.
Serial Communication Operation Method
1. synchronization mode
In synchronous mode, the function of reading the serial port tries to read the specified number of data in the receiving buffer of the serial port until the specified number of data is fully read or the specified timeout value is reached.
[CPP]
View plaincopyprint?
- Commtimeouts timeover; // The commtimeouts structure is used to set the read/write function wait time.
- Memset (& timeover, 0, sizeof (timeover ));
- DWORD timemultiplier, timeconstant;
- Timeover. readtotaltimeoutmultiplier = timemultiplier;
- Timeover. readtotaltimeoutconstant = timeconstant;
- Setcommtimeouts (hcomport, & timeover );
- ......
- Readfile (hcomport, // serial port handle
- Inbuffer, // Buffer
- Nwantread, // number of bytes the function tries to read each time it calls readfile
- & Nrealread, // actual number of bytes read
- Null); // indicates that readfile will adopt the synchronous file read/write mode.
Commtimeouts timeover; // The commtimeouts structure is used to set the read/write function wait time. <Br/> memset (& timeover, 0, sizeof (timeover); <br/> DWORD timemultiplier, timeconstant; <br/> timeover. readtotaltimeoutmultiplier = timemultiplier; <br/> timeover. readtotaltimeoutconstant = timeconstant; <br/> setcommtimeouts (hcomport, & timeover); <br/> ...... <Br/> readfile (hcomport, // serial port handle <br/> inbuffer, // buffer <br/> nwantread, // each time readfile is called, number of bytes to be read by the function <br/> & nrealread, // the actual number of bytes to be read <br/> null); // indicates that readfile will adopt the synchronous file read/write mode
If the specified number of data to be read is large and the set timeout time is long, and the number of data in the receiving buffer is small, it may cause thread blocking. To solve this problem, check the cbinque Member of the COMSTAT structure. The size of the member is the actual number of data waiting in the receiving buffer. If the value of nwantread is equal to COMSTAT. cbinque, thread blocking can be effectively prevented.
2. Query Method
Query Method: A thread in a process regularly queries the receiving buffer of the serial port. If there is data in the buffer, the thread reads the data. If there is no data in the buffer, the thread continues to execute, therefore, it takes a lot of CPU time, which is actually a derivative of the synchronization method.
[CPP]
View plaincopyprint?
- Commtimeouts timeover;
- Memset (& timeover, 0, sizeof (timeover ));
- Timeover. readintervaltimeout = maxword; // note that the synchronization mode is different.
- Setcommtimeouts (hcomport. & timeover );
- ......
- Readfile (hcomport.
- Inbuffer.
- Nwantread.
- & Nrealread,
- Null); // indicates that readfile will adopt the synchronous file read/write mode.
Commtimeouts timeover; <br/> memset (& timeover, 0, sizeof (timeover); <br/> timeover. readintervaltimeout = maxword; // note that the synchronization mode is different. <br/> setcommtimeouts (hcomport. & timeover); <br/> ...... <Br/> readfile (hcomport. <br/> inbuffer. <br/> nwantread. <br/> & nrealread, <br/> null); // indicates that readfile is synchronized to the file.
In addition to the variable timeover settings in the commtimeouts structure, the query method and synchronization method are similar in program code, but the two work in different ways. Although readfile adopts the synchronous file read/write mode, since the timeover interval exceeds the time set to maxword, readfile reads all the waiting data in the receiving queue each time, data of up to nwantread bytes can be read at a time.
3. asynchronous mode
In asynchronous mode, the multi-threaded structure of Windows enables the serial port read and write operations in the background, while other parts of the application are executed in the foreground.
[CPP]
View plaincopyprint?
- Overlapped wroverlapped;
- Commtimeouts timeover;
- Memset (& timeover.0.sizeof (timeover ));
- Dwordtimemultiplier, timeconstant;
- Timeover. readtotaltimeoutmultiplier = timemultiplier;
- Timeover. readtotaltimeoutconstant = timeconstant;
- Setcommtimeouts (hcomport, & timeover );
- Wroverlapped. hevent = createevent (null. True, false, null); // create an event handle
- ......
- Readfile (hcomport,
- Nbuffer,
- Nwantread,
- & Nrealread,
- & Wroverlapped); // asynchronously contacts the event
- /* Because the asynchronous method is used, it only returns the status of whether the data has been read, and does not return the actual data read. That is, the nrealread in readfile is invalid */
- // The data actually read is returned by the getoverlappedresult function.
- Getoverlappedresult (hcomport,
- & Wroverlapped,
- & Nrealread,
- True );
- /* Indicates that it is returned to the application only after the asynchronous operation ends. At this time, the getoverlappedresult function is equivalent to the waitforsingleobject function. */
- ......
- Resetevent (wroverlapped. hevent); // release the event handle
Overlapped wroverlapped; <br/> commtimeouts timeover; <br/> memset (& timeover.0.sizeof (timeover); <br/> dwordtimemultiplier, timeconstant; <br/> timeover. readtotaltimeoutmultiplier = timemultiplier; <br/> timeover. readtotaltimeoutconstant = timeconstant; <br/> setcommtimeouts (hcomport, & timeover); <br/> wroverlapped. hevent = createevent (null. true, false, null); // create an event handle <br/> ...... <Br/> readfile (hcomport, <br/> nbuffer, <br/> nwantread, <br/> & nrealread, <br/> & wroverlapped ); // asynchronous mode and associated with the event <br/>/* because the asynchronous mode is used, it only returns the status of the data that has been read and does not return the actual data read, that is, the nrealread in readfile is invalid */</P> <p> // the data actually read is returned by the getoverlappedresult function <br/> getoverlappedresult (hcomport, <br/> & wroverlapped, <br/> & nrealread, <br/> true ); <br/>/* indicates that it is returned to the application only after the asynchronous operation is completed. At this time, the getoverlappedresult function is equivalent to the waitforsingleobject function. */<Br/> ...... <Br/> resetevent (wroverlapped. hevent); // release the event handle
When using the Asynchronous Method and createfile to open a serial device, the fdwattrsandflags parameter of the createfile function must be set to file_flag _ overlapped. In Windows, asynchronous file reading and writing is supported only on the serial device. In addition, the getoverlappedresult function only supports files opened by the serial device or using the devicelocontrol function.
4. event-driven
If you have strict response time requirements for port data, you can use the event-driven method. The event-driven method sets Event Notifications. When a desired event occurs, Windows sends a notification indicating that the event has occurred, which is similar to the interrupt method in the DOS environment. Windows defines nine types of serial communication events, which are commonly used in the following three types:
Ev_rxchar: receives a byte and puts it in the input buffer;
Ev_txempty: The last character in the output buffer, which is sent out;
Ev_rxflag: receives event characters (evtchar members in the DCB structure) and puts them in the input buffer.
After setcommmask () is used to specify a useful event, the application can call waitcommevent () to wait for the event to occur. Setcommmask (hcomm, 0) can abort waitcommevent.
[CPP]
View plaincopyprint?
- COMSTAT;
- DWORD dwevent;
- Setcommmask (hcomport, ev_rxchar); // sets the Event code
- /* Ev_rxchar indicates that the event is triggered when a character is received, and then the waitcommevent function is called to wait for the event to occur. */
- ......
- If (waitcommevent (hcomport, & dwevent, null ))
- If (dwevent & ev_rxchar) & COMSTAT. cbinque)
- Readfile (hcomport,
- Inbuffer,
- COMSTAT. cbinque,
- & Nrealread,
- Null); // indicates that the function is synchronized.