串口写入成功,读取失败

时间:2011-12-16 17:45:18

标签: c++ windows serial-port

运行超级终端或Docklight后,我的程序正常工作(写入和读取正常)。但是,如果我从未运行任何这些,我的所有读数都会失败。

所以我想我必须在我的串口初始化代码中遗漏一些东西,但我无法弄清楚是什么。这是:

串口初始化:

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

1 个答案:

答案 0 :(得分:3)

首先应该打开端口,而不是配置。而你的代码则反方向。这就是为什么您的配置代码不起作用,端口只是打开默认设置。

看看你的代码:

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

m_hFile

中设置了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);
 .....

您的hyper terminal程序似乎调整了默认设置,这就是为什么当您使用`hyper terminal打开端口后,它会以正确的设置打开。