Win32 serial Programming

Source: Internet
Author: User
I. Basic Knowledge

There is a big difference between serial communication and 16-bit serial communication under Win32. In Win32, two programming methods can be used for serial communication. One is to call Windows API functions, and the other is to use ActiveX controls. By calling APIs, you can clearly understand the serial communication mechanism, familiarize yourself with various configurations, and freely and flexibly use different traffic control policies for serial communication. The following describes the basic knowledge of serial port operations.

Open the serial port: Use the createfile () function to open the serial port. There are two methods to open the serial port, one is synchronous (nonoverlapped), and the other is asynchronous (overlapped ). When you use overlapped to open it, the appropriate method is:

Handle hcomm;
Hcomm = createfile (gszport,
Generic_read | generic_write,
0,
0,
Open_existing,
File_flag_overlapped,
0 );
If (hcomm = invalid_handle_value)
// Error opening port; abort
Configure the serial port:

1. DCB Configuration

The DCB (Device Control Block) structure defines the control settings of serial communication devices. Many important settings are set in the DCB structure. You can initialize DCB in three ways.

(1) Use the getcommstate () function to obtain the initial value of DCB. The usage is as follows:

DCB = {0 };
If (! Getcommstate (hcomm, & DCB ))
// Error getting current DCB settings
Else
// DCB is ready for use.

(2) Use the buildcommdcb () function to initialize the DCB structure. This function fills DCB with the baud rate, parity type, data bit, and stop bit. The default value is set for the Flow Control member function. Its usage is:

DCB;
Fillmemory (& DCB, sizeof (DCB), 0 );
DCB. dcblength = sizeof (DCB );
If (! Buildcommdcb ("9600, N,", & DCB )){
// Couldn't build the DCB. Usually a problem
// With the communications specification string.
Return false;
}
Else
// DCB is ready for use.

(3) Use the setcommstate () function to manually set the initial value of DCB. The usage is as follows:

DCB;
Fillmemory (& DCB, sizeof (DCB), 0 );
If (! Getcommstate (hcomm, & DCB) // get current DCB
// Error in getcommstate
Return false;
// Update DCB rate.
DCB. baudrate = cbr_9600;
// Set new state.
If (! Setcommstate (hcomm, & DCB ))
// Error in setcommstate.
Possibly a problem with the Communications
// Port handle or a problem with the DCB structure itself.

When you manually set the DCB value, see the msdn help for the meaning of the members of the DCB structure.

2. Traffic control settings

Hardware traffic control: There are two types of hardware traffic control in serial communication: DTE/DSR mode and RTS/CTS mode, which are related to the DCB structure initialization, in the DCB structure, the initial values of outxctsflow, foutxdsrflow, fdsrsensiti.pdf, frtscontrol, and fdtrcontrol are critical. Different values represent different traffic control values. You can also set traffic control settings on your own, however, we recommend that you use standard and popular traffic control methods. When hardware traffic control is adopted, the logical bits of DTE, DSR, RTS, and CTS directly affect the data read/write and the buffer control for sending and receiving data.

Software throttling: special characters Xon and xoff are used in serial communication to control serial data sending and receiving. Related DCB members include fout, finx, xoffchar, xonchar, xofflim, and xonlim. For more information, see the msdn help.

Serial Port read/write operations: Synchronous mode (nonoverlapped) and asynchronous mode (overlapped ). Synchronous means that the function is returned only after the read/write operation is completed. This may causeProgramDie, because if an error occurs during reading and writing, the error will never be returned, and the thread may always wait there. Asynchronous mode is much more flexible. Once the read/write operation fails, the read/write will be suspended, and the function will return directly. The getlasterror function can be used to find out the cause of the read/write failure. Therefore, asynchronous operations are often used.

Read operation: The readfile () function is used to complete read operations. Asynchronous read operations:

DWORD dwread;
Bool fwaitingonread = false;
Overlapped osreader = {0 };
// Create the overlapped event. Must be closed before exiting
// To avoid a handle leak.
Osreader. hevent = createevent
(Null, true, false, null );
If (osreader. hevent = NULL)
// Error creating overlapped event; abort.
If (! Fwaitingonread ){
// Issue read operation.
If (! Readfile (hcomm, lpbuf, read_buf_size,
& Dwread, & osreader )){
If (getlasterror ()! = Error_io_pending)
// Read not delayed?
// Error in communications; report it.
Else
Fwaitingonread = true;
}
Else {
// Read completed immediately
Handleasuccessfulread (lpbuf, dwread );
}
}

If the read operation is suspended, call the waitforsingleobject () function or the waitformuntilpleobjects () function to wait until the read operation is completed or times out. Then call getoverlappedresult () to obtain the desired information.

Write operation: similar to read operation, so it is not detailed in detail. The called API function is the writefile function.

Serial Port Status:

(1) communication event: Use the setcommmask () function to set the mask of the communication event to be obtained, and then call the waitcommevent () function to detect the occurrence of the communication event. Configurable communication event flag (that is, the mask set by setcommmask () function) can include ev_break, ev_cts, ev_dsr, ev_err, ev_ring, ev_rlsd, ev_rxchar, ev_rxflag, and ev_txempty.

Note: 1 for the ev_ring flag setting, Win95 will not return the ev_ring event because Win95 will not detect this event. 2. If you set ev_rxchar, the characters can be detected. However, when you bind this event with the readfile () function to read data from the serial port, an error may occur, resulting in fewer read bytes, for specific reasons, see the msdn help. You can use the cyclic read method. Another better solution is to call the clearcommerror () function to determine the number of bytes waiting to be read in the buffer zone during a read operation.

(2) error handling and Communication Status: many errors may occur during serial communication. You can use the clearcommerror () function to detect errors and clear error conditions.

(3) Modem status: setcommmask () can contain many event signs, but these event signs only indicate voltage changes on the serial line. Call the getcommmodemstatus () function to obtain the real voltage status on the line.

Extended functions: if an application wants to use its own traffic control function, you can use the escapecommfunction () function to set the levels of DTR and RTS lines.

Communication Timeout: in communication, timeout is a very important factor, because if the data is suddenly interrupted or stopped for some reason during the data receiving process, if the time-out control mechanism is not adopted, the I/O thread will be suspended or blocked infinitely. The timeout setting in serial communication is divided into two steps. First, set the five variables in the commtimeouts structure, and then call setcommtimeouts () to set the timeout value. For an asynchronous read/write operation, if the read/write is successfully completed asynchronously after the operation is suspended, the waitforsingleobject () or waitformultipleobjects () function returns wait_object_0, getoverlappedresult (), and returns true. You can also use getcommtimeouts () to get the initial value of the system.

Close the serial port: when the program ends or the serial port resources need to be released, it is easy to close the serial port correctly. You can use the API to call closehandle () to close the serial port handle.

The call method is closehandle (hcomm );

However, it is worth noting that before closing the serial port, you must ensure that the read/write serial port thread has exited; otherwise, misoperation may occur. The general method is to use the event-driven mechanism to start an event, indicates that the serial port read/write thread is forcibly exited. Before the thread exits, the main thread is notified that the serial port can be disabled.

II. Implementation

1. Program Design Ideas

For different applications, although the interface is different, if the communication between the serial port and the host is adopted, the processing method for the serial port is roughly similar. It is nothing more than sending and receiving data through the serial port, the data received through the serial port is sent to the upper-layer software for display, and the data sent from the upper-layer to the serial port is forwarded. However, in actual programming, due to different communication modes and flow control, the serial port settings are also different, which involves issues such as DCB initialization and read/write serial ports. The general idea of serial communication application design (that is, the operation process) is: first, determine the serial name, baud rate, parity mode, data bit, stop bit to be opened, and pass it to createfile () function to open a specific serial port. Second, to protect the system's initial settings for the serial port, call getcommtimeouts () to obtain the original timeout settings for the serial port. Then, initialize the DCB object and call setcommstate () to set DCB, call setcommtimeouts () to set the serial port timeout control. Call setupcomm () to set the buffer size for the serial port to receive and send data. The serial port setting is basically complete, and then the read/write thread can be started.

Generally, the reading and writing of the serial port is completed by the reading and writing thread of the serial port, which can avoid the deadlock of the main program when the reading and writing is blocked. For full-duplex serial port read/write, the read thread and write thread should be enabled separately. For half-duplex and single-work, it is recommended that you only need to open one thread. In the thread, check the serial port status correctly according to the predefined communication handshake mode, and read and send the serial port data.

2. Implementation Details

In the case of half-duplex, complete the necessary serial port configuration, enable the serial port, DCB settings, and timeout settings, and enable the thread, for example, cwinthread hserialthread = (cwinthread *) afxbeginthread (serialoperation, hwnd, thread_priority_normal); The enabled thread is serialoperation, and the priority is normal.

Full-duplex serial programming is similar to a single worker. The difference is that the dual-thread is started, namely, the read thread and the write thread. The read thread depends on different events or messages, the read operation is completed by constantly querying the valid data received by the serial port. The write thread sends data events and data to be sent by the main thread to the serial port.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.