Win32 serial port program operation skills

Source: Internet
Author: User
Tags byte sizes
The following are some notes I made when reading "communications programming for Windows 95", so most of the topics are the same as chapter 3 in this book. some structure and API announcements are copied from VC 5.0 on-line help.

 

These things mainly talk about how to communicate with the serial port on the Win32 platform. it may be helpful for those who understand the serial port communication, but it is unclear whether there are programer available APIs on the Win32 platform (like me? : P) I just want to sort it out. More clearly, I may need to flip through on-line help or books. if you want to try a program under Win32 that controls modem (such as dialing and communication), but you do not know about serial port, then you should look for another book that talks about these things.

1. Enable a serial port

Enable the serial port device by using creatfile ().

Handle createfile (
Lptstr lpfilename, // pointer to name of the file
DWORD dwdesiredaccess, // access (read-write) Mode
DWORD dw1_mode, // share mode
Lpsecurity_attributes lpsecurityattributes, // pointer to security attributes
DWORD dwcreationdistribution, // how to create
DWORD dwflagsandattributes, // file attributes
Handle htemplatefile // handle to file with attributes to copy
);

Use createfile () API.
Lpfilename is "COM1" or "com2"
Dwdersiredaccess is generally generic_read | generic_write
Dww.mode "must" be 0, that is, it cannot be shared, but different threads in the same process can be shared once enabled.
Lpsecurityattributes is generally null
Dwcreateiondistributon here "must" be open_existing
Dwflagsandattributes defines the enabled attributes. If it is set to file_flag_overlapped, asynchronous I/O can be used.
Htemplatefile "must" be null
Return archive handle
Set the size of the serial port transfer and receipt Buffer

After the serial port is enabled, you can call setupcomm () to configure the Transfer Buffer and the receive buffer. if setupcomm () is not called, Win95 configures the preset buffer.

Bool setupcomm (
Handle hfile, // handle of communications device
DWORD dwinqueue, // size of input buffer
DWORD dwoutqueue // size of output buffer
);

2. Disable serial port File

Use the General closehandle.

Bool closehandle (
Handle hobject // handle to object to close
)

3. Obtain the seial port information

In Win32, the information used for communication is expressed in the comatrix drop structure. (Of course, it is not just the serial port.) getcomatrix roperties () can be used to obtain the information:

Bool getcomatrix roperties (
Handle hfile, // handle of communications device
Lpcomatrix drop // address of communications properties Structure
);

Comatrix Drop looks like this:

Typedef struct _ comatrix drop {// cmmp
Word wpacketlength; // packet size, in bytes
Word wpacketversion; // packet version
DWORD dwservicemask; // services implemented
DWORD dwreserved1; // Reserved
DWORD dwmaxtxqueue; // Max TX bufsize, in bytes
DWORD dwmaxrxqueue; // Max RX bufsize, in bytes
DWORD dwmaxbaud; // Max baud rate, in BPS
DWORD dwprovsubtype; // specific provider type
DWORD dwprovcapabilities; // capabilities supported
DWORD dwsettableparams; // changable Parameters
DWORD dwsettablebaud; // allowable baud rates
Word wsettabledata; // allowable byte sizes
Word wsettablestopparity; // stop bits/parity allowed
DWORD dwcurrenttxqueue; // TX buffer size, in bytes
DWORD dwcurrentrxqueue; // RX buffer size, in bytes
DWORD dwprovspec1; // provider-specific data
DWORD dwprovspec2; // provider-specific data
Wchar wcprovchar [1]; // provider-specific data
} Comatrix drop;

In this case, you need to configure the space by programmer. the interesting problem is that the system requires additional space after this structure. however, the programmer does not know how much the system will need. A simple practice is to configure a large block of space that will definitely be sufficient. another clever way is to execute getcomatrix roperties () twice. For the first time, only the space of sizeof (comatrix drop) is configured, because some actions have not yet been executed, therefore, the system will not try to fill in the following information, so there will be no problems. then execute getcomatrix roperties () for the first time. Obtain the result and retrieve the wpacketlength in the structure. The member represents the actual size, and then reconfigure a new one based on the size. in this way, there will be no waste of space.

As for the meaning of the above-mentioned members of the comatrix drop structure, the on-line help should be fully written.

4. Set and obtain the communication status

 

You can get some status by using comatrix drop, but when you want to change the current settings, you need two APIs:

Bool getcommstate (
Handle hfile, // handle of communications device
Lpdcb // address of device-Control Block Structure
);

Bool setcommstate (
Handle hfile, // handle of communications device
Lpdcb // address of device-Control Block Structure
);

You can use getcommstate () to get the current serial port status, or use setcommstate () to set the serial port status.

Please read help for the DCB structure.

In addition, the most common programmer control settings are baud rate, parity method, data bits, and stop bit. buildcommdcb.

Bool buildcommdcb (
Lptstr lpdef, // pointer to device-control string
Lpdcb // pointer to device-Control Block
);

Lpdef is long like this: "baud = 2400 parity = n data = 8 stop = 1"

5. Communication Setting Dialog Box

The Win32 API provides an API to enable the communication Setting Dialog Box: commconfigdialog (). When you call this API, a baud rate, data bits, and parity can be set .. and other information dialog box, programmer can use it to allow users to set some information and get results.

Bool commconfigdialog (
Lptstr lpszname, // pointer to device name string
Hwnd, // handle to window
Lpcommconfig lpcc // pointer to comm. Configuration Structure
);

Among them, the lpcc is used to store the results of the set value.

Typedef struct _ comm_config {
DWORD dwsize;
Word wversion;
Word wreserved;
DCB;
DWORD dwprovidersubtype;
DWORD dwprovideroffset;
DWORD dwprovidersize;
Wchar wcproviderdata [1];
} Commconfig, * lpcommconfig;

Before we call commconfigdialog (), dwsize should be set to sizeof (commconfig). The value of wversion does not seem important here (I don't know, the on-line help of vc5 can be set to 1, and the example of the book in my hand is set to 0x100). After the commconfigdialog () is called, the baudrate, bytesize, stopbits and parity are user settings.

6. Timeout Mechanism

Because it does not maintain an absolutely stable rate during transmission. because of the transmission quality, programer will need a timeout mechanism to help them with some control. in the timeout mechanism of Win32 communication, the nature of timeout is divided into two types. Let's take a look at the structure of commtimeouts:

Typedef struct _ commtimeouts {// ctmo
DWORD readintervaltimeout;

DWORD readtotaltimeoutmultiplier;
DWORD readtotaltimeoutconstant;
DWORD writetotaltimeoutmultiplier;
DWORD writetotaltimeoutconstant;
} Commtimeouts, * lpcommtimeouts;

Programmer can use getcommtimeouts () and setcommtimeouts () to read or set the current timeout value.

Bool getcommtimeouts (
Handle hfile, // handle of communications device
Lpcommtimeouts // address of Comm. time-outs Structure
);

Bool setcommtimeouts (
Handle hfile, // handle of communications device
Lpcommtimeouts // address of communications time-out Structure
);

The first kind of timeout mechanism is called Interval timeout. It is literally easy to understand that this kind of timeout mechanism is to read the timeout of the interval between characters, interval timeout can be used only when characters are read. that is, in this structure of readintervaltimeout, the unit is MS, when read a character, beyond the value of readintervaltimeout, but has not read the next character, timeout occurs.

The second timeout mechanism is called total timeout. in this timeout mechanism, Win32 provides an elastic way to set total timeout. taking the read Total timeout as an example, a linear upper limit is formed using readtotaltimeoutmultiplier and readtotaltimeoutconstant. what does it mean? The actual total timeout should be a sub-statement like this:

Readtotaltimeout = readtotaltimeoutmultiplier * bytestoread + readtotaltimeoutconstant

Writetotaltimeout is calculated using the same formula. in this way, a fixed value can be used as the timeout value, or a line can be used as the value of timeout. The number of bytes to be read or written changes.

If you do not want to use timeout, set all data members in commtimeouts to 0.

If you set readintervaltimeout to maxdword and set both readtotaltimeoutmultiplier and readtotaltimeoutconstant to 0, the read action will be immediately returned if no data exists in the receive queue, but will not stop reading.

Here is an API similar to buildcommdcb () called buildcommdcbandtimeouts ():

Bool buildcommdcbandtimeouts (
Lptstr lpdef, // pointer to the device-control string
Lpdcb, // pointer to the device-Control Block
Lpcommtimeouts // pointer to comm. Time-out Structure
);

Lpdef is a control string. It can be a string in the format of lpdef in buildcommdcb (), but the "to = xxx" setting is added. if "to = on", this API sets the Read and Write timeout values based on the value in lpcommtimeouts. if "to = off", no timeout is set for this device. if it is a value other than "on" and "off", the lpcommtimeouts setting will be ignored.

By the way, after setting the timeout value, check whether the pcf_inttimeouts and pcf_totaltimeouts flags in dwprovcapabilities in comatrix drop are set to check whether interval timeout and total timeout are supported.

7. Read data

 

Reading data from the serial port is the same as reading a normal file. It is achieved through readfile.

Bool readfile (
Handle hfile, // handle of file to read
Lpvoid lpbuffer, // address of buffer that records es data
DWORD nnumberofbytestoread, // number of bytes to read
Lpdword lpnumberofbytesread, // address of number of bytes read
Lpoverlapped // address of structure for Data
);

Note that nnumberofbytestoread sets the maximum number of reads at a time. It is very likely that the read value (check lpnumberofbytesread) is smaller than this value. this API will usually return when an error or timeout occurs.

Purgecomm () can be used to terminate the reading or writing operations currently in progress, or flush the data waiting for reading or writing in the I/O buffer.

Bool purgecomm (
Handle hfile, // handle of communications Resource
DWORD dwflags // action to perform
);

Dwflags has four types of flags:

Purge_txabort: ends the currently ongoing (background) write action.
Purge_rxabort: The (background) read currently in progress
Purge_txclear: Buffer written by flush
Purge_txclear: Buffer read by flush

The use of flushfilebuffers () ensures that all data is sent, and this API will return.

Another interesting API is clearcommerror (). It is literally used to clear errors, but in fact it can also get some information about the current communication device.

Bool clearcommerror (
Handle hfile, // handle to communications device
Lpdword lperrors, // pointer to variable to receive error codes
Lpcomstat lpstat // pointer to buffer for communications Status
);

After calling this API, some information about the communication device will be stored in lpstat. The COMSTAT structure is as follows:

Typedef struct _ COMSTAT {// CST
DWORD fctshold: 1; // TX waiting for CTs Signal
DWORD fdsrhold: 1; // TX waiting for DSR Signal
DWORD frlsdhold: 1; // TX waiting for RlSD Signal
DWORD fxoffhold: 1; // TX waiting, xoff char rec 'd
DWORD fxoffsent: 1; // TX waiting, xoff char sent
DWORD feof: 1; // EOF character sent
DWORD ftxim: 1; // character waiting for TX
DWORD freserved: 25; // Reserved
DWORD cbinque; // bytes in input buffer
DWORD cboutque; // bytes in output buffer
} COMSTAT, * lpcomstat

With fctshold, fdsrhold, frlsdhold, fxoffhold, and fxoffsent, you can know what causes communication to be blocked. (related to handshaking and Flow Control) cbinque and cboutque can show how many bytes are being read or written to the queue.

8. Write Data

Like reading data, programmer can use writefile () to write data to serial port.

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 needed for overlapped I/O
);

There are three interesting APIs for writing data to communication devices: setcommbreak (), clearcommbreak, and transmitcommchar ().

Bool setcommbreak (
Handle hfile // handle of communications device
);

Bool clearcommbreak (
Handle hfile // handle to communications device
);

Bool transmitcommchar (
Handle hfile, // handle of communications device
Char cchar // character to transmit
);

Setcommbreak () is used to pause the current transmission job, which will stop the data in the buffer from being sent. At this time, program can do some miscellaneous, and then use clearcommbreak () reply to the transmission job.

Transmitcommchar () is used to transmit one character of data immediately before all buffer data is sent out, even if there is data in the buffer. in other words, this character has the highest priority to be sent out.

9. event-driven I/O

In Win32, I/O of communication devices can be achieved through event-driven methods. it mainly uses an API called waitcommevent. after the API is called, it will be blocked until the specified event occurs. let's take a look at how to set events, and then look back at waitcommevent ().

The programer can use getcommmask () and setcommmask () to obtain or set the communication events currently set.

Bool getcommmask (
Handle hfile, // handle of communications device
Lpdword lpevtmask // address of variable to get event mask
);

Bool setcommmask (
Handle hfile, // handle of communications device
DWORD dwevtmask // mask that identifies enabled events
);

Configurable events include ev_break, ev_cts, ev_dsr, ev_err, ev_ring, ev_rlsd, ev_rxchar, ev_rxflag, and ev_txempty. (For more information about the meaning, see help.) Of course, you can combine them into combined events.

After setting the event to be processed, you can use waitcommevent ()

Bool waitcommevent (
Handle hfile, // handle of communications device
Lpdword lpevtmask, // address of variable for event that occurred
Lpoverlapped, // address of overlapped Structure
);

Waitcommevent () will block until the specified communication event occurs. therefore, when waitcommevent () returns, you can obtain the event from lpevtmask and decide how to handle it.

For example, you can use setcommmask () to set the event to ev_rxchar. When waitcommevent () is called, it will not return until there are characters available for reading. After it returns, you can check whether ev_rxchar is set in lpevtmask. If yes, you can use readfile () to read it. in this way, we can avoid the inefficiency caused by polling in some situations.

10. handle errors

The clearncommerror () mentioned above can be used to obtain the cause of the current error. (See Help)

11. hardware control commands

Win32 provides the escapecommfunction () that allows the programer to control several hardware signals.

Bool escapecommfunction (
Handle hfile, // handle to communications device
DWORD dwfunc // extended function to perform
);

Dwfunc can be:

Clrdtr: Disable DTr
Clrrts: Get the RTS off
Setdtr: enables DTR on
Setrts: Let the RTS on
Setxoff: "simulation" receives xoff characters
Setxon: "simulation" receives the Xon character
Setbreak: The same as setcommbreak ().
Clrbreak: The same as clearcommbreak ().

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.