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

📄 clinkcom.cpp

📁 linux 下串口调用通用类 方便通用
💻 CPP
字号:
#include <stdio.h>#include <stdlib.h>#include <string.h>#include <termios.h>            //* tcgetattr, tcsetattr */#include <unistd.h>             //* read, write, close */#include <fcntl.h>              //* open */#include <string.h>             //* bzero, memcpy */#include <limits.h>             //* CHAR_MAX */#include <sys/time.h>#include "../tools/global.h"#include "../tools/csysconfig.h"//#include "../tools/cmsgctrl.h"#include "clink.h"#include "clinkcom.h"/* * Decription for TIMEOUT_SEC(buflen,baud); * baud bits per second, buflen bytes to send. * buflen*20 (20 means sending an octect-bit data by use of the maxim bits 20) * eg. 9600bps baudrate, buflen=1024B, then TIMEOUT_SEC = 1024*20/9600+2 = 4 * don't change the two lines below unless you do know what you are doing. */#define TIMEOUT_SEC(buflen,baud) (buflen*20/baud+2)#define TIMEOUT_USEC 0int clinkcom::cominit(){	setlinktype(LINK_TYPE_COM);	return 0;}int clinkcom::comclear(){//	tcsetattr 很费时?//    tcsetattr (this->fd, TCSADRAIN, &termios_old);	cominit();	return 0;}//构造函数clinkcom::clinkcom(){	cominit();}//析构函数clinkcom::~clinkcom(){	if(CLOSED!=this->getfd())	{		tcflush (this->getfd(), TCOFLUSH);     // flush all output data	}	comclear();}//通过当前连接,写数据int clinkcom::write(void *data,int datalength,int flags){   	int           retval,len, total_len = 0;    fd_set          fs_write;	struct timeval tv_timeout;	if(true == this->isdead())	{		return -1;	}    FD_ZERO (&fs_write);    FD_SET (this->getfd(), &fs_write);    tv_timeout.tv_sec = TIMEOUT_SEC (datalength, getbaudrate ());    tv_timeout.tv_usec = 0;    for (total_len = 0, len = 0; total_len < datalength;) {        retval = select (this->getfd() + 1, NULL, &fs_write, NULL, &tv_timeout);        if (retval)		{            len = ::write (this->getfd(), &((char *)data)[total_len], datalength - total_len);            if (len > 0)			{                total_len += len;            }        }        else		{			tcflush (this->getfd(), TCOFLUSH);     // flush all output data            break;        }    }	if(total_len != datalength)	{		tcflush (this->getfd(), TCOFLUSH);     // flush all output data		this->seterror(LINK_ERROR_CLOSE);		onerror();		return -2;	}    return (total_len);}//用串口参数连接设备int clinkcom::connect(void *pvoidarg){    char	*pComPort;    int		retval;	int		fd;	if(NULL == 	pvoidarg)	{		return -1;	}	if(false == this->setlinkparam(pvoidarg,sizeof(scomarg)))	{		return -1;	}	scomarg *parg=(scomarg *)pvoidarg;    switch (parg->port) {    case 0:        pComPort = "/dev/ttyS0";        break;    case 1:        pComPort = "/dev/ttyS1";        break;    case 2:        pComPort = "/dev/ttyS2";        break;    case 3:        pComPort = "/dev/ttyS3";        break;    case 4:        pComPort = "/dev/ttyS4";        break;    case 5:        pComPort = "/dev/ttyS5";        break;    case 6:        pComPort = "/dev/ttyS6";        break;    case 7:        pComPort = "/dev/ttyS7";        break;    default:        pComPort = "/dev/ttyS0";        break;    }    fd = open (pComPort, O_RDWR | O_NOCTTY | O_NONBLOCK);    if (-1 == fd) {        return -2;    }    tcgetattr (fd, &termios_old);       //* save old termios value */    //* 0 on success, -1 on failure */    retval = setportattrib(parg);    if (-1 == retval) {		close(fd);        return -3;    }    tcflush (fd, TCIFLUSH);    retval = tcsetattr (fd, TCSANOW, &termios_new);    if (-1 == retval) {		close(fd);        return -4;    }	this->fd=fd;	this->setdirection(LINK_DIRE_LINKTO);	if(LINK_CHECK_NOT == parg->checkmethod)	{		this->setstate(LINK_STATE_GOOD);	}	else	{		this->setstate(LINK_STATE_CHECK);	}	setcheckmethod(parg->checkmethod);	return 0;}int clinkcom::setportattrib(const scomarg *parg){    bzero (&termios_new, sizeof (termios_new));    cfmakeraw (&termios_new);    setbaudrate (parg->baudrate);    termios_new.c_cflag |= CLOCAL | CREAD;    setflowcontrol (parg->fctrl);    setdatabit (parg->databit);    setparitycheck (parg->parity);    setstopbit (parg->stopbit);    termios_new.c_oflag = 0;    termios_new.c_lflag |= 0;    termios_new.c_oflag &= ~OPOST;    termios_new.c_cc[VTIME] = 1;        //* unit: 1/10 second. */    termios_new.c_cc[VMIN] = 1; //* minimal characters for reading */	return 0;}/* * Function:	static INT32 BAUDRATE (INT32 baudrate) * Arguments:	INT32 baudrate; * Description:	convert baudrate from INT32 to MACRO B** */int clinkcom::baudrate(int baudrate){    switch (baudrate) {    case 0:        return (B0);    case 50:        return (B50);    case 75:        return (B75);    case 110:        return (B110);    case 134:        return (B134);    case 150:        return (B150);    case 200:        return (B200);    case 300:        return (B300);    case 600:        return (B600);    case 1200:        return (B1200);    case 2400:        return (B2400);    case 4800:        return (B4800);    case 9600:        return (B9600);    case 19200:        return (B19200);    case 38400:        return (B38400);    case 57600:        return (B57600);    case 115200:        return (B115200);    default:        return (B9600);    }}/* * Function:	static INT32 _BAUDRATE (INT32 baudrate) * Arguments:	INT32 baudrate; * Description:	convert baudrate from MACRO B** to INT32 */int clinkcom::_baudrate(int baudrate){//* reverse baudrate */    switch (baudrate) {    case B0:        return (0);    case B50:        return (50);    case B75:        return (75);    case B110:        return (110);    case B134:        return (134);    case B150:        return (150);    case B200:        return (200);    case B300:        return (300);    case B600:        return (600);    case B1200:        return (1200);    case B2400:        return (2400);    case B4800:        return (4800);    case B9600:        return (9600);    case B19200:        return (19200);    case B38400:        return (38400);    case B57600:        return (57600);    case B115200:        return (115200);    default:        return (9600);    }}int clinkcom::getbaudrate (){    return (_baudrate(cfgetospeed (&termios_new)));}/* * Function:	static void SetBaudrate (INT32 baudrate) * Arguments:	INT32 baudrate; * Description:	set serial port baudrate by use of file descriptor fd */void clinkcom::setbaudrate (int baudrate){    termios_new.c_cflag = this->baudrate (baudrate);  //* set baudrate */}/* * Function:	static static void SetDataBit (INT32 databit) * Arguments:	INT32 databit; * Description:	Set	databit; */void clinkcom::setdatabit (char databit){    termios_new.c_cflag &= ~CSIZE;    switch (databit) {    case 8:        termios_new.c_cflag |= CS8;        break;    case 7:        termios_new.c_cflag |= CS7;        break;    case 6:        termios_new.c_cflag |= CS6;        break;    case 5:        termios_new.c_cflag |= CS5;        break;    default:        termios_new.c_cflag |= CS8;        break;    }}/* * Function:	static void SetStopBit (const char *stopbit) * Arguments:	const char *stopbit; * Description:	Set Stop Bit */void clinkcom::setstopbit (const char *stopbit){    if (0 == strcmp (stopbit, "1")) {        termios_new.c_cflag &= ~CSTOPB; //* 1 stop bit */    }    else if (0 == strcmp (stopbit, "1.5")) {        termios_new.c_cflag &= ~CSTOPB; //* 1.5 stop bits */    }    else if (0 == strcmp (stopbit, "2")) {        termios_new.c_cflag |= CSTOPB;  //* 2 stop bits */    }    else {        termios_new.c_cflag &= ~CSTOPB; //* 1 stop bit */    }}/* * Function:	static void SetParityCheck (char parity) * Arguments:	char parity; * Description:	Set Parity Check */void clinkcom::setparitycheck (char parity){    switch (parity) {    case 'N':                  //* no parity check */        termios_new.c_cflag &= ~PARENB;        break;    case 'E':                  //* even */        termios_new.c_cflag |= PARENB;        termios_new.c_cflag &= ~PARODD;        break;    case 'O':                  //* odd */        termios_new.c_cflag |= PARENB;        termios_new.c_cflag |= ~PARODD;        break;    default:                   //* no parity check */        termios_new.c_cflag &= ~PARENB;        break;    }}/* * Function:	static void SetFlowControl(INT32 fctrl) * Arguments:	INT32 fctrl; * 				0: No Flow Control; *				1: Hardware Control; *				2: Software Control; */void clinkcom::setflowcontrol (char fctrl){    switch (fctrl) {    case 0:        termios_new.c_cflag &= ~CRTSCTS;        break;    case 1:    default:        termios_new.c_cflag |= CRTSCTS;        break;    case 2:        break;    }}//读当前连接的数据/*int clinkcom::read(void *buff,int len,int flags){	if(true == this->isdead())	{		return -1;	}	return ::read(this->getfd(),buff,len);*//*    INT32           retval = 0;    fd_set          fs_read;    if (!bOpen) {        return (E_NOTOPEN);    }    FD_ZERO (&fs_read);    FD_SET (fd, &fs_read);    tv_timeout.tv_sec = TIMEOUT_SEC (datalength, GetBaudrate ());    tv_timeout.tv_usec = TIMEOUT_USEC;    retval = select (fd + 1, &fs_read, NULL, NULL, &tv_timeout);    if (retval) {        return (read (fd, data, datalength));    }    else {        return (E_NODATA);    }*//*}*//*    INT32           retval = 0;    fd_set          fs_read;    if (!bOpen) {        return (E_NOTOPEN);    }    FD_ZERO (&fs_read);    FD_SET (fd, &fs_read);    tv_timeout.tv_sec = TIMEOUT_SEC (datalength, GetBaudrate ());    tv_timeout.tv_usec = TIMEOUT_USEC;    retval = select (fd + 1, &fs_read, NULL, NULL, &tv_timeout);    if (retval) {        return (read (fd, data, datalength));    }    else {        return (E_NODATA);    }*//*}*//*	debugprint("write com len %d\n",len);	if(true == this->isdead())	{		return -1;	}	int ret=-1;	int retlen=0;	int writelen=len;	char *p=(char *)buff;	if(len<=0)	{		return len;	}	while(writelen>0)	{		ret=::write(this->getfd(),p,writelen);		if(ret==-1)		{			seterror(LINK_ERROR_CLOSE);			break;		}		else if(ret <=0)		{			break;		}		writelen -= ret;		retlen += ret;		p += ret;	}	tcflush (this->getfd(), TCOFLUSH);     // flush all output datadebugprint("write com ret %d,retlen=%d\n",ret,retlen);	if(ret!=len)	{//		writelogfile(TYPEERROR|DESTTX|DESTSTD|DISPALL,//					"write socket %s error\n",this->getsockinfo());		return -1;	}	else	{//		writelogfile(TYPENORMAL|DESTTX|DESTSTD|DISPALL,//					"write socket %s LEN=%d\n",this->getsockinfo(),len);		return retlen;	}*/

⌨️ 快捷键说明

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