Acerca de la comunicación en serie

El uso de puertos serie para la comunicación de datos ocupa un lugar importante en el campo de la comunicación. El uso de RS232-RS485 para recopilar y transmitir señales de datos es otro tema candente en la programación de VC. La comunicación en serie se utiliza ampliamente en el software de comunicación. Como teléfono, fax, vídeo y controles varios. Entre las diversas herramientas de desarrollo, VC es potente y flexible y cuenta con el mayor soporte de Microsoft. Por lo tanto, en la programación de comunicaciones generales que involucra operaciones de hardware, VC se recomienda principalmente como herramienta de desarrollo. Sin embargo, la comunicación en serie de control industrial es diferente de los programas de comunicación en serie generales porque la mayoría de los periféricos de control transmiten datos hexadecimales (tipo BYTE). Por lo tanto, para mejorar la estabilidad de ejecución del programa, escribimos programas para la comunicación. Los datos de tipo BYTE se pueden ignorar.

Actualmente existen dos métodos populares de comunicación en serie: uno es utilizar el control CMSCOMM proporcionado por Microsoft para la comunicación, pero muchos programadores ahora sienten que este método debería abandonarse. El segundo es utilizar las funciones WINAPI para programar. Este tipo de programación es la más difícil y requiere que domines muchas funciones API. El tercero es escribir utilizando algunos controles de comunicación en serie proporcionados en la red actual, como la clase CSerial, etc.

Implementación del programa:

A través del desarrollo y la práctica de muchos proyectos, descubrí que el uso de las funciones API de WIN para el desarrollo del puerto serie puede brindar a los programadores mucho control y la operación del programa también. muy estable. Así que encapsulé las funciones que están en contacto con el puerto serie y luego las llamé en cada proyecto. El efecto fue relativamente bueno. Ahora enumero las diversas funciones y métodos de llamada.

1. Configuración del trabajo relacionado con el puerto serie

#define MAXBLOCK 2048

#define XON 0x11

#define XOFF 0x13

BOOL SetCom(HANDLE & m_hCom, const char *m_sPort, int BaudRate, int Databit, CString parity, CString stopbit)

{

COMMTIMEOUTS TimeOuts; /Configuración del tiempo de espera de salida del puerto serie

DCB dcb; /// Puerto coincidente del dispositivo

m_hCom=CreateFile(m_sPort, GENERIC_READ | GENERIC_WRITE, 0, NULL,

OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED,

NULL); // Abre el puerto serie en modo superpuesto

if(m_hCom==INVALID_HANDLE_VALUE)

{

AfxMessageBox("Configurando la parte del puerto serie, falló la apertura del puerto serie"); ///// La función de comunicación asincrónica superpuesta (INVALID_HANDLE_VALUE) falló.

return FALSE;

}

SetupComm(m_hCom, MAXBLOCK, MAXBLOCK); //Establecer búfer

memset(amp; TimeOuts) , 0, sizeof(TimeOuts));

TimeOuts.ReadIntervalTimeout=MAXDWORD; // Establecer el tiempo de espera del intervalo al máximo y establecer el tiempo de espera total en 0 hará que ReadFile regrese inmediatamente y complete la operación.

p>

TimeOuts.ReadTotalTimeoutMultiplier=0; //Leer coeficiente de tiempo

TimeOuts.ReadTotalTimeoutConstant=0; //Leer constante de tiempo

TimeOuts.WriteTotalTimeoutMultiplier=50; timeout= Coeficiente de tiempo * Número de caracteres necesarios para leer/escribir la constante de tiempo

TimeOuts.WriteTotalTimeoutConstant=2000 //Establezca el tiempo de espera de escritura para especificar el tiempo de espera de escritura en la función miembro WriteComm

SetCommTimeouts(m_hCom, amp; TimeOuts); //Tiempo de espera de la función GetOverlappedResult*/

if(!GetCommState(m_hCom, amp; dcb)) ////Modo de apertura del puerto serie, puerto, velocidad en baudios y dispositivo que coinciden con el puerto

{

AfxMessageBox("GetCommState Failed");

return FALSE

}

dcb.fParity =TRUE; //Permitir paridad

dcb.fBinary=TRUE;

if(parity=="NONE")

dcb.Parity=NOPARIDAD ;

if(parity=="ODD")

dcb.Parity=ODDPARITY;

if(parity=="PARIDAD ")

dcb.Parity=EVENPARITY;

if(stopbit=="1")//Establecer la velocidad en baudios

dcb.StopBits=ONESTOPBIT;

//if(stopbit=="0")//Establecer la velocidad en baudios

// dcb.StopBits=NONESTOPBIT;

if(stopbit= ="2")/ /Establecer velocidad en baudios

dcb.StopBits=T

WOSTOPBITS;

BOOL m_bEcho=FALSE; ///

int m_nFlowCtrl=0

BOOL m_bNewLine=FALSE; > dcb.BaudRate=BaudRate; // Velocidad en baudios

dcb.ByteSize=Databit; // Bits por byte

// Configuración de control de flujo de hardware

dcb .fOutxCtsFlow=m_nFlowCtrl==1;

dcb.fRtsControl=m_nFlowCtrl==1 ?RTS_CONTROL_HANDSHAKE: RTS_CONTROL_ENABLE

// Configuración de control de flujo XON/XOFF (¡control de flujo de software!)

dcb.fInX=dcb.fOutX=m_nFlowCtrl==2;

dcb.XonChar=XON

dcb.XoffChar=XOFF; p> p>

dcb.XonLim=50;

dcb. TRUE; //// configuración del puerto de comunicación com

else

{

AfxMessageBox("El puerto serie se ha abierto, la configuración falló");

return FALSE

}

}

2. Operación de lectura del puerto serie:

int ReadCom(HANDLE hComm, BYTE inbuff [], DWORD&nBytesRead, int ReadTime)

{

DWORD lrc ; /// Verificación de redundancia vertical

DWORD endtime; /// //////jiesuo

static OVERLAPPED

int ReadNumber=0;

int numCount=0; //Controla el número de lecturas

DWORD dwErrorMask, nToRead

COMSTAT comstat; Offset=0; ///Desplazamiento de bytes relativo al comienzo del archivo

ol.OffsetHi

gh=0; /// La palabra de orden superior del desplazamiento de bytes para comenzar a transmitir datos, que el proceso de llamada puede ignorar durante las canalizaciones y las comunicaciones.

ol.hEvent=NULL; /// Identificar evento, establecido para señalar el estado cuando se completa la transmisión de datos

ol.hEvent=CreateEvent(NULL, TRUE, FALSE, NULL);

endtime=GetTickCount() ReadTime; //GetTickCount() recupera el tiempo (milisegundos) que tarda el sistema desde el principio hasta este punto

for(int i=0; ilt ; 2000; i )

inbuff[i]=0;

Sleep(ReadTime);

ClearCommError(hComm, y dwErrorMask, y comstat) ;

nToRead=min(2000, comstat.cbInQue);

if(int(nToRead)lt; 2)

ir a bucle

if(! ReadFile(hComm, inbuff, nToRead, nBytesRead, ol))

{

if((lrc=GetLastError())==ERROR_IO_PENDING)

{

////////////////////

endtime=GetTickCount() ReadTime //GetTickCount( ) recuperar El tiempo que le tomó al sistema llegar a este punto (milisegundos)

while(!GetOverlappedResult(hComm, amp; ol, amp; nBytesRead, FALSE))//Esta función recupera el resultado de la operación superpuesta

{

if(GetTickCount()gt; endtime)

break

}

}

}

devuelve 1;

Bucle: devuelve 0;

}

3. comandos de puerto

int WriteCom(HANDLE hComm, BYTE Outbuff[], int size, int bWrite[])

{

DWORD nBytesWrite, endtime, lrc;

static OVERLAPPED ol;

DWORD dwErrorMask, dwError;

COMSTAT comstat;

ol.hEvent=CreateEvent(NULL, TRUE, FALSO, NULO);

ol.Offset=0;

ol.Of

fsetHigh=0;

ol.hEvent=NULL; /// Identifica el evento Cuando se completa la transmisión de datos, configúrelo en el estado de señal

ClearCommError(hComm, amp; dwErrorMask, amp; comstat);

if(!WriteFile(hComm, Outbuff, size, & nBytesWrite, & ol))

{

if(( lrc =GetLastError())==ERROR_IO_PENDING)

{

endtime=GetTickCount() 1000;

while(!GetOverlappedResult(hComm, amp; ol, amp ;nBytesWrite, FALSE))

{

dwError=GetLastError();

if(GetTickCount()gt;endtime)

{

AfxMessageBox("El tiempo de escritura en el puerto serie es demasiado largo, el número actual de datos en el búfer de envío del puerto serie está vacío");

break; p>

}

if(dwError=ERROR_IO_INCOMPLETE)

continuar; //Resultado de retorno normal cuando no se ha leído completamente

else

{

// Se produjo un error, ¡intenta recuperarlo!

ClearCommError(hComm, y dwError, y comstat;

break

}

}

<); p> }

}

FlushFileBuffers(hComm);

PurgeComm(hComm, PURGE_TXCLEAR);

bWrite=0; p>

p>

return 1;

}

Cuatro. El método de llamada es muy simple. Solo necesita configurar los parámetros del puerto serie.

Por ejemplo:

BOOL Main_OpenCom()//Establecer COM

{

int Boundrate=9600 //Velocidad en baudios

CString; StopBits="1"; //Bits de parada

int DataBits=8; //Bits de datos

CString Parity="ODD" //Verificación de paridad

CString m_Port="COM1";

return SetCom(m_hCom1, m_Port, Boundrate, DataBits, Parity, StopBits)

}

void Main( )

{

int TAMAÑO;

DWORD BytestoRead=52*Cuenta 6; //11 bytes requeridos

int BWRITE [2]

int ReadTime=2000;

BYTE Outbuff[12]={0xff, 0x00, 0xea, 0xff, 0xea, 0xff, 0, 0, 0, 0, 0, 0 };

TAMAÑO=sizeof(Outbuff);

WriteCom(m_hCom, Outbuff, TAMAÑO, BWRITE

ReadCom(m_hCom, m_Inbuff, BytestoRead, ReadTime); );

//Realizar el procesamiento de desembalaje de Xiangyin

}

">Red de conocimientos turísticos All Rights Reserved.