There are two ways in VC to perform serial communication. One is the ActiveX control provided by Microsoft Microsoft Communications Control. The other is to access the serial port directly with VC . Both methods will be briefly described below. I. Microsoft Communications Control Microsoft provides a serial communication control in Windows, with it, we can make communication with serial ports. Before using it, the control should be added to the application's dialog. Then generate the corresponding object with ClassWizard. Now we can use it. This control has a lot of its own properties, you can set it through its properties window, or you can use. 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". This makes it easy to communicate with other serial ports. GetSettings: Number of serial port parameters. SetPortopen: Turns the serial port, when a program opens the serial port, the additional program will not be able to use the 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 all the characters of the buffer. 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 100class CMyDialog: public CDialog {protected: VARIANT InBuffer; VARIANT OutBuffer; CMSComm m_Com; public: ......} BOOL CMyDiaLog :: OnInitDialog () {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;} CDIALOG :: ONTIMER (Nidevent);} The data transmitted with this control is Unicode format . For the relationships and conversions of Unicode and ANSI, please refer to 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 little difference between the two, just in Windows 9x disk files can only be synchronized, and the serial port can only be asynchronously access. CREATEFILE: Open the specified serial port with a specified manner. The usual mode is m_hcom = createfile ("COM1", Generic_Read | Generic_Write, 0, NULL, OPEN_EXISTINISTING, FILE_ATTRIBUTE_NORMAL | File_Flag_Overlapped, null; m_hcom is the file handle. Generic_read | generic_write specifies that the serial port is read and written. The third parameter 0 indicates that the serial port is exclusive open. Open_existing means that the program will return fails when the specified serial port does not exist. FILE_ATTRIBUTE_NORMAL | file_flag_overlapped indicates file properties. When you open the serial port, you must specify file_flag_overlapped, which indicates that the file or device does not maintain the access pointer, and when reading and writing, you must use the overlapped structure to specify the file offset of the access. 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. COMMTIMEOUTS structure is as follows: typedef struct _COMMTIMEOUTS {DWORD ReadIntervalTimeout; DWORD ReadTotalTimeoutMultiplier; DWORD ReadTotalTimeoutConstant; DWORD WriteTotalTimeoutMultiplier; DWORD WriteTotalTimeoutConstant;} COMMTIMEOUTS, * LPCOMMTIMEOUTS; ReadIntervalTimeout: the maximum delay between two characters, when the serial data is read, once the two The time difference of the character transmission exceeds this time, and the read function will return existing data. Set to 0 indicates that this 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 an operation of reading the serial port, the timeout is multiplied by ReadtotalTimeoutMultiPlier by reading the number of bytes, plus the ReadtotalTimeoutConstant. Set ReadInterValTimeout to MaxdWord and set ReadTotalTimeoutMultiPlier and ReadTotalTimeoutConstant to 0, indicating that the reading operation will immediately return the character 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 an operation written in a serial port, the timeout is multiplied by WriteTotalTimeoutMultiPlier with WriteTotalTimeoutConstant. The setcommtimeouts function can set the timeout parameters of a device handle, and the timeout parameters of a device handle can be used to use the getcommtimeouts function. DCB: DCB structure is mainly used for serial port parameter settings. This structure is too large, here is nothing to talk, and interesters 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 can be used to get the properties of the existing serial port with getcommstate. SetupComm: Set the serial input and output buffers. Overlapped: Save information of serial port asynchronous communication. The specific structure is as follows: typedef struct _overlapped {dword; dword; dWord offset; handle hEvent;} Overlapped; Internal, INTERNALHIGH is reserved to the system, users do not need to be set. OFFSET, OFFSTHIGH is the offset of the read and write serial port, which typically sets OFFSTHigh to null, 2GB data can be supported. HEVENT reads and writes events, because the serial port is asynchronous communication, the operation may be blocked by other processes, and the program can be understood by checking whether it is read or not. 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 the following example: 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_OverlappedRead, 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, 10000, 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; CLEARCOMMERROR (m_hidcomdev, & dwerrorflags, & comstat); Return (int) comstat.cbinque;