问题
After I run Hyper Terminal or Docklight, my program works (writes and reads OK). But if I never run any of those, all my reads fail.
So I guess I must be missing something in my serial port initialization code, but I can't figure out what. Here it is:
Serial port initialization:
bool CSerialPortDrivenHardware::InitSerialPort(){
m_SerialPort.Config( m_SerialPortConfig );
bool success = ( m_SerialPort.Open( m_SerialPortName ) == TRUE );
if( !success )
Log( LOG_TYPE_ERROR, "CSerialPortDrivenHardware", "InitSerialPort", "Could not establish serial port connection" );
else{
m_SerialPort.SetControlBit( DTR_CONTROL_BIT );
m_SerialPort.SetControlBit( RTS_CONTROL_BIT );
}
return success;
}
Serial port class (relevant code):
BOOL CSerialPort::Config( SConfig sConfig ) {
if( !m_hFile ) return FALSE;
DCB dcb;
if ( !::GetCommState( m_hFile, &dcb ) ) {
m_dwLastError = ::GetLastError();
return FALSE;
}
dcb.BaudRate = sConfig.dwBaudRate;
dcb.Parity = sConfig.bParity;
dcb.StopBits = sConfig.bStopBits;
dcb.ByteSize = sConfig.bDataBits;
if ( !::SetCommState( m_hFile, &dcb ) ) {
m_dwLastError = ::GetLastError();
return FALSE;
}
::Sleep(200);
return TRUE;
}
BOOL CSerialPort::Open( LPCSTR cszCOM ) {
CHAR sPortName[256] = "\\\\.\\";
strcat_s( sPortName, cszCOM );
m_strPortName = sPortName;
if( m_hFile )
return FALSE;
m_hFile = ::CreateFile( m_strPortName.c_str(), GENERIC_READ|GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL);
if( m_hFile == INVALID_HANDLE_VALUE )
m_hFile = NULL;
if( !m_hFile )
return FALSE;
SetFlags( 0 );
return TRUE;
}
void CSerialPort::SetFlags( DWORD dwFlags ) {
if( dwFlags & READMODE_BLOCKING )
SetTimeout( INFINITE );
else
SetTimeout( 0 );
}
void CSerialPort::SetTimeout( DWORD dwTimeout ) {
COMMTIMEOUTS sCommTimeouts;
if( !::GetCommTimeouts( m_hFile, &sCommTimeouts ) ) {
m_dwLastError = ::GetLastError();
return;
}
sCommTimeouts.ReadIntervalTimeout = 0;
sCommTimeouts.ReadTotalTimeoutMultiplier = 0;
sCommTimeouts.ReadTotalTimeoutConstant = dwTimeout;
if ( !::SetCommTimeouts( m_hFile, &sCommTimeouts ) )
m_dwLastError = ::GetLastError();
}
BOOL CSerialPort::SetControlBit( ESerialPortControlBit eControlBit ) {
if( !m_hFile )
return FALSE;
BOOL bResult = FALSE;
switch( eControlBit ) {
case DTR_CONTROL_BIT:
bResult = ::EscapeCommFunction( m_hFile, SETDTR );
break;
case RTS_CONTROL_BIT:
bResult = ::EscapeCommFunction( m_hFile, SETRTS );
break;
}
return bResult;
}
回答1:
You should first open port, than configure. And your code does it in opposite direction. That's why your configure code does not work and port just opens with default settings.
Just look your code:
BOOL CSerialPort::Config( SConfig sConfig ) {
if( !m_hFile ) return FALSE;
....
And m_hFile is set in CSerialPort::Open
BOOL CSerialPort::Open( LPCSTR cszCOM ) {
CHAR sPortName[256] = "\\\\.\\";
strcat_s( sPortName, cszCOM );
m_strPortName = sPortName;
if( m_hFile )
return FALSE;
m_hFile = ::CreateFile( m_strPortName.c_str(), GENERIC_READ|GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL);
.....
It seems your hyper terminal program adjust default settings and that's why when you open port after using `hyper terminal it opens with correct settings.
来源:https://stackoverflow.com/questions/8538070/serial-port-writes-succeed-reads-fail