Serial port writes succeed, reads fail

僤鯓⒐⒋嵵緔 提交于 2019-12-11 15:24:59

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!