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

📄 serialstreambuf.cc

📁 linux下串口通讯用的类库 c++编写
💻 CC
📖 第 1 页 / 共 2 页
字号:
#include <iostream>#ifndef _sys_types_h_INCLUDED_#    include <sys/types.h>#    define _sys_types_h_INCLUDED_#endif#ifndef _sys_stat_h_INCLUDED_#    include <sys/stat.h>#    define _sys_stat_h_INCLUDED_#endif#ifndef _fcntl_h_INCLUDED_#    include <fcntl.h>#    define _fcntl_h_INCLUDED_#endif#ifndef _unistd_h_INCLUDED_#    include <unistd.h>#    define _unistd_h_INCLUDED_#endif#ifndef _std_cassert_INCLUDED_#    include <cassert>#    define _std_cassert_INCLUDED_#endif#ifndef _std_fstream_INCLUDED_#    include <fstream>#    define _std_fstream_INCLUDED_#endif#ifndef _limits_h_INCLUDED_#    include <limits.h>#    define _limits_h_INCLUDED_#endif#ifndef _SerialStreamBuf_h_#    include "SerialStreamBuf.h"#endifusing namespace std ;using namespace LibSerial ;//// Set the values of the static members of the SerialStream class. //const SerialStreamBuf::BaudRateEnum  SerialStreamBuf::DEFAULT_BAUD            = BAUD_9600          ;const SerialStreamBuf::CharSizeEnum  SerialStreamBuf::DEFAULT_CHAR_SIZE       = CHAR_SIZE_7        ;const short                          SerialStreamBuf::DEFAULT_NO_OF_STOP_BITS = 1                  ;const SerialStreamBuf::ParityEnum    SerialStreamBuf::DEFAULT_PARITY          = PARITY_NONE        ;const SerialStreamBuf::FlowControlEnumSerialStreamBuf::DEFAULT_FLOW_CONTROL    = FLOW_CONTROL_NONE  ;const shortSerialStreamBuf::DEFAULT_VMIN            = 1                  ;const shortSerialStreamBuf::DEFAULT_VTIME           = 0                  ;SerialStreamBuf*SerialStreamBuf::open( const string filename,                        ios_base::openmode mode ) {    //    // If the buffer is alreay open then we should not allow a call to    // another open().    //    if( is_open() != false ) {        return 0 ;    }    //    // We only allow three different combinations of ios_base::openmode    // so we can use a switch here to construct the flags to be used    // with the open() system call.    //    int flags ;    if ( mode == (ios_base::in|ios_base::out) ) {        flags = O_RDWR ;    } else if ( mode == ios_base::in ) {        flags = O_RDONLY ;    } else if ( mode == ios_base::out ) {        flags = O_WRONLY ;    } else {        return 0 ;    }    /* switch( mode ) {       case ios_base::in:       flags = O_RDONLY ;       break ;       case ios_base::out:       flags = O_WRONLY ;       break ;       case (ios_base::in|ios_base::out):       flags = O_RDWR ;       break ;       default:       return 0 ;       break ;       } */    //    // Since we are dealing with the serial port we need to use the    // O_NOCTTY option.    //    flags |= O_NOCTTY ;    //    // Try to open the serial port.     //    this->mFileDescriptor = ::open(filename.data(), flags) ;    if( -1 == this->mFileDescriptor ) {        return 0 ;    }    //    // Initialize the serial port.     //    if( -1 == this->InitializeSerialPort() ) {        return 0 ;    }    return this;}intSerialStreamBuf::InitializeSerialPort() {    //    // If we do not have a valid file descriptor then return with    // failure.    //    if( -1 == this->mFileDescriptor ) {        return -1 ;    }    //    // Use non-blocking mode while configuring the serial port.     //    int flags = fcntl(this->mFileDescriptor, F_GETFL, 0) ;    if( -1 == fcntl( this->mFileDescriptor,                      F_SETFL,                      flags | O_NONBLOCK ) ) {        return -1 ;    }    //    // Flush out any garbage left behind in the buffers associated    // with the port from any previous operations.     //    if( -1 == tcflush(this->mFileDescriptor, TCIOFLUSH) ) {        return -1 ;    }    //    // Set up the default configuration for the serial port.     //    if( -1 == this->SetParametersToDefault() ) {        return -1 ;    }    //    // Allow all further communications to happen in blocking     // mode.     //    flags = fcntl(this->mFileDescriptor, F_GETFL, 0) ;    if( -1 == fcntl( this->mFileDescriptor,                      F_SETFL,                      flags & ~O_NONBLOCK ) ) {        return -1 ;    }    //    // If we get here without problems then we are good; return a value    // different from -1.    //    return 0 ;}intSerialStreamBuf::SetParametersToDefault() {    if( -1 == mFileDescriptor ) {        return -1 ;    }    //    // Set all values (also the ones, which are not covered by the    // parametrisation-functions of this library).    //    struct termios tio;    tio.c_iflag = IGNBRK;    tio.c_oflag = 0;    tio.c_cflag = B19200 | CS8 | CLOCAL | CREAD;    tio.c_lflag = 0;    tio.c_line = '\0';    bzero( &tio.c_cc, sizeof(tio.c_cc) );    tio.c_cc[VTIME] = 0;    tio.c_cc[VMIN]  = 1;    if ( -1 == tcsetattr(mFileDescriptor,TCSANOW,&tio) ) {      return -1 ;    }    //    // Baud rate    //    if( BAUD_INVALID == SetBaudRate(DEFAULT_BAUD) ) {        return -1 ;    } ;    //    // Character size.     //    if( -1 == SetCharSize(DEFAULT_CHAR_SIZE) ) {        return -1 ;    }    //    // Number of stop bits.     //    if( -1 == SetNumOfStopBits(DEFAULT_NO_OF_STOP_BITS) ) {        return -1 ;    }    //    // Parity    //    if( -1 == SetParity(DEFAULT_PARITY) ) {        return -1 ;    }    //    // Flow control    //    if( -1 == SetFlowControl(DEFAULT_FLOW_CONTROL) ) {        return -1 ;    }    //    // VMin    //    if ( -1 == SetVMin(DEFAULT_VMIN) ) {        return -1 ;    }    //    // VTime    //    if ( -1 == SetVTime(DEFAULT_VTIME) ) {        return -1 ;    }    //    // All done. Return a value other than -1.     //    return 0 ;}const SerialStreamBuf::BaudRateEnumSerialStreamBuf::SetBaudRate(const BaudRateEnum baud_rate) {    if( -1 == mFileDescriptor ) {        return BAUD_INVALID ;    }    switch (baud_rate) {    case BAUD_50:    case BAUD_75:       case BAUD_110:      case BAUD_134:      case BAUD_150:      case BAUD_200:      case BAUD_300:      case BAUD_600:      case BAUD_1200:     case BAUD_1800:     case BAUD_2400:     case BAUD_4800:     case BAUD_9600:     case BAUD_19200:    case BAUD_38400:    case BAUD_57600:    case BAUD_115200:        //        // Get the current terminal settings.         //        struct termios term_setting ;        if( -1 == tcgetattr(mFileDescriptor, &term_setting) ) {            return BAUD_INVALID ;        }        //        // Modify the baud rate in the term_setting structure.        //        cfsetispeed( &term_setting, baud_rate ) ;        cfsetospeed( &term_setting, baud_rate ) ;        //        // Apply the modified termios structure to the serial         // port.         //        if( -1 == tcsetattr(mFileDescriptor, TCSANOW, &term_setting) ) {            return BAUD_INVALID ;        }        break ;    default:        //        // :TODO: Thu Jul 13 16:30:14 2000 Pagey        //        // There is obviously a problem if we reach here. The method        // must have been called with an invalid value of the baud        // rate. We should probably throw an exception here. I will        // print something on cerr for the time being but leave the        // stream in "good" state.         //        return BAUD_INVALID ;        break ;    } ;    //    // If we succeeded in setting the baud rate then we need to return    // the baud rate.     //    return BaudRate() ;}const SerialStreamBuf::BaudRateEnumSerialStreamBuf::BaudRate() const {    if( -1 == mFileDescriptor ) {        return BAUD_INVALID ;    }    //    // Get the current terminal settings.     //    struct termios term_setting ;    if( -1 == tcgetattr(mFileDescriptor, &term_setting) ) {        return BAUD_INVALID ;    }    //    // Read the input and output baud rates.     //    speed_t input_baud = cfgetispeed( &term_setting ) ;    speed_t output_baud = cfgetospeed( &term_setting ) ;    //    // Make sure that the input and output baud rates are    // equal. Otherwise, we do not know which one to return.    //    if( input_baud != output_baud ) {        return BAUD_INVALID ;     }    switch( input_baud ) {    case B50:         return BAUD_50 ; break ;    case B75:        return BAUD_75 ; break ;    case B110:         return BAUD_110 ; break ;    case B134:         return BAUD_134 ; break ;    case B150:        return BAUD_150 ; break ;    case B200:         return BAUD_200 ; break ;    case B300:        return BAUD_300 ; break ;    case B600:        return BAUD_600 ; break ;    case B1200:        return BAUD_1200 ; break ;    case B1800:        return BAUD_1800 ; break ;    case B2400:         return BAUD_2400 ; break ;    case B4800:        return BAUD_4800 ; break ;    case B9600:        return BAUD_9600 ; break ;    case B19200:        return BAUD_19200 ; break ;    case B38400:        return BAUD_38400 ; break ;    case B57600:        return BAUD_57600 ; break ;    case B115200:        return BAUD_115200 ; break ;    default:        return BAUD_INVALID ; // we return an invalid value in this case.         break ;    }    //    // The code should never reach here due to the fact that the default    // section of the above switch statement returns. So we force an    // abort here using an assertion which will always fail.    //    assert( false ) ;    return BAUD_INVALID ;}const SerialStreamBuf::CharSizeEnumSerialStreamBuf::SetCharSize(const CharSizeEnum char_size) {    if( -1 == mFileDescriptor ) {        return CHAR_SIZE_INVALID ;    }    switch(char_size) {    case CHAR_SIZE_5:    case CHAR_SIZE_6:    case CHAR_SIZE_7:    case CHAR_SIZE_8:        //        // Get the current terminal settings.         //        struct termios term_setting ;        if( -1 == tcgetattr(mFileDescriptor, &term_setting) ) {            return CHAR_SIZE_INVALID ;        }        //        // Set the character size to the specified value. If the character        // size is not 8 then it is also important to set ISTRIP. Setting        // ISTRIP causes all but the 7 low-order bits to be set to        // zero. Otherwise they are set to unspecified values and may        // cause problems. At the same time, we should clear the ISTRIP        // flag when the character size is 8 otherwise the MSB will always        // be set to zero (ISTRIP does not check the character size        // setting; it just sets every bit above the low 7 bits to zero).        //        if( char_size == CHAR_SIZE_8 ) {            term_setting.c_iflag &= ~ISTRIP ; // clear the ISTRIP flag.        } else {            term_setting.c_iflag |= ISTRIP ;  // set the ISTRIP flag.        }        term_setting.c_cflag &= ~CSIZE ;     // clear all the CSIZE bits.        term_setting.c_cflag |= char_size ;  // set the character size.         //        // Set the new settings for the serial port.         //        if( -1 == tcsetattr(mFileDescriptor, TCSANOW, &term_setting) ) {            return CHAR_SIZE_INVALID ;        }         break ;    default:        return CHAR_SIZE_INVALID ;        break ;    }    return this->CharSize() ;}const SerialStreamBuf::CharSizeEnumSerialStreamBuf::CharSize() const {    if( -1 == mFileDescriptor ) {        return CHAR_SIZE_INVALID ;    }    //    // Get the current terminal settings.     //    struct termios term_setting ;    if( -1 == tcgetattr(mFileDescriptor, &term_setting) ) {        return CHAR_SIZE_INVALID ;    }    //    // Extract the character size from the terminal settings.     //    int char_size = (term_setting.c_cflag & CSIZE) ;    switch( char_size ) {    case CS5:        return CHAR_SIZE_5 ; break ;    case CS6:        return CHAR_SIZE_6 ; break ;    case CS7:         return CHAR_SIZE_7 ; break ;    case CS8:        return CHAR_SIZE_8 ; break ;    default:        //        // If we get an invalid character, we set the badbit for the        // stream associated with the serial port.        //        return CHAR_SIZE_INVALID ;        break ;    } ;    return CHAR_SIZE_INVALID ;}shortSerialStreamBuf::SetNumOfStopBits(short stop_bits) {    if( -1 == mFileDescriptor ) {        return 0 ;    }    //    // Get the current terminal settings.     //    struct termios term_setting ;    if( -1 == tcgetattr(mFileDescriptor, &term_setting) ) {        return 0 ;    }    switch( stop_bits ) {    case 1:        term_setting.c_cflag &= ~CSTOPB ;        break ;    case 2:        term_setting.c_cflag |= CSTOPB ;        break ;    default:         return 0 ;        break ;    }    //    // Set the new settings for the serial port.     //    if( -1 == tcsetattr(mFileDescriptor, TCSANOW, &term_setting) ) {        return 0 ;    }     return this->NumOfStopBits() ;}short SerialStreamBuf::NumOfStopBits() const {    if( -1 == mFileDescriptor ) {        return 0 ;    }    //    // Get the current terminal settings.     //    struct termios term_setting ;    if( -1 == tcgetattr(mFileDescriptor, &term_setting) ) {        return 0 ;    }    //    // If CSTOPB is set then the number of stop bits is 2 otherwise it    // is 1.    //    if( term_setting.c_cflag & CSTOPB ) {        return 2 ; 

⌨️ 快捷键说明

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