运行超级终端或Docklight之后,我的程序可以运行(写入并读取OK)。但是,如果我从不执行任何操作,则所有读取操作都会失败。

因此,我想我的串行端口初始化代码中肯定缺少某些内容,但是我无法弄清楚是什么。这里是:

串口初始化:

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;
}


串行端口类(相关代码):

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;
}

最佳答案

您应该先打开端口,然后再配置。和您的代码以相反的方向。这就是为什么您的配置代码不起作用,并且仅使用默认设置打开端口的原因。

看一下您的代码:

BOOL CSerialPort::Config( SConfig sConfig ) {
    if( !m_hFile ) return FALSE;
 ....


并且m_hFileCSerialPort::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);
 .....


看来您的hyper terminal程序会调整默认设置,这就是为什么在使用`hyper terminal后打开端口时会打开正确设置的原因。

关于c++ - 串口写成功,读失败,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/8538070/

10-13 06:29