Serial communication method (WinAPI implementation)

xiaoxiao2021-03-06  20

Preface:

Targer, using serial ports to carry out important status in the field of communication communication. The acquisition and delivery of data signals using RS232-RS485 is another hot spot for VC programming. Serial communication has a wide range of applications in communication software. Such as phones, fax, video, and various controls. In the middle of various development tools, VC is strongly supported and flexible, and also gets the maximum support for Microsoft, so in general, the communication programming of hardware operations is generally recommended, and VC is recommended as development tools. However, industrial control serial communication This is different from a general serial communication program because most of the peripheral devices are transmitted (Byte type), so in order to improve the running stability of the program, we write the program to write You can not consider the work of transferring BYTE type data.

The current popular approach is currently two ways: First, use Microsoft's CMSCOMM control to communicate, but now many programmers should give up this way. Second, using the WinAPI function to program, this programming is the highest, requiring you to master a lot of API functions. The third is to prepare some of the serial communication controls provided above now, such as the CSerial class.

Program implementation:

I found that the development and practice of the WIN API function can be used to make a large control of the programmer, and the program is also very stable. So I will package the function of serial ports, and then call in various projects, the effect is still better, and each function and calling method are now listed, I hope to help you.

First, set the serial correlation work

#define maxblock 2048

#define XON 0x11

#define XOFF 0x13

Bool setcom (Handle & M_HCOM, Const Char * M_Sport, Int Baudrate, Int Database, CString Parity, CString Stopbit)

{

CommTIMEOUTS TIMEOUTS; // Serial Output Time Timeout Settings

DCB DCB; // Matching with port

M_HCOM = CreateFile (m_sport, generic_read | generic_write, 0, null,

Open_EXISTING, FILE_ATTRIBUTE_NORMAL | file_flag_overlapped,

NULL); // Open the serial port in the overlapping manner

IF (M_HCOM == Invalid_Handle_Value)

{

AFXMessageBox ("Setting the serial port section, serial port failure"); / overlapping mode asynchronous communication (Invalid_Handle_Value) function failed.

Return False;

}

Setupcomm (M_HCOM, Maxblock, MaxBlock); // Set buffer

MEMSET (& Timeouts, 0, Sizeof (Timeouts));

TimeOuts.readintervaltimeout = maxdword; // Set the interval timeout to the largest, set the total overtime to 0 will cause readfile to return and complete the operation

Timeouts.ReadtotalTimeoutMultiPlier = 0; // Read time coefficient

Timeouts.readtotalTimeoutConstant = 0; // Read time constant

TimeOuts.writeTotalTimeoutMultiPlier = 50; // Total timeout = time factor * Requires read / write characters time constant timeouts.writeTotimeoutConstant = 2000; // Setup timeout to specify WriteComm member functions

Setcommtimeouts; // GetoverlappedResult function waiting time * /

IF (! getcommstate (M_HCOM, & DCB)) serial port open mode, port, baud rate and port matching device

{

AfxMessageBox ("getcommstate failed";

Return False;

}

Dcb.fparity = true; // Allow parity

Dcb.fbinary = true;

IF (Parity == "None")

DCB.PARITY = NOPARITY

IF (Parity == "ODD")

DCB.PARITY = ODDPARITY;

IF (Parity == "Even")

DCB.PARITY = EVENPARITY

IF (stopbit == "1") // set the baud rate

DCB.Stopbits = onestopbit;

// if (stopbit == "0") // set the baud rate

// dcb.stopbits = nonstopbit;

IF (stopbit == "2") // set the baud rate

DCB.Stopbits = twostopbits;

BOOL M_BECHO = FALSE; ///

INT M_NFLOWCTRL = 0;

BOOL M_BNEWLINE = false; ///

Dcb.baudrate = BaudRate; // baud rate

Dcb.bytesize = Database; / / per word

// Hardware flow control settings

Dcb.foutxctsflow = m_nflowctrl == 1;

Dcb.frtscontrol = m_nflowctrl == 1? RTS_Control_Handshake: RTS_Control_enable;

// XON / XOFF stream control setting (software flow control!)

Dcb.finx = dcb.foutx = m_nflowctrl == 2;

Dcb.xonchar = xon;

DCB.XOFFCHAR = Xoff;

Dcb.xonlim = 50;

Dcb.xofflim = 50;

IF (setcommstate (M_HCOM, & DCB))

Return True; Communication port settings for COM

Else

{

AfxMessageBox ("Serial Port is opened, set failed");

Return False;

}

}

Second, read serial port operations:

Int Readcom (Handle Hchammmmmmmmmmmm, Byte Inbuff [], DWORD & NBYTESREAD, INT ReadTime

{

DWORD LRC; // Portrait redundancy check

DWord endtime; / jueostatic overlapped il;

INT readnumber = 0;

INT numcount = 0; // Control the number of reads

DWORD DWERRORSK, NTOREAD;

COMSTAT COMSTAT;

Ol.offset = 0; /// The byte offset starting with respect to the file

Ol.offsethiGH = 0; /// The calling process is negligible when the byte offset of the transmitted data is ignored.

Ol.hevent = null; /// Identify the event, the data transfer is set to signal state

Ol.hevent = CreateEvent (NULL, TRUE, FALSE, NULL);

EndTime = gettickcount () readime; // gettickcount () Retrieve the time (milliseconds) started to this

For (int i = 0; i <2000; i )

Inbuff [i] = 0;

SLEEP (READTIME);

Clearcommerror (HCOMM, & DWERRORMASK, & COMSTAT);

NTOREAD = min (2000, comstat.cbinque);

IF (int (NTOREAD) <2)

Goto loop;

IF (! Readfile (hcomm, inbuff, ntoread, & nbytesread, & ol))

{

IF ((Lrc = getLastError ()) == Error_io_pending)

{

///

EndTime = gettickcount () readime; // gettickcount () Retrieve the time (milliseconds) started to this

While (! GetoverlappedResult (hcomm, & ol, & nbytesread, false) // This function retrieves the result of overlapping operation

{

IF (GettickCount ()> endtime)

Break;

}

}

}

Return 1;

LOOP: RETURN 0;

}

Third, write the serial order command

Int writecom (Handle Hchammmmm, Byte Outbuff [], Int size, Int Bwrite [])

{

DWORD NBYTESWRITE, ENDTIME, LRC;

Static overlapped OL;

DWORD DWERRORMASK, DWERROR;

COMSTAT COMSTAT;

Ol.hevent = CreateEvent (NULL, TRUE, FALSE, NULL);

Ol.offset = 0;

Ol.offsethiGH = 0;

Ol.hevent = null; /// identifies the event, set it to signal state when data is completed

Clearcommerror (HCOMM, & DWERRORMASK, & COMSTAT);

IF (! Writefile (HComm, Outbuff, Size, & nbyteswrite, & ol))

{

IF ((Lrc = getLastError ()) == Error_io_pending)

{

Endtime = gettickcount () 1000;

While (! GetoverlappedResult (HComm, & OL, & nbyteswrite, false)

{

Dwerror = getLastError (); if (gettickcount ()> endtime)

{

AfxMessageBox ("" ​​The number of data in the current port transmission buffer is empty ");

Break;

}

IF (dwerror = error_io_incumplete)

Continue; // Normal return results not completely completed

Else

{

// Errors, try recovery!

Clearcommerror (hcomm, & dwrror, & comstat);

Break;

}

}

}

}

FlushfileBuffers (HCOMM);

PurgeComm (hcomm, purge_txclear);

BWRITE = 0;

Return 1;

}

Fourth, the calling method is simple, just make simple settings for your serial port parameters. such as:

Bool main_opencom () // Sets COM

{

Int boundrate = 9600; // baud rate

CString Stopbits = "1"; // Stopping

INT DATABITS = 8; // Data Bit

CSTRING PARITY = "odd"; // parity

CString M_Port = "COM1";

Return setcom (M_Hcom1, M_Port, Buggs, DataBits, Parity, Stopbits);

}

void main ()

{

Int size;

DWORD BYTESTOREAD = 52 * count 6; // To 11 bytes

Int bwrite [2];

INT readtime = 2000;

BYTE OUTBUFF [12] = {0xFF, 0x00, 0XEA, 0xFF, 0xEA, 0xFF, 0, 0, 0, 0, 0};

Size = SizeOf; Outbuff

Writecom (M_Hcom, Outbuff, Size, BWRITE);

READCOM (M_HCOM, M_INBUFF, BYTESTOREAD, READTIME);

/ / EQUAN Xiang Yin

}

With the package of the above functions, I believe that everyone should be able to make it easy and quickly.

转载请注明原文地址:https://www.9cbs.com/read-42517.html

New Post(0)