bState=WriteFile(
hCom, // handle to file to write to
transData, // pointer to data to write to file
8, // number of bytes to write
&sent_number, // pointer to number of bytes written
NULL // pointer to structure for overlapped I/O
);
if (!bState)
{
return 0x10;
}
bState=ReadFile(
hCom,
readData,
5+ucCountReg*2,
&read_number,
NULL
);
if (!bState) return 0x10;
Проблемы с ReadFile при работе с COM портом
Возникла следующая неприятная особенность при работе с COM портом.
Суть программы в том, что она в начале посылает запрос устройству, а потом считывает ответ. Это реализовано примерно так:
Код:
В принципе работает без нареканий. НО!
Если остановить работу программы и запустить какую-нибудь другую программу (использующую тот же порт), а потом её выключить, то при запуске моей программы запись в порт осуществляется без проблем (т.е. bState и sent_number корректны), а вот при чтении возвращает read_number=0. Приходится отключать преобразователь USB<->RS485 (который в системе регистрируется как COM порт) и включать его заново.
В чём может быть проблема?
Код:
GetCommMask( hPort, &dwEvtMask );
SetCommMask( hPort, dwEvtMask|EV_RXCHAR );
WaitCommEvent( hPort, &dwEvtMask, 0 );
if( dwEvtMask & EV_RXCHAR )
{
ReadFile( hPort,... );
}
SetCommMask( hPort, dwEvtMask|EV_RXCHAR );
WaitCommEvent( hPort, &dwEvtMask, 0 );
if( dwEvtMask & EV_RXCHAR )
{
ReadFile( hPort,... );
}
P.S.
Возможно твоя программа открывает соединение на другой частоте.
Также настрой тайм-ауты (SetCommTimeouts).
Можешь проверить с помощью функции GetCommConfig, затем установить нужные параметры порта через SetCommConfig или SetCommState
Код:
BOOL PortSetup( HANDLE hPort )
{
DCB PortDCB;
PortDCB.DCBlength = sizeof (DCB);
GetCommState (hPort, &PortDCB);
PortDCB.BaudRate = CBR_9600; // частота
PortDCB.fBinary = TRUE;
PortDCB.fParity = FALSE;
PortDCB.fOutxCtsFlow = FALSE;
PortDCB.fOutxDsrFlow = FALSE;
PortDCB.fDtrControl = DTR_CONTROL_DISABLE;
PortDCB.fDsrSensitivity = FALSE;
PortDCB.fTXContinueOnXoff = TRUE;
PortDCB.fOutX = FALSE;
PortDCB.fInX = FALSE;
PortDCB.fErrorChar = FALSE;
PortDCB.fNull = FALSE;
PortDCB.fRtsControl = RTS_CONTROL_DISABLE;
PortDCB.fAbortOnError = FALSE;
PortDCB.ByteSize = 8;
PortDCB.Parity = NOPARITY;
PortDCB.StopBits = ONESTOPBIT;
if( !SetCommState (hPort, &PortDCB) )
return FALSE;
COMMTIMEOUTS CommTimeouts;
GetCommTimeouts (hPort, &CommTimeouts);
CommTimeouts.ReadIntervalTimeout = -1;
CommTimeouts.ReadTotalTimeoutMultiplier = 0;
CommTimeouts.ReadTotalTimeoutConstant = 0;
CommTimeouts.WriteTotalTimeoutMultiplier = 10;
CommTimeouts.WriteTotalTimeoutConstant = 1000;
if( !SetCommTimeouts (hPort, &CommTimeouts) )
return FALSE;
PurgeComm( hPort,
PURGE_TXABORT | PURGE_RXABORT |
PURGE_TXCLEAR | PURGE_RXCLEAR );
return TRUE;
}
{
DCB PortDCB;
PortDCB.DCBlength = sizeof (DCB);
GetCommState (hPort, &PortDCB);
PortDCB.BaudRate = CBR_9600; // частота
PortDCB.fBinary = TRUE;
PortDCB.fParity = FALSE;
PortDCB.fOutxCtsFlow = FALSE;
PortDCB.fOutxDsrFlow = FALSE;
PortDCB.fDtrControl = DTR_CONTROL_DISABLE;
PortDCB.fDsrSensitivity = FALSE;
PortDCB.fTXContinueOnXoff = TRUE;
PortDCB.fOutX = FALSE;
PortDCB.fInX = FALSE;
PortDCB.fErrorChar = FALSE;
PortDCB.fNull = FALSE;
PortDCB.fRtsControl = RTS_CONTROL_DISABLE;
PortDCB.fAbortOnError = FALSE;
PortDCB.ByteSize = 8;
PortDCB.Parity = NOPARITY;
PortDCB.StopBits = ONESTOPBIT;
if( !SetCommState (hPort, &PortDCB) )
return FALSE;
COMMTIMEOUTS CommTimeouts;
GetCommTimeouts (hPort, &CommTimeouts);
CommTimeouts.ReadIntervalTimeout = -1;
CommTimeouts.ReadTotalTimeoutMultiplier = 0;
CommTimeouts.ReadTotalTimeoutConstant = 0;
CommTimeouts.WriteTotalTimeoutMultiplier = 10;
CommTimeouts.WriteTotalTimeoutConstant = 1000;
if( !SetCommTimeouts (hPort, &CommTimeouts) )
return FALSE;
PurgeComm( hPort,
PURGE_TXABORT | PURGE_RXABORT |
PURGE_TXCLEAR | PURGE_RXCLEAR );
return TRUE;
}