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

📄 serial.cpp

📁 一个通讯管理机的源代码。比较好用。推荐
💻 CPP
字号:
#include "serial.h"#ifdef _UC7400#include <sys/ioctl.h>#include <moxadevice.h>#define RS232_MODE 0#define RS485_2WIRE_MODE 1#define RS422_MODE 2#define RS485_4WIRE_MODE 3#endifusing namespace Serial ;CSerialPortDef::CSerialPortDef(CChannelSet& setChannel){	m_wChannelNo = setChannel.m_wChannelNo;	m_strChannelName = setChannel.m_strChannelName;	m_strComName = setChannel.m_strComName;	m_dwIntervalMS = setChannel.m_dwIntervalMS;	switch (setChannel.m_lBaudRate)	{	case 300:		m_lBaudRate = BAUD_600;		break;	case 600:		m_lBaudRate = BAUD_600;		break;	case 1200:		m_lBaudRate = BAUD_1200;		break;	case 2400:		m_lBaudRate = BAUD_2400;		break;	case 4800:		m_lBaudRate = BAUD_4800;		break;	case 9600:		m_lBaudRate = BAUD_9600;		break;	case 19200:		m_lBaudRate = BAUD_19200;		break;	default:		m_lBaudRate = BAUD_9600;		break;	}	m_byStopBit = setChannel.m_byStopBit;	switch (setChannel.m_byDataBit)	{	case 5:		m_byDataBit = CHAR_SIZE_5;		break;	case 6:		m_byDataBit = CHAR_SIZE_6;		break;	case 7:		m_byDataBit = CHAR_SIZE_7;		break;	case 8:		m_byDataBit = CHAR_SIZE_8;		break;	default:		m_byDataBit = CHAR_SIZE_8;		break;	}	switch (setChannel.m_byParity)	{	case 0://无		m_byParity = PARITY_NONE;		break;	case 1://奇		m_byParity = PARITY_ODD;		break;	case 2://偶		m_byParity = PARITY_EVEN;		break;	default:		m_byParity = PARITY_NONE;		break;	}	m_bIsMaster = setChannel.m_bIsMaster; //front	if (setChannel.m_strKDL == string("CDT"))	{		/*			if (m_bIsMaster)			m_kdl = kdl_eCDTm;		else m_kdl = kdl_eCDTs;       */		m_kdl = kdl_eCDT;	}	else if (setChannel.m_strKDL == string("TA"))	{		m_kdl = kdl_eTA;	}	else if (setChannel.m_strKDL == string("ISA"))	{		m_kdl = kdl_eISA;	}	else if (setChannel.m_strKDL == string("SIMU"))	{		m_kdl = kdl_eSimu;	}	else if (setChannel.m_strKDL == string("SEPAM2000"))	{		m_kdl = kdl_eSepam2000;	}	else if (setChannel.m_strKDL == string("SEPAM1000"))	{		m_kdl = kdl_eSepam1000;	}	else if (setChannel.m_strKDL == string("PM500"))	{		m_kdl = kdl_ePM500;	}	else if (setChannel.m_strKDL == string("GDZL"))	{		m_kdl = kdl_eJDDY;	}	else if (setChannel.m_strKDL == string("GPS"))
	{
		m_kdl = kdl_eGPS;
	}	else if (setChannel.m_strKDL == string("DNP3"))	{		m_kdl = kdl_eDNP3;	}	else if (setChannel.m_strKDL == string("JA05"))	{		m_kdl = kdl_eJA05;	}	else if ((setChannel.m_strKDL == string("PMAC")) || (setChannel.m_strKDL == string("MODBUS-RTU")))	{		m_kdl = kdl_ePMAC;	}	else if (setChannel.m_strKDL == string("INT-BUS"))	{		m_kdl = kdl_eINTBUS;	}	else if (setChannel.m_strKDL == string("CSC2000"))	{		m_kdl = kdl_eCSC2000;	}	else if (setChannel.m_strKDL == string("BWD-3K130A"))	{		m_kdl = kdl_eBWD_3K130A;	}	else if (setChannel.m_strKDL == string("DATA86"))	{		m_kdl = kdl_eDATA86;	}	else if (setChannel.m_strKDL == string("YD2"))	{		m_kdl = kdl_eYD2;	}};bool CSerial::Open(){	bool bRet = true;	// If the buffer is alreay open then we should not allow a call to another open().	if( IsOpen() == false )	{		bRet = false;		// Since we are dealing with the serial port we need to use the O_NOCTTY option.		int flags = O_RDWR | O_NOCTTY;		// Try to open the serial port.		if ((m_hFile = ::open(m_pChannel->m_strComName.data(), flags) ) != -1)		{			if( InitializeSerialPort())				bRet = true;		}	}	return bRet ;}void CSerial::Close(){	if (m_hFile != -1)	{		::close(m_hFile);	}}bool CSerial::InitializeSerialPort(){	bool bRet = false;		// If we do not have a valid file descriptor then return with failure.	if (-1 == m_hFile) return bRet ;	#ifdef _UC7400	int mode = RS232_MODE;	ioctl(m_hFile, MOXA_SET_OP_MODE, &mode);	//1. Function: MOXA_SET_OP_MODE//	int ioctl(fd, MOXA_SET_OP_MODE, &mode)//	Description//	Set the interface mode. Argument 3 mode will pass to the UART device driver and change it.//	2. Function: MOXA_GET_OP_MODE//	int ioctl(fd, MOXA_GET_OP_MODE, &mode)#endif	// Use non-blocking mode while configuring the serial port.	int flags = fcntl(m_hFile, F_GETFL, 0) ;	if (-1 == fcntl(m_hFile,F_SETFL,flags | O_NONBLOCK ) )		return bRet ;		// Flush out any garbage left behind in the buffers associated	// with the port from any previous operations.	if (-1 == tcflush(m_hFile, TCIOFLUSH) )		return bRet;		// Set up the default configuration for the serial port.	if (SetParameters() == false)		return bRet ;		// Allow all further communications to happen in blocking mode.	flags = fcntl(m_hFile, F_GETFL, 0) ;	if( -1 == fcntl(m_hFile,F_SETFL,flags & ~O_NONBLOCK ) )		return bRet ;	// If we get here without problems then we are good; return a value	// different from -1.	return true ;}bool CSerial::SetParameters(){	// Baud rate	if (BAUD_INVALID == SetBaudRate((BaudRateEnum)m_pChannel->m_lBaudRate))	{		cout <<"SetBaudRate failure"<<endl;		return false;	}	// Character size.	if (-1 == SetCharSize((CharSizeEnum)m_pChannel->m_byDataBit))	{		cout <<"SetCharSize failure"<<endl;		return false;	}	// Number of stop bits.	if (-1 == SetNumOfStopBits(m_pChannel->m_byStopBit))	{		cout <<"SetNumOfStopBits failure"<<endl;		return false;	}	// Parity	if (-1 == SetParity((ParityEnum)m_pChannel->m_byParity))	{		cout <<"SetParity failure"<<endl;		return false;	}	// Flow control	if (-1 == SetFlowControl(FLOW_CONTROL_SOFT))		return false;	// All done. Return a value other than -1.	return true;}const BaudRateEnum CSerial::SetBaudRate(const BaudRateEnum baud_rate){	if(-1 == m_hFile)		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:	{		// Get the current terminal settings.		struct termios term_setting ;		if (-1 == tcgetattr(m_hFile, &term_setting))			return BAUD_INVALID ;		// Modify the baud rate in the term_setting structure.		cfsetispeed( &term_setting, baud_rate ) ;		cfsetospeed( &term_setting, baud_rate ) ;				term_setting.c_iflag = 0;		term_setting.c_oflag = 0;		term_setting.c_lflag = 0;//		term_setting.c_cflag = CREAD;		term_setting.c_cc[VMIN]=1;		term_setting.c_cc[VTIME]=0;				// Apply the modified termios structure to the serial port.		if(-1 == tcsetattr(m_hFile, TCSANOW, &term_setting))			return BAUD_INVALID ;		break ;	}	default:		return BAUD_INVALID ;	break ;	} ;  //  // If we succeeded in setting the baud rate then we need to return  // the baud rate.  //	return BaudRate() ;}const BaudRateEnum CSerial::BaudRate() const{	if (-1 == m_hFile )		return BAUD_INVALID ;		// Get the current terminal settings.	struct termios term_setting ;	if (-1 == tcgetattr(m_hFile, &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 ;	default:		return BAUD_INVALID ; // we return an invalid value in this case.	break ;	}	assert( false ) ;	return BAUD_INVALID ;}const CharSizeEnum CSerial::SetCharSize(const CharSizeEnum char_size){	if( -1 == m_hFile )		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(m_hFile, &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(m_hFile, TCSANOW, &term_setting) )			return CHAR_SIZE_INVALID ;		break ;	}	default:		return CHAR_SIZE_INVALID ;	break ; 	}	return CharSize() ;}const CharSizeEnum CSerial::CharSize() const{	if( -1 == m_hFile)		return CHAR_SIZE_INVALID ;	// Get the current terminal settings.	struct termios term_setting ;	if(-1 == tcgetattr(m_hFile, &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 ;}short CSerial::SetNumOfStopBits(short stop_bits){	if (-1 == m_hFile)		return 0 ;	// Get the current terminal settings.	struct termios term_setting ;	if (-1 == tcgetattr(m_hFile, &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(m_hFile, TCSANOW, &term_setting))		return 0 ;	return NumOfStopBits() ;}short CSerial::NumOfStopBits() const{	if(-1 == m_hFile)		return 0 ;	// Get the current terminal settings.	struct termios term_setting ;	if(-1 == tcgetattr(m_hFile, &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 ;	else return 1 ;}const ParityEnum CSerial::SetParity(const ParityEnum parity){	if (-1 == m_hFile)		return PARITY_INVALID ;	// Get the current terminal settings.	struct termios term_setting ;	if (-1 == tcgetattr(m_hFile, &term_setting))		return PARITY_INVALID ;	// Set the parity in the termios structure.	switch( parity )	{	case PARITY_EVEN:		term_setting.c_cflag |= PARENB;     /* Enable parity */    		term_setting.c_cflag &= ~PARODD;   /* 转换为偶效验*/     		term_setting.c_iflag |= INPCK;       /* Disnable parity checking */		break;	case PARITY_ODD:		term_setting.c_cflag |= (PARODD | PARENB); /* 设置为奇效验*/  		term_setting.c_iflag |= INPCK;             /* Disnable parity checking */ 		break ;	case PARITY_NONE:		term_setting.c_cflag &= ~PARENB;   /* Clear parity enable */		term_setting.c_iflag &= ~INPCK;     /* Enable parity checking */ 		break ;	default:		term_setting.c_cflag &= ~PARENB;   /* Clear parity enable */		term_setting.c_iflag &= ~INPCK;     /* Enable parity checking */ 		break ;	}	// Write the settings back to the serial port.	if (-1 == tcsetattr(m_hFile, TCSANOW, &term_setting))		return PARITY_INVALID ;	return Parity() ;}const ParityEnum CSerial::Parity() const{	if (-1 == m_hFile)		return PARITY_INVALID ;	// Get the current terminal settings.	struct termios term_setting ;	if(-1 == tcgetattr(m_hFile, &term_setting))		return PARITY_INVALID ;	// Get the parity setting from the termios structure.	if( term_setting.c_cflag & PARENB )   // parity is enabled.	{		if (term_setting.c_cflag & PARODD)  // odd parity			return PARITY_ODD ;		 else                              // even parity			return PARITY_EVEN ;	}	else                                // no parity.		return PARITY_NONE ;	return PARITY_INVALID ; // execution should never reach here.}const FlowControlEnum CSerial::SetFlowControl(const FlowControlEnum flow_c){	if (-1 == m_hFile)		return FLOW_CONTROL_INVALID ;	// Flush any unwritten, unread data from the serial port.	if (-1 == tcflush(m_hFile, TCIOFLUSH))		return FLOW_CONTROL_INVALID ;	// Get the current terminal settings.	struct termios tset;	int retval = tcgetattr(m_hFile, &tset);	if (-1 == retval)		return FLOW_CONTROL_INVALID ;	// Set the flow control. Hardware flow control uses the RTS (Ready	// To Send) and CTS (clear to Send) lines. Software flow control	// uses IXON|IXOFF	if ( FLOW_CONTROL_HARD == flow_c )	{		tset.c_iflag &= ~ (IXON|IXOFF);		tset.c_cflag |= CRTSCTS;		tset.c_cc[VSTART] = _POSIX_VDISABLE;		tset.c_cc[VSTOP] = _POSIX_VDISABLE;	}	else	{		tset.c_iflag &= ~ (IXON|IXOFF);//		tset.c_iflag |= IXON|IXOFF;		tset.c_iflag |= IXANY;		tset.c_cflag &= ~CRTSCTS;//		tset.c_cc[VSTART] = CTRL_Q ; // 0x11 (021) ^q//		tset.c_cc[VSTOP]  = CTRL_S ; // 0x13 (023) ^s	}	retval = tcsetattr(m_hFile, TCSANOW, &tset);	if (-1 == retval)		return FLOW_CONTROL_INVALID ;	return FlowControl() ;}const FlowControlEnum CSerial::FlowControl() const{	if( -1 == m_hFile)		return FLOW_CONTROL_INVALID ;	// Get the current terminal settings.	struct termios tset ;	if(-1 == tcgetattr(m_hFile, &tset))		return FLOW_CONTROL_INVALID ;	// Check if IXON and IXOFF are set in c_iflag. If both are set and	// VSTART and VSTOP are set to 0x11 (^Q) and 0x13 (^S) respectively,	// then we are using software flow control.//	if ((tset.c_iflag & IXON) && (tset.c_iflag & IXOFF) && (CTRL_Q == tset.c_cc[VSTART]) && (CTRL_S == tset.c_cc[VSTOP] ))	if (tset.c_iflag & IXANY)		return FLOW_CONTROL_SOFT ;	else if (!((tset.c_iflag & IXON) || (tset.c_iflag & IXOFF)))		// If neither IXON or IXOFF is set then we must have hardware flow		// control.		return FLOW_CONTROL_HARD ;	//	// If none of the above conditions are satisfied then the serial	// port is using a flow control setup which we do not support at	// present.	return FLOW_CONTROL_INVALID ;}

⌨️ 快捷键说明

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