Serial Communication of VC ++

Source: Internet
Author: User
There are two methods in VC ++ for serial communication. One is to use Microsoft Communication Control, an ActiveX control provided by Microsoft. Another method is to directly access the serial port using VC ++. The two methods are described below.

I. Microsoft Communications Control

Microsoft provides a serial communication control in windows. With this control, we can easily use the serial communication. Add the control to the application dialog box before using it. Then use classwizard to generate the corresponding object. Now we can use it.

This control has many attributes, which can be set in the Properties window or in a program. I recommend using program settings, which is more flexible.

Setcomport: Specifies the serial port used.

Get the current serial port.

Setsettings: Specify the parameters of the serial port. It is generally set to the default parameter "9600, N, 8, 1 ". This facilitates communication with other serial ports.

Getsettings: Get the serial port parameters.

Setportopen: enable or disable the serial port. When a program opens the serial port, other programs cannot use the serial port.

Getportopen: gets the serial port status.

Getinbuffercount: number of characters received in the input buffer.

Setinputlen: number of characters that read the input buffer at a time. When it is set to 0, the program will read all the characters in the buffer zone.

Getinput: Read the input buffer.

Getoutbuffercount: number of characters to be sent in the output buffer.

Setoutput: Write to the output buffer.

Generally, you can use the above functions and attributes for serial communication. The following is an example.

# Define messagelength 100

Class cmydialog: Public cdialog
{
Protected:
Variant inbuffer;
Variant outbuffer;
Cmscomm m_com;
Public:
......
}

Bool cmydialog: oninitdialog ()
{
Cdialog: oninitdialog ();
M_com.setcommp ORT (1 );
If (! M_com.getportopen ())
{
M_com.setsettings ("57600, N, 8, 1 ");
M_com.setportopen (true );
M_com.setinbuffercount (0 );
Settimer (1, 10, null );
Inbuffer. bstrval = new unsigned short [messagelength];
Outbuffer. bstrval = new unsigned short [messagelength];
Outbuffer. Vt = vt_bstr;
}
Return true;
}

Void cmydialog: ontimer (uint nidevent)
{
If (m_com.getinbuffercount ()> = messagelength)
{
Inbuffer = m_com.getinput ();
// Handle the inbuffer.
// Fill the outbuffer.
M_com.setoutput (outbuffer );
}
Cdialog: ontimer (nidevent );
}

The data transmitted using this control is in unicode format. For the relationship and conversion between Unicode and ANSI, see msdn.

For more information about the control, see the Comm control section of msdn.

2. Access the serial port directly using VC ++.

In VC ++, serial ports and disk files can be read and written in a unified manner. There is almost no difference between the two. In Windows 9x, the disk files can only be accessed synchronously, while the serial port can only be accessed asynchronously.

Createfile: Open the specified serial port in the specified way. The common method is

M_hcom = createfile ("COM1", generic_read | generic_write, 0, null, open_existing, file_attribute_normal | file_flag_overlapped, null );

M_hcom is the file handle. Generic_read | generic_write indicates that the serial port can be read and written. The third parameter 0 indicates that the serial port is exclusively open. Open_existing indicates that the program will return failure if the specified serial port does not exist. File_attribute_normal | file_flag_overlapped indicates the file attributes. When enabling the serial port, you must specify file_flag_overlapped, which indicates that the file or the device does not maintain the access pointer. When reading and writing, you must use the overlapped structure to specify the amount of file offsets to be accessed.

Readfile: reads serial data.

Writefile: write data to the serial port.

Closehandle: Close the serial port.

Commtimeouts: commtimeouts is mainly used for setting serial port timeout parameters. The commtimeouts structure is as follows:

Typedef struct _ commtimeouts
{
DWORD readintervaltimeout;
DWORD readtotaltimeoutmultiplier;
DWORD readtotaltimeoutconstant;
DWORD writetotaltimeoutmultiplier;
DWORD writetotaltimeoutconstant;
} Commtimeouts, * lpcommtimeouts;

Readintervaltimeout: The maximum latency between two characters. When reading data from the serial port, the READ function returns the existing data once the time difference between the two characters exceeds this time. If it is set to 0, this parameter does not work.

Readtotaltimeoutmultiplier: timeout for reading each character.

Readtotaltimeoutconstant: a fixed timeout for reading serial data at a time. Therefore, in a single serial port reading operation, the timeout value is readtotaltimeoutmultiplier multiplied by the number of bytes read, and readtotaltimeoutconstant. Set readintervaltimeout to maxdword, and set readtotaltimeoutmultiplier and readtotaltimeoutconstant to 0, indicating that the read operation will immediately return the characters stored in the input buffer.

Writetotaltimeoutmultiplier: the time-out between each character written.

Writetotaltimeoutconstant: a fixed timeout for writing data to the serial port. Therefore, in a serial port write operation, the timeout value is writetotaltimeoutmultiplier multiplied by the number of written bytes plus writetotaltimeoutconstant.

The setcommtimeouts function can be used to set the timeout parameter of a device handle. To obtain the timeout parameter of a device handle, you can use the getcommtimeouts function.

DCB: the DCB structure is mainly used for serial parameter settings. This structure is too large. Here we will not discuss it one by one. If you are interested, you can view the DCB description on msdn. The following two are important attributes.

Baudrate: the speed of serial communication. Generally, the value is 9600.

Bytesize: the number of bytes. Generally, it is set to 8.

You can use the setcommstate function to set the DCB structure and use getcommstate to obtain the attributes of the existing serial port.

Setupcomm: Set the serial port input and output buffer.

Overlapped: stores the information of the Serial Asynchronous Communication. The specific structure is as follows:

Typedef struct _ overlapped
{
DWORD internal;
DWORD internalhigh;
DWORD offset;
DWORD offsethigh;
Handle hevent;
} Overlapped;

Internal and internalhigh are reserved for use by the system. You do not need to set them.

Offset, offsethigh is the offset of the read/write serial port. Generally, offsethigh is set to null, and 2 GB Data is supported.

Hevent read/write events, because the serial port is asynchronous communication, the operation may be blocked by other processes, the program can check the time to determine whether the read/write is complete. The event is automatically set to valid after reading and writing is complete.

Through the above functions and structures, we can communicate through the serial port. Now let's take a look at the following example:

Bool cserial: open (INT nport, int nbaud)
{
If (m_bopened)
Return (true );
Char szport [15];
DCB;

Wsprintf (szport, "Com % d", nport );
M_hcomdev = createfile (szport, generic_read | generic_write, 0, null, open_existing,
File_attribute_normal | file_flag_overlapped, null );
If (m_hcomdev = NULL)
Return (false );

Memset (& m_overlappedread, 0, sizeof (overlapped ));
Memset (& m_overlappedwrite, 0, sizeof (overlapped ));

Commtimeouts;
Commtimeouts. readintervaltimeout = 0 xffffffff;
Commtimeouts. readtotaltimeoutmultiplier = 0;
Commtimeouts. readtotaltimeoutconstant = 0;
Commtimeouts. writetotaltimeoutmultiplier = 0;
Commtimeouts. writetotaltimeoutconstant = 5000;
Setcommtimeouts (m_hcomdev, & commtimeouts );

M_overlappedread.hevent = createevent (null, true, false, null );
M_overlappedwrite.hevent = createevent (null, true, false, null );

DCB. dcblength = sizeof (DCB );
Getcommstate (m_hcomdev, & DCB );
DCB. baudrate = nbaud;
DCB. bytesize = 8;
If (! Setcommstate (m_hcomdev, & DCB) |! Setupcomm (m_hcomdev, 10000,100 00) |
M_overlappedread.hevent = NULL | m_overlappedwrite.hevent = NULL)
{
DWORD dwerror = getlasterror ();
If (m_overlappedread.hevent! = NULL)
Closehandle (m_overlappedread.hevent );
If (m_overlappedwrite.hevent! = NULL)
Closehandle (m_overlappedwrite.hevent );
Closehandle (m_hcomdev );
Return false;
}

M_bopened = true;
Return m_bopened;
}

Int cserial: inbuffercount (void)
{
If (! M_bopened | m_hcomdev = NULL) Return (0 );
DWORD dwerrorflags;
COMSTAT;

Clearcommerror (m_hidcomdev, & dwerrorflags, & COMSTAT );
Return (INT) COMSTAT. cbinque;
}

DWORD cserial: readdata (void * buffer, DWORD dwbytesread)
{
If (! M_bopened | m_hcomdev = NULL) return 0;
Bool breadstatus;
DWORD dwerrorflags;
COMSTAT;

Clearcommerror (m_hcomdev, & dwerrorflags, & COMSTAT );
If (! COMSTAT. cbinque) return 0;

Dwbytesread = min (dwbytesread, (DWORD) COMSTAT. cbinque );

Breadstatus = readfile (m_hcomdev, buffer, dwbytesread, & dwbytesread, & m_overlappedread );
If (! Breadstatus)
{
If (getlasterror () = error_io_pending)
{
Waitforsingleobject (m_overlappedread.hevent, 2000 );
Return dwbytesread;
}
Return 0;
}
Return dwbytesread;
}

DWORD cserial: senddata (const char * buffer, DWORD dwbyteswritten)
{
If (! M_bopened | m_hcomdev = NULL)
Return (0 );
Bool bwritestat;
Bwritestat = writefile (m_hcomdev, buffer, dwbyteswritten, & dwbyteswritten, & m_overlappedwrite );
If (! Bwritestat)
{
If (getlasterror () = error_io_pending)
{
Waitforsingleobject (m_overlappedwrite.hevent, 1000 );
Return dwbyteswritten;
}
Return 0;
}
Return dwbyteswritten;
}

Related Article

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.