(1) parameter Setting and enabling of serial port
parameters of RS-232-C serial port configuration is a required condition for serial communication. In addition, different serial ports are configured for different occasions, purposes, and functions. To make the Program more flexible, wider adaptability. You can set all the possible parameters in a few combo boxes in advance. You can change the settings at any time after the program runs. Customize a Data Structure for setting serial port parameters:
| typedef struct tagcom_config {< br> int nport; file: // port number, from COM1 to com4 int nbaud; file: // baud rate, from rjbps to 57600bps (the corresponding macro is cbr_1200 to cbr_57600 ) int ndata; file: // Number of data bits, 7 bits or 8 bits int nstop; file: // the number of Stop bits, can be 1 bits, 1.5 bit and 2 bit. int nparity; // check method, with or without a check (noparity) , file: // odd check (oddparity) , and even check (evenparity) . }com_config; |
After selecting the appropriate parameters, you can open the communication port based on the configured port configuration. Compared with the previousDoSWhich of the following serial communication programs is different,WindowsIn the operating platform, applications are not recommended to directly control hardware (including ports), nor to interrupt the use (unlessRing0System Level), but throughWindowsThe device driver provided by the operating system for data transmission. InWindowsIn the operating system, the serial port is processed as a file like other communication ports, rather than directly operating on the port. For serial communication,Win 32Provides the corresponding fileI/OFunctions and communication functions. By understanding the use of these functions, You can compile a communication program that meets different needs. Structures related to communication devices include:Commconfig,Comatrix drop,Commtimeouts,COMSTAT,DCB,Modemdevcaps,ModemsettingsTotal7Communications-relatedWindows APICommon functions26For more information, seeMsdnHelp file. The following are some of the key steps to enable the serial port:Code:
// Open the file as a file and save the returned port handle to the handle. Idcomdev . Idcomdev = createfile (g_szcom_port [g_com_config.nport], Generic_read | generic_write, 0, Null, Open_existing, File_attribute_normal, Null ); ...... File: // cfg Is Commconfig Instance Object to obtain the status of the current communication port. Cfg. DCB. dcblength = sizeof (DCB ); Getcommstate (idcomdev, & (CFG. DCB )); File :// Set the size of the sending and receiving Cache Setupcomm (idcomdev, 4096,409 6 ); // Purgecomm () Is a clearing function that can be used to stop any pending background reads or writes, and can be washed away I/O File :// Buffer Zone . Where: Purge_txabort Used to stop background write operations; Pruge_rxabort Used to abort the background File :// Read operations; Pruge_txclear Used to clear the sending buffer;Pruge_rxclear Used to clear the receiving buffer Purgecomm (idcomdev, purge_txabort | purge_rxabort | purge_txclear | purge_rxclear ); File :// Fill in according to the set parameters DCB Structure object DCB Data member variables DCB. dcblength = sizeof (DCB ); Getcommstate (idcomdev, & DCB ); File :// Set port communication parameters DCB. baudrate = g_com_baud [g_com_config.nbaud]; DCB. bytesize = g_com_bytesize [g_com_config.ndata]; DCB. Parity = g_com_parity [g_com_config.nparity]; DCB. stopbits = g_com_stopbits [g_com_config.nstop]; File :// Hardware Traffic Control DCB. fdtrcontrol = dtr_control_disable; DCB. foutxctsflow = false; DCB. frtscontrol = rts_control_disable; File :// Software Flow Control DCB. finx = DCB. foutx = false; DCB. xonchar = (char) 0xff; DCB. xoffchar = (char) 0xff; DCB. xonlim = 100; DCB. xofflim = 100; DCB. evtchar = 0x0d; DCB. fbinary = true; DCB. fparity = true; File ://Timeout control settings. There are two types of Timeout: interval timeout It is only useful for reading data from a port. ) It specifies the time to experience reading two characters; Total timeout : When the total time required to read or write a specific number of bytes exceeds a certain threshold , Timeout trigger. Calculation timeout can be calculated according to the formula: File: // readtotaltimeout = (readtotaltimeoutmultiplier * bytes_to_read) + // Readtotaltimeoutconstant File: // writetotaltimeout = (writetotaltimeoutmuliplier * bytes_to_write) + // Writetototaltimeoutconstant File :// If the parameter is 0 There is no timeout. Commtimeouts. readintervaltimeout = maxdword; Commtimeouts. readtotaltimeoutmultiplier = 0; Commtimeouts. readtotaltimeoutconstant = 0; Commtimeouts. writetotaltimeoutmultiplier = 2*9600/DCB. baudrate; Commtimeouts. writetotaltimeoutconstant = 25; Setcommtimeouts (idcomdev, & commtimeouts ); File :// According to the configured DCB Configure the communication port status, enable the listener port, and monitor the number of incoming packets from the peripherals. File :// Data thread Comreadthreadproc . If (setcommstate (idcomdev, & DCB )) { M_bcomportopen = true; G_hcom = idcomdev; Afxbeginthread (comreadthreadproc, null, thread_priority_normal ); Return; } |
(2) Listening to monitoring threads
after the port is successfully opened, enable the function by executing the thread afxbeginthread (comreadthreadproc, null, thread_priority_normal ); A working thread used to listen on a port comreadthreadproc is enabled. The specific processing process
is as follows:
| uint comreadthreadproc (lpvoid pparam) {< br> ...... file: // set the identity of the read port thread execution flag g_comthread.setreadthreadkillflag (false); while (1) {< br> file: // indicates the port enabling status. If (true = g_comthread.getclosecomflag ()) {< br> g_comthread.setreadthreadkillflag (true); return 0; // close }< br> file: // Read port operation dwneedread = 500; file: // read data from the port to the cache If (! Readfile (g_hcom, Buf, dwneedread, & dwactread, null) {< br> clearcommerror (g_hcom, & dwerrormask, & COMSTAT); purgecomm (g_hcom, purge_rxclear); continue; }< br> file: // Add the read characters to the global buffer g_comreadbuf.add (BUF, dwactread); sleep (1); }< br> ...... return 0; } |
g_comthread and g_comreadbuf are the instance objects of the thread class ccomthread and read Port Class comreadbuf respectively. The two classes use the ccriticalsection m_lock; class to implement the critical section technology to maintain synchronization between threads. two functions of the ccomreadbuf class getonebyte ( ...... ) , Add ( ...... ) is used to read one character from the port and add the read character to the buffer. The main implementation code is as follows:
| bool ccomreadbuf: getonebyte (byte * CB) {< br> m_lock.lock (); If (m_nhead = m_ntail) {< br> m_lock.unlock (); return false; // null }< br> * cb = m_readbuf [m_ntail]; If (m_ntail m_ntail ++; else m_ntail = 0; m_lock.unlock (); return true; // null } void ccomreadbuf: add (byte Buf [], int nbytes) {< br> int nt, I; m_lock.lock (); for (I = 0; I br >{< br> NT = (m_nHead-m_nTail); If (NT <0) NT + = m_nbufsize; If (nt + 1 = m_nbufsize) break; // buffer full m_readbuf [m_nhead] = Buf [I]; If (m_nhead m_nhead ++; else m_nhead = 0; }< br> m_lock.unlock (); } |
(3) sending control commands
The control command can be obtained from the edit box on the dialog bar, and then can be sent from the port by writing files. This part is easy to implement and does not involve technologies such as threads. The main code is as follows:
...... File ://Obtain the command line from the dialog bar Nread = m_wnddlgbar.getdlgitemtext (idc_edit_send, Buf, 500 ); File ://Send command to Port If (nread> 0) { Buf [nread] = 0x0d; Buf [nread + 1] = 0x00; : Writefile (g_hcom, Buf, nread + 1, & dwactwrite, null ); } ...... |