VC serial communication
Aunt
There are two ways in VC to perform serial communication. One is ActiveX with Microsoft Company
Control Microsoft Communications Control. The other is to access the serial port directly with VC . The following will be briefly
These two methods.
First, Microsoft Communications Control
Microsoft provides a serial communication control in Windows, with it, we can be very simple
Use serial port for communication. Before using it, the control should be added to the application's dialog. Then use it again
ClassWizard generates the corresponding object. Now we can use it.
This control has a lot of its own properties, you can set it through its properties window, you can also use program settings.
. I recommend program settings, which is more flexible.
SetCommport: Specifies the serial port used.
Getcommport: Get the serial port currently used.
SetSettings: Specify the parameters of the serial port. Generally set to default parameters "9600, n, 8, 1". So convenient
Communication with other serial ports.
GetSettings: Number of serial port parameters.
SetPortopen: Open or close the serial port, when a program opens the serial port, the other program will not be
Use this serial port.
GetPortopen: A serial port status.
GetInbufferCount: The number of characters accepted in the input buffer.
SetInputlen: The number of characters in the input buffer is read at a time. When set to 0, the program will read the buffer.
All characters.
GetInput: Read the input buffer.
GetputBufferCount: The number of characters to be sent in the output buffer.
SetOutput: Write the output buffer.
In general, serial communication can be made in terms of using the above functions and attributes. The following is an example.
#define messageLength 100
Class CMYDIALOG: PUBLIC CDIALOG {Protected: Variant Inbuffer; Variant Outbuffer; CMSCOMM M_COM; Public: ...
Bool CMYDIALOG :: OnNitdialog () {cdialog :: OnInitdialog (); m_com.setcommport (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 with this control is a Unicode format. For the relationship and conversion of Unicode and ANSI
Look at MSDN.
For additional details about the control, please check the MSDN About the Comm Control section.
Second, directly use VC to access the serial port. In VC , serial ports and disk files can be read and written in a unified way. There is almost no such thing.
With the same, only the disk files under Windows 9x can only do synchronous access, while the serial port can only be used asynchronously.
CREATEFILE: Open the specified serial port with a specified manner. Usually
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 specifies that the serial port is read
Write operation. The third parameter 0 indicates that the serial port is exclusive open. Open_existing means that when the specified serial port does not exist
When the program will return fails. FILE_ATTRIBUTE_NORMAL | file_flag_overlapped Table
Demaptive file properties. When the serial port is opened, you must specify file_flag_overlapped, which represents the file or set
If you do not maintain the access pointer, you must use the overlapped structure to specify the file offset by the Overlapped structure.
the amount.
ReadFile: Read serial port data.
Writefile: Write data to serial port.
CloseHandle: Close the serial port.
CommTIMEOUTS: CommTIMEOUTS is primarily used for serial port timeout parameter settings.
The COMMTIMEOUTS structure is as follows:
typedef struct _COMMTIMEOUTS {DWORD ReadIntervalTimeout; DWORD ReadTotalTimeoutMultiplier; DWORD ReadTotalTimeoutConstant; DWORD WriteTotalTimeoutMultiplier; DWORD WriteTotalTimeoutConstant;} COMMTIMEOUTS, * LPCOMMTIMEOUTS;
READINTERVALTIMEOUT: The biggest delay between the two characters, once two characters when reading serial port data
The time difference of the transmission exceeds this time, and the read function will return existing data. Set to 0 indicates that the parameter does not work
.
ReadtotalTimeoutMultiPlier: Reads timeout between each character.
ReadtotalTimeoutConstant: The fixed timeout of the serial port data is read at a time. So in one read serial port
In the operation, the timeout is multiplied by ReadtotalTimeoutMultiPlier with the number of bytes read.
ReadtotalTimeoutConstant. Set ReadintervalTimeout to MaxdWord and will
ReadtotalTimeOutmultiplier and ReadtotalTimeoutConstant set to 0, indicating that the read operation will be immediately
Returns the characters stored in the input buffer.
WriteTotalTimeoutmultiplier: Write a timeout between each character.
WriteTotalTimeoutConstant: The fixed timeout written in serial port data at a time. So in a written serial port
In the operation, the timeout is multiplied by WriteTotalTimeoutMultiplier with the number of bytes written.
WriteTotalTimeoutConstant.
The setcommtimeouts function can set the timeout parameters of a device handle, to get a device handle
When parameters can use the getcommtimeouts function.
DCB: DCB structure is mainly used for serial port parameter settings. This structure is too large, here is not telling,
Interests can view MSDN's description of DCB. The following two are more important attributes. BAUDRATE: Communication speed of serial port. Generally set to 9600.
Bytesize: byte number. Generally set to 8.
The DCB structure can be set with the setcommstate function, and you can use getcommstate to get existing strings
The properties of the mouth.
SetupComm: Set the serial input and output buffers.
Overlapped: Save information of serial port asynchronous communication. The specific structure is as follows:
Typedef struct _over; dword; dword; dword;}); "hle le h;" overlapped;
INTERNAL, INTERNALHIGH is reserved to the system, and users do not need to be set.
OFFSET, OFFSTHIGH is the offset of the read and write serial port, which is usually set to NULL, which can be supported.
2GB data.
HEVENT reads and writes events, because the serial port is asynchronous communication, the operation may be blocked by other processes, the program can pass
I have checked this time to learn if I have finished reading and writing. The event will be automatically set to be valid after reading and writing.
Through the above functions and structure, we can communicate through the serial port, now we look at it.
Example of surface:
Bool CSerial :: Open (int nport, int nbaud) {if (m_bopened) return (true);
Char szport [15]; DCB 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_Overlapped, 0, Sizeof (Overlapped); Memset (& M_OverlappedWrite, 0, Sizeof (overlapped));
COMMTIMEOUTS CommTimeOuts; CommTimeOuts.ReadIntervalTimeout = 0xFFFFFFFF; 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, 1000, 10000) || 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 Comstat;
Clearcommorror (M_HidComDev, & dwerrorflags, & combst);
Return (int) comstat.cbinque;
}
DWORD CSERIAL :: ReadData (Void * Buffer, DWORD DWBYTESREAD) {
IF (! m_bopened || m_hcomdev == null) Return 0;
Bool Breadstatus; DWORD DWERRORFLAGS; COMSTAT COMSTAT;
Clearcommorror (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 DWBYTESWRITEN) {
IF (! m_bopened || m_hcomdev == null) Return (0);
Bool bwritestat;
BWRITESTAT = Writefile (M_Hcomdev, Buffer, DWBYTESWRITEN, & DWBYTESWRITEN,
& M_OverlappedWrite); if (bWriteStat) {if (GetLastError (== ERROR_IO_PENDING) {WaitForSingleObject (m_OverlappedWrite.hEvent, 1000); return dwBytesWritten;} return 0;!)} Return dwBytesWritten;}
The above function is basically the opening and reading and writing of the serial port. This article is slightly description and closing letter of the serial port class.
number. Readers should write these contents. Next, you can call the serial port class in your program.
For any questions about this article, please contact the author.
References: MSDN 1999, Microsoft Corp