⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 win32port.cpp

📁 DOS下采用中断接收数据的串口通讯的例子,很难找到的好东西!
💻 CPP
📖 第 1 页 / 共 5 页
字号:
    }
    return settings.Dtr;
}

//
// This is an implementation of the virtual Rts() function from
// the base class RS232. It doesn't have to do too much work, it
// merely updates the settings member and then calls the
// write_settings() member function to do all the work. It does
// check to see if RTS/CTS handshaking is in place, and if it is,
// it returns a non-fatal warning to the calling routine. If that
// doesn't happen, it updates the Rts member in the settings
// object and calls write_settings() to update the physical port.
// Note that it returns the current setting of the Rts member. If
// this function is called with no arguments by the end user, it
// doesn't do anything except return that value.
//

int Win32Port::Rts( int setting /* = UNCHANGED */ )
{
    if ( error_status < RS232_SUCCESS )
        return error_status;
    if ( setting != UNCHANGED ) {
        if ( settings.RtsCts == 1 )
            return WIN32_HANDSHAKE_LINE_IN_USE;
        settings.Rts = setting != 0;
        RS232Error error = write_settings();
        if ( error < RS232_SUCCESS )
            return error;
    }
    return settings.Rts;
}

//
// This is the local implementation of the RS232 member function
// DtrDsrHandshaking. All it has to do is set the member in the
// settings function, then rely on the write_settings() member to
// do all the work. Note that setting this handshaking type to be
// true means that you no longer have direct control over the DTR
// output line. Any attempt to modify DTR will be futile until
// this handshaking value is turned back off.
//
// After finishing its work, this function returns the setting of
// DTR/DSR handshaking for the port. Note that if the user calls
// it with no arguments, it will skip all the setting work and
// just return the value of the current setting.
//
int Win32Port::DtrDsrHandshaking( int setting /* = UNCHANGED */ )
{
    if ( error_status < RS232_SUCCESS )
        return error_status;
    if ( setting != UNCHANGED ) {
        settings.DtrDsr = setting != 0;
        RS232Error error = write_settings();
        if ( error < RS232_SUCCESS )
            return error;
    }
    return settings.DtrDsr;
}

//
// This is the local implementation of the RS232 member function
// RtsCtsHandshaking. All it has to do is set the member in the
// settings function, then rely on the write_settings() member to
// do all the work. Note that setting this handshaking type to be
// true means that you no longer have direct control over the RTS
// output line. Any attempt to modify RTS will be futile until
// this handshaking value is turned back off.
//
// After finishing its work, this function returns the setting of
// RTS/CTS handshaking for the port. Note that if the user calls
// it with no arguments, it will skip all the setting work and
// just return the value of the current setting.
//

int Win32Port::RtsCtsHandshaking( int setting )
{
    if ( error_status < RS232_SUCCESS )
        return error_status;
    if ( setting != UNCHANGED ) {
        settings.RtsCts = setting != 0;
        RS232Error error = write_settings();
        if ( error < RS232_SUCCESS )
            return error;
    }
    return settings.RtsCts;
}

//
// This member function is called to either check or modify the
// current software handshaking state of the port. It doesn't have
// to do any of the hard work, that is all taken care of by the
// write_settings() member of the class. The function returns
// the current state of software handshaking in the port. Note that
// if it is called with no argument, it will skip over all of the
// code that modifies the value and simply return the current state.
//
int Win32Port::XonXoffHandshaking( int setting /* = UNCHANGED */ )
{
    if ( error_status < RS232_SUCCESS )
        return error_status;
    if ( setting != UNCHANGED ) {
        settings.XonXoff = setting != 0;
        RS232Error error = write_settings();
        if ( error < RS232_SUCCESS )
            return error;
    }
    return settings.XonXoff;
}

//
// The following four functions implement the RS232 class
// member functions that return the values of the modem
// status lines. In this case all four functions are so similar
// that there is no point in documenting them individually.
//
// All of these functions simply look at a specific bit in the
// m_dwModemStatus word to see if their individual status line is
// set. The modem status word is read in every time we see a change
// in the status lines. We have set up WaitCommEvent so that it
// should signal an event every time one of the status lines
// changes.
//
// Note that you can set up a derived class so that your app is notified
// every time one of the lines change. This is particularly valuable
// for monitoring the RI line, as it may be difficult to catch an 
// incoming ring in progress.
//

int Win32Port::Cd()
{
    return ( MS_RLSD_ON & m_dwModemStatus ) != 0;
}

int Win32Port::Cts()
{
    return ( MS_CTS_ON & m_dwModemStatus ) != 0;
}

int Win32Port::Dsr()
{
    return ( MS_DSR_ON & m_dwModemStatus ) != 0;
}

int Win32Port::Ri()
{
    return ( MS_RING_ON & m_dwModemStatus ) != 0;
}

//
// Just like the four modem status routines, the four line status
// error routines all take the same form. Each of the checks the
// m_dwErrors for their specific error bit, returning true if the
// bit is set and false if it is not. If the caller invoked the function
// with the clearing option, the bit in the cumulative line status
// error word will be cleared.
//
int Win32Port::ParityError( int clear /* = UNCHANGED */ )
{
    int return_value;

    if ( error_status < RS232_SUCCESS )
        return error_status;
    return_value = ( m_dwErrors & CE_RXPARITY ) != 0;
    if ( clear != UNCHANGED && clear != 0 ) 
        m_dwErrors &= ~CE_RXPARITY;
    return return_value;
}

int Win32Port::FramingError( int clear /* = UNCHANGED */ )
{
    int return_value;

    if ( error_status < RS232_SUCCESS )
        return error_status;
    return_value = ( m_dwErrors & CE_FRAME ) != 0;
    if ( clear != UNCHANGED && clear != 0 ) 
        m_dwErrors &= ~CE_FRAME;
    return return_value;
}

int Win32Port::HardwareOverrunError( int clear /* = UNCHANGED */ )
{
    int return_value;

    if ( error_status < RS232_SUCCESS )
        return error_status;
    return_value = ( m_dwErrors & CE_OVERRUN ) != 0;
    if ( clear != UNCHANGED && clear != 0 ) 
        m_dwErrors &= ~CE_OVERRUN;
    return return_value;
}

int Win32Port::BreakDetect( int clear /* = UNCHANGED */ )
{
    int return_value;

    if ( error_status < RS232_SUCCESS )
        return error_status;
    return_value = ( m_dwErrors & CE_BREAK ) != 0;
    if ( clear != UNCHANGED && clear != 0 ) 
        m_dwErrors &= ~CE_BREAK;
    return return_value;
}

//
// This routine acts just like the previous four. The only
// difference is the type of error being handled. The software
// overrun error is set when the driver receives a character
// but doesn't have room to store it. Unfortunately, there isn't
// an EV_XXXX routine to force this error to generate an event
// when it happens, so we end up checking the comm status
// after every input packet.
//
int Win32Port::SoftwareOverrunError( int clear /* = UNCHANGED */ )
{
    int return_value;

    if ( error_status < RS232_SUCCESS )
        return error_status;
    return_value = ( m_dwErrors & CE_RXOVER ) != 0;
    if ( clear != UNCHANGED && clear != 0 ) 
        m_dwErrors &= ~CE_RXOVER;
    return return_value;
}

//
// This function is called to provoke the output thread into sending
// a break of a specified duration. We haven't set up any path by
// which to set the duration of the break, instead we just stored
// the desired duration in the object, and count on the output thread
// checking there to see what it should be. The output thread is
// continually checking for the m_hBreakRequestEvent, and when it sees
// it, it faithfully sends the break.
//
int Win32Port::Break( long milliseconds )
{
    if ( milliseconds > 1000 )
        m_iBreakDuration = 1000;
    else
        m_iBreakDuration = milliseconds;
    SetEvent( m_hBreakRequestEvent );
    return RS232_SUCCESS;
}

//
// The Peek() function is fairly close to read_buffer(). It takes
// whatever it can get out the input buffer, and returns a count
// of bytes read in ByteCount. 
//
int Win32Port::Peek( void *buffer, unsigned int count )
{
    if ( error_status < RS232_SUCCESS )
        return error_status;
    ByteCount = m_RxQueue.Peek( (char *) buffer, count );
    ( (char *) buffer )[ ByteCount ] = '\0';
    return RS232_SUCCESS;
}


//
// The two FlushXxBuffer routines do the same things. Both calls
// have to take care to clear both the internal buffers used by
// the driver, plus the external buffers we keep in the class. One
// is done by a simple member of class MTQueue, the other by using
// a Win32 API call.
//
int Win32Port::FlushRXBuffer()
{
    if ( error_status < RS232_SUCCESS )
        return error_status;
    m_RxQueue.Clear();
    PurgeComm( m_hPort, PURGE_RXCLEAR ); 
    if ( !m_bInputThreadReading )
        SetEvent( m_hReadRequestEvent );
    return RS232_SUCCESS;
}

int Win32Port::FlushTXBuffer()
{
    if ( error_status < RS232_SUCCESS )
        return error_status;
    m_TxQueue.Clear();
    PurgeComm( m_hPort, PURGE_TXCLEAR ); 
    return RS232_SUCCESS;
}

//
// Since we have a few error codes that are unique to the Win32Port class,
// it makes sense to translate them ourselves when requested. That's what
// this function does. Note that most of the time it passes the job up to
// the base class.
//
char *Win32Port::ErrorName( int error )
{
    if ( error < RS232_NEXT_FREE_ERROR && error >= RS232_ERROR )
        return RS232::ErrorName( error );
    if ( error < RS232_NEXT_FREE_WARNING && error >= RS232_WARNING )
        return RS232::ErrorName( error );
    if ( error >= RS232_SUCCESS )
        return RS232::ErrorName( error );
    switch ( error ) {
        case WIN32_CHECK_WINDOWS_ERROR :
            return "Check Windows error code in m_dwWindowsError";
        case WIN32_SETTINGS_FAILURE :
            return "Failure to set port parameters";
        case WIN32_HANDSHAKE_LINE_IN_USE :
            return "Handshake line is already in use";
        default :
            return( "Undefined error" );
    }
}

//
// The last of our locally implemented versions of base class
// functions is FormatDebugOutput(). It should be fairly easy
// to figure out, it simply creates a line of output upon request.

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -