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

📄 win16.cpp

📁 DOS下采用中断接收数据的串口通讯的例子,很难找到的好东西!
💻 CPP
📖 第 1 页 / 共 2 页
字号:
    if ( error_status < RS232_SUCCESS )
        return error_status;
    SetCommBreak( handle );
    timer = ReadTime() + milliseconds;
    while ( ReadTime() < timer )
        IdleFunction();
    ClearCommBreak( handle );
    return RS232_SUCCESS;
}

// The four Modem Status routines all take advantage of directly
// peeking at the MSR byte inside the driver.  They just mask off
// the bit they are interested in, and return a logical result to
// the calling routine.

int Win16Port::Cd( void )
{
    if ( error_status < RS232_SUCCESS )
        return error_status;
    return ( *modem_status_register & MSR_CD ) != 0;
}

int Win16Port::Ri( void )
{
    if ( error_status < RS232_SUCCESS )
        return error_status;
    return ( *modem_status_register & MSR_RI ) != 0;
}

int Win16Port::Cts( void )
{
    if ( error_status < RS232_SUCCESS )
        return error_status;
    return ( *modem_status_register & MSR_CTS ) != 0;
}

int Win16Port::Dsr( void )
{
    if ( error_status < RS232_SUCCESS )
        return error_status;
    return ( *modem_status_register & MSR_DSR ) != 0;
}

// The four line status routines and the software overrrun error
// detect routine all get their information from the
// Windows API function GetCommError().  It returns all the line
// status bits, rearranged by Windows just for fun.

int Win16Port::SoftwareOverrunError( int clear )
{
    COMSTAT comstat;
    int return_value;

    if ( error_status < RS232_SUCCESS )
        return error_status;
    line_status |= GetCommError( handle, &comstat );
    return_value = ( ( line_status & CE_RXOVER ) != 0 );
    if ( clear != UNCHANGED && clear != 0 )
        line_status &= ~CE_RXOVER;
    return return_value;
}

int Win16Port::ParityError( int reset )
{
    COMSTAT comstat;
    int return_value;

    if ( error_status < RS232_SUCCESS )
        return error_status;
    line_status |= GetCommError( handle, &comstat );
    return_value = ( ( line_status & CE_RXPARITY ) != 0 );
    if ( reset != UNCHANGED && reset != 0 )
        line_status &= ~CE_RXPARITY;
    return return_value;
}

int Win16Port::BreakDetect( int reset )
{
    COMSTAT comstat;
    int return_value;

    if ( error_status < RS232_SUCCESS )
        return error_status;
    line_status |= GetCommError( handle, &comstat );
    return_value = ( ( line_status & CE_BREAK ) != 0 );
    if ( reset != UNCHANGED && reset != 0 )
        line_status &= ~CE_BREAK;
    return return_value;
}

int Win16Port::FramingError( int reset )
{
    COMSTAT comstat;
    int return_value;

    if ( error_status < RS232_SUCCESS )
        return error_status;
    line_status |= GetCommError( handle, &comstat );
    return_value = ( ( line_status & CE_FRAME ) != 0 );
    if ( reset != UNCHANGED && reset != 0 )
        line_status &= ~CE_FRAME;
    return return_value;
}

int Win16Port::HardwareOverrunError( int reset )
{
    COMSTAT comstat;
    int return_value;

    if ( error_status < RS232_SUCCESS )
        return error_status;
    line_status |= GetCommError( handle, &comstat );
    return_value = ( ( line_status & CE_OVERRUN ) != 0 );
    if ( reset != UNCHANGED && reset != 0 )
        line_status &= ~CE_OVERRUN;
    return return_value;
}

// All of the handshaking functions rely on write_settings() to do
// the dirty work of actually changing the settings.  They then
// return the current setting to the caller.

int Win16Port::XonXoffHandshaking( int setting )
{
    if ( error_status < RS232_SUCCESS )
        return error_status;
    if ( setting != UNCHANGED ) {
        settings.XonXoff = ( setting != 0 );
        write_settings();
    }
    return( settings.XonXoff );
}

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

int Win16Port::DtrDsrHandshaking( int setting )
{
    if ( error_status < RS232_SUCCESS )
        return error_status;
    if ( setting != UNCHANGED ) {
        settings.DtrDsr = ( setting != 0 );
        write_settings();
    }
    return( settings.DtrDsr );
}

// Setting DTR and RTS is done with a Windows API Escape code.
// The escape sequence is undocumented but widely known, and
// used by so much software it is unlikely to ever change.

int Win16Port::Dtr( int setting )
{
    if ( error_status < RS232_SUCCESS )
        return error_status;
    if ( setting != UNCHANGED ) {
        if ( settings.DtrDsr == 1 )
            return WINDOWS_PORT_HANDSHAKE_LINE_IN_USE;
        else {
            if ( ( settings.Dtr = setting ) == 1 )
                EscapeCommFunction( handle, SETDTR );
            else
                EscapeCommFunction( handle, CLRDTR ); 
        }
    }
    return settings.Dtr;
}

int Win16Port::Rts( int setting )
{
    if ( error_status < RS232_SUCCESS )
        return error_status;
    if ( setting != UNCHANGED ) {
        if ( settings.RtsCts == 1 )
            return WINDOWS_PORT_HANDSHAKE_LINE_IN_USE;
        else {
            if ( ( settings.Rts = setting ) == 1 )
                EscapeCommFunction( handle, SETRTS );
            else
                EscapeCommFunction( handle, CLRRTS ); 
        }
    }
    return settings.Rts;
}

// All the information needed to perform the following functions is
// found in the COMSTAT function returned by GetCommError().


int Win16Port::RXSpaceFree( void )
{
    COMSTAT comstat;

    if ( error_status < RS232_SUCCESS )
        return error_status;
    line_status |= GetCommError( handle, &comstat );
    return INPUT_BUFFER_SIZE - comstat.cbInQue;
}

int Win16Port::TXSpaceUsed( void )
{
    COMSTAT comstat;

    if ( error_status < RS232_SUCCESS )
        return error_status;
    line_status |= GetCommError( handle, &comstat );
    return comstat.cbOutQue;
}

// The Windows API provides a dedicated function to perform this task.

int Win16Port::FlushTXBuffer( void )
{
    int status;

    if ( error_status < RS232_SUCCESS )
        return error_status;
    status = FlushComm( handle, 0 );
    if ( status != 0 )
        return translate_windows_error( status );
    return RS232_SUCCESS;
}

// The debug output includes a complete dump of the current DCB
// structure for the port, which describes virtually everything
// windows knows about the port.  The only thing left out here
// which could be interesting in the COMSTAT structure.

int Win16Port::FormatDebugOutput( char *buffer, int line_number )
{
    if ( buffer == 0 )
        return( first_debug_output_line +  7 );
    if ( line_number < first_debug_output_line )
        return RS232::FormatDebugOutput( buffer, line_number );
    switch( line_number - first_debug_output_line ) {
        case 0 :
            wsprintf( buffer,
                      (LPSTR) "Derived class: Win16Port  "
                      "Ri: %2d  Cts: %2d  Cd: %2d  Dsr: %2d  "
                      "RX Overrun: %d",
                      Ri(), Cts(), Cd(), Dsr(),
                      SoftwareOverrunError() );
            break;
        case 1 :
            wsprintf( buffer,
                      "TX Used: %5d   RX Free: %5d  "
                      "Parity Err: %d  Break: %d  "
                      "Overrun: %d  Framing Err: %d",
                      TXSpaceUsed(), RXSpaceFree(),
                      ParityError(),
                      BreakDetect(),
                      HardwareOverrunError(),
                      FramingError() );
            break;
        case 2 :
            wsprintf( buffer,
                      "DCB: RlsTimeout: %04x  CtsTimeout: %04x  "
                      "DsrTimeout: %04x  fBinary: %1d",
                      dcb.RlsTimeout,
                      dcb.CtsTimeout,
                      dcb.DsrTimeout,
                      dcb.fBinary );
            break;
        case 3 :
            wsprintf( buffer,
                      "DCB: fRtsDisable: %1d  fParity: %1d  "
                      "fOutxCtsFlow: %1d  fOutxDsrFlow: %1d",
                      dcb.fRtsDisable,
                      dcb.fParity,
                      dcb.fOutxCtsFlow,
                      dcb.fOutxDsrFlow );
            break;
        case 4 :
            wsprintf( buffer,
                      "DCB: fDtrDisable: %1d  fOutX: %1d  fInx: %1d  "
                      "fPeChar: %1d  fNull: %1d  fChEvt: %1d",
                      dcb.fDtrDisable,
                      dcb.fOutX,
                      dcb.fInX,
                      dcb.fPeChar,
                      dcb.fNull,
                      dcb.fChEvt );
            break;
        case 5 :
            wsprintf( buffer,
                      "DCB: fDtrflow: %1d  fRtsflow: %1d  XonChar: %02x  "
                      "XoffChar: %02x  XonLim: %04x  XoffLim: %04x",
                      dcb.fDtrflow,
                      dcb.fRtsflow,
                      dcb.XonChar,
                      dcb.XoffChar,
                      dcb.XonLim,
                      dcb.XoffLim );
            break;
        case 6 :
            wsprintf( buffer,
                      "DCB: PeChar: %02x  EofChar: %02x  EvtChar: %02x  "
                      "TxDelay:  %04x",
                      dcb.PeChar,
                      dcb.EofChar,
                      dcb.EvtChar,
                      dcb.TxDelay );
            break;
        default :
            return RS232_ILLEGAL_LINE_NUMBER;
    }
    return RS232_SUCCESS;
}


char * Win16Port::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 WINDOWS_PORT_DEFAULT_PARAMETERS :
            return "Default parameters in error";
        case WINDOWS_PORT_NOT_OPEN :
            return "Port not open";
        case WINDOWS_PORT_ALREADY_OPEN :
            return "Port already open";
        case WINDOWS_PORT_HANDSHAKE_LINE_IN_USE :
            return "Handshake line in use";
        default :
            return( "Undefined error" );
    }
}

// For Win16 we need a pair of OS specific routines to handle a couple
// of timing issues properly. In a program that really uses the idle
// function you might want to replace this function with one that
// performs a PeekMessage() call

int RS232::IdleFunction( void )
{
    return RS232_SUCCESS;
}

//
// ReadTime() returns the current time of day in milliseconds.  It uses
// the Windows specific tick count function, instead of polling MS-DOS
// or the BIOS.
//

long ReadTime( void )
{
    return GetTickCount();
}

// ******************** END OF WIN16.CPP ********************

⌨️ 快捷键说明

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