📄 scomm.cpp
字号:
#include <fcntl.h>#include <sys/types.h>#include <sys/stat.h>#include <unistd.h>#include <sys/time.h>#include <sys/select.h>#include <errno.h> /*错误号定义*/#include <stdio.h>#include <string.h>#include "scomm.h"#define CMSPAR 010000000000#undef STOPBIT_MARKscomm::scomm() { _fd = -1;}scomm::~scomm(){ close();}int scomm::open(const char *dev){ strcpy(_device, dev); if (_fd >= 0) close(); int fd = ::open(_device, O_RDWR | O_NOCTTY); if (fd < 0) return -1; _fd = fd; return 0;}int scomm::close(){ if (_fd >= 0) { ::close(_fd); _fd = -1; } return 0;}int scomm::read(void *buf, int size, int timeout){ if(timeout<0) return _fd >= 0 ? ::read(_fd, buf, size) : -1; int n; fd_set input; struct timeval tv; /* Initialize the input set */ FD_ZERO(&input); FD_SET(_fd, &input); /* Initialize the timeout structure */ tv.tv_sec = timeout/1000; tv.tv_usec = (timeout%1000)*1000; /* Do the select */ n = select(_fd + 1, &input, NULL, NULL, &tv); /* See if there was an error */ if(n<=0) return n; /* We have input */ if (FD_ISSET(_fd, &input)) return ::read(_fd, buf, size); return -1;}static int speed_arr[] = { B115200, B57600, B38400, B19200, B9600, B4800, B2400, B1200, B300,};static int name_arr[] = { 115200, 57600, 38400, 19200, 9600, 4800, 2400, 1200, 300,};void scomm::set_baud(int baud){ int i; struct termios Opt; tcgetattr(_fd, &Opt); int baud_count = sizeof(speed_arr) / sizeof(int); for ( i= 0; i <baud_count ; i++){ if (baud == name_arr[i]){ tcflush(_fd, TCIOFLUSH); cfsetispeed(&Opt, speed_arr[i]); cfsetospeed(&Opt, speed_arr[i]); break; } } // Local Options (Choosing Raw Input) Opt.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG); Opt.c_iflag = IGNPAR; // Setting Software Flow Control Opt.c_iflag &= ~(IXON | IXOFF | IXANY); // Choosing Raw Output Opt.c_oflag &= ~OPOST; /*Output*/ // Setting Read Timeouts Opt.c_cc[VMIN] = 0; Opt.c_cc[VTIME] = 10; // 1 seconds tcflush(_fd,TCIFLUSH); /* Update the options and do it NOW */ if (tcsetattr(_fd,TCSANOW,&Opt) != 0){ perror("tcsetattr fd1"); return; }}/***@brief 设置串口数据位,停止位和效验位*@param fd 类型 int 打开的串口文件句柄**@param databits 类型 int 数据位 取值 为 7 或者8**@param stopbits 类型 int 停止位 取值为 1 或者2**@param parity 类型 int 效验类型 取值为N,E,O,M,S*/bool scomm::set_parity(int parity,int databits,int stopbits){ struct termios options; if ( tcgetattr( _fd,&options) != 0){ perror("SetupSerial 1"); return false; } options.c_cflag &= ~CSIZE; switch (databits) /*设置数据位数*/ { case 7: options.c_cflag |= CS7; break; case 8: options.c_cflag |= CS8; break; default: fprintf(stderr,"Unsupported data size\n"); return false; } switch (parity) { case 'n': case 'N': options.c_cflag &= ~CMSPAR; options.c_cflag &= ~PARENB; /* Clear parity enable */ break; case 'o': case 'O': options.c_cflag &= ~CMSPAR; options.c_cflag |= (PARODD | PARENB); /* 设置为奇效验*/ break; case 'e': case 'E': options.c_cflag &= ~CMSPAR; options.c_cflag |= PARENB; /* Enable parity */ options.c_cflag &= ~PARODD; /* 转换为偶效验*/ break; case 'S': case 's':#ifndef STOPBIT_MARK options.c_cflag &= ~PARODD;#endif options.c_cflag |= PARENB | CMSPAR; break; case 'M': case 'm': options.c_cflag |= PARENB | CMSPAR |PARODD;#ifdef STOPBIT_MARK stopbits = 2;#endif break; default: fprintf(stderr,"Unsupported parity\n"); return false; } /* 设置停止位*/ switch (stopbits) { case 1: options.c_cflag &= ~CSTOPB; break; case 2: options.c_cflag |= CSTOPB; break; default: fprintf(stderr,"Unsupported stop bits\n"); return false; } /* Set input parity option */ if (parity == 'n' || parity == 'N') options.c_iflag &= ~INPCK; /* Enable parity checking */ else options.c_iflag |= INPCK;// options.c_cc[VTIME] = 150; // 15 seconds// options.c_cc[VMIN] = 0; tcflush(_fd,TCIFLUSH); /* Update the options and do it NOW */ if (tcsetattr(_fd,TCSANOW,&options) != 0){ perror("SetupSerial 3"); return false; } return true;}// vim: ts=4 sw=4 cindent
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -