📄 serial.c
字号:
#include <stdio.h> /* Standard input/output definitions */#include <stdlib.h>#include <string.h> /* String function definitions */#include <unistd.h> /* UNIX standard function definitions */#include <fcntl.h> /* File control definitions */#include <errno.h> /* Error number definitions */#include <termios.h> /* POSIX terminal control definitions */#include <sys/time.h>#include "serial.h"void delay(int ms){ struct timeval delaytimer; delaytimer.tv_sec = ms / 1000; delaytimer.tv_usec = (ms % 1000) * 1000; select(0, NULL, NULL, NULL, &delaytimer); return;}int gettickcount(){ struct timeval tv; struct timezone tz; gettimeofday (&tv , &tz); return tv.tv_sec*1000 + tv.tv_usec / 1000;}int Comm_Wait(int fd, unsigned int secs, unsigned int usecs){ fd_set rfds, testfds; struct timeval timer; int retval; FD_ZERO(&rfds); FD_SET(fd, &rfds); while (1) { testfds = rfds; timer.tv_sec = secs; timer.tv_usec = usecs; retval = select(fd + 1, &testfds, NULL, NULL, &timer); switch (retval) { case 0: return retval; case -1: return retval; default: if(FD_ISSET(fd, &testfds)) return 1; }// end switch } return 0;}/*打开串口,并设置串口属性,入口参数: devname-设备名称 /dev/ttyS0 /dev/ttyS1...... termios-保留默认串口属性的指针 baud-波特率,允许值1200,2400,4800,9600,19200,38400,57600,115200 其他值不允许 databits-数据位7,8 其他值不允许 stopbits-停止位 0 1 2 parity-校验,允许值:'Oo' 'Ee' 'Nn' 'Ss'返回值:<0 失败 >0 文件描述符*/int _comm_open(const char* devname, struct termios* psaveoptions, int baud, int databits, int stopbits, char parity, char flowControl){ int fd; struct termios options; fd = open(devname, O_RDWR | O_NOCTTY | O_NDELAY | O_NONBLOCK); if (fd == -1) return -1; else fcntl(fd, F_SETFL, FNDELAY); if (tcgetattr(fd, psaveoptions) == -1) { return ERR_GETOPT; } bzero(&options, sizeof(options)); speed_t baudRate = B9600; switch (baud) { case 115200: baudRate = B115200; break; case 57600: baudRate = B57600; break; case 38400: baudRate = B38400; break; case 19200: baudRate = B19200; break; case 9600: baudRate = B9600; break; case 4800: baudRate = B4800; break; case 2400: baudRate = B2400; break; case 1200: baudRate = B1200; break; default: return ERR_BAUDRATE; }//end switch baud if ((cfsetispeed(&options, baudRate) == -1) || (cfsetospeed(&options, baudRate) == -1)) { return ERR_BAUDRATE; } options.c_cflag |= (CLOCAL | CREAD); switch (databits) { case 8: options.c_cflag &= ~CSIZE; options.c_cflag |= CS8; break; case 7: options.c_cflag &= ~CSIZE; options.c_cflag |= CS7; break; default: return ERR_DATABIT; } switch (stopbits) { case 0: case 1: options.c_cflag &= ~CSTOPB; break; case 2: options.c_cflag |= CSTOPB; break; default: return ERR_STOPBIT; } switch (parity) { case 'e': //偶校验 case 'E': options.c_cflag |= PARENB; options.c_cflag &= ~PARODD; options.c_iflag |= (INPCK | ISTRIP); break; case 'o': //奇校验 case 'O': options.c_cflag |= PARENB; options.c_cflag |= PARODD; options.c_iflag |= (INPCK | ISTRIP); break; case 'n': //无校验 case 'N': options.c_cflag &= ~PARENB; break; case 's': case 'S': options.c_cflag &= ~PARENB; //复位奇偶校验标志位 ?? options.c_cflag &= ~CSTOPB; //复位停止位?? break; default: return ERR_PARITY; } /* if (settings->flowControl != 0) { if (settings->flowControl == 'n') { options.c_cflag &= ~CRTSCTS; options.c_iflag &= ~(IXON | IXOFF | IXANY); } else if (settings->flowControl == 'h') { // DSR signal checked manually during transmission options.c_cflag &= ~CRTSCTS; options.c_iflag &= ~(IXON | IXOFF | IXANY); } }*/ switch (flowControl) { case 'h': case 'H': options.c_cflag |= CRTSCTS; options.c_iflag &= ~(IXON | IXOFF | IXANY); break; case 's': case 'S': options.c_cflag &= ~CRTSCTS; options.c_iflag |= (IXON | IXOFF | IXANY); break; case 'N': case 'n': options.c_cflag &= ~CRTSCTS; options.c_iflag &= ~(IXON | IXOFF | IXANY); break; default: return ERR_FLOWCONTROL; } //options.c_cflag &= ~CRTSCTS; //options.c_iflag &= ~(IXON | IXOFF | IXANY); options.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG); //Choosing Raw Input options.c_oflag &= ~OPOST; //Choosing Raw Output options.c_cc[VMIN] = 1; options.c_cc[VTIME] = 0; tcflush(fd, TCIFLUSH); if (tcsetattr(fd, TCSANOW, &options) == -1) { return ERR_SETOPT; } return fd;}int comm_close(int fd, struct termios* psaveoptions){ tcsetattr(fd, TCSANOW, psaveoptions); close(fd); return 0;}int comm_open(const char* devname, struct termios* psaveoptions, const char* settings){ char* baudToken = NULL; char* databitsToken = NULL; char* stopbitsToken = NULL; char* parityToken = NULL; char * flowControlToken = NULL; int baud, databits, stopbits; char parity, flowControl; char databuff[512]; strncpy(databuff, settings, sizeof(databuff)); do { baudToken = (char*)databuff; if ((databitsToken = strstr(baudToken , ",")) == NULL) break; *databitsToken++ = '\0'; if ((stopbitsToken = strstr(databitsToken, ",")) == NULL) break; *stopbitsToken++ = '\0'; if ((parityToken = strstr(stopbitsToken, ",")) == NULL) break; *parityToken++ = '\0'; if ((flowControlToken = strstr(parityToken, ",")) == NULL) break; *flowControlToken++ = '\0'; } while (0); if ((baudToken == NULL) || (databitsToken == NULL) || (stopbitsToken == NULL) || (parityToken == NULL) || (flowControlToken == NULL) ) { return ERR_SETTING; } //fprintf(stderr, "%s\n%s\n%s\n%s\n%s\n", baudToken, databitsToken, stopbitsToken, parityToken, flowControlToken); baud = atol(baudToken); databits = atol(databitsToken); if ((databits != 8) && (databits != 7)) { return ERR_SETTING; } stopbits = atol(stopbitsToken); if ((stopbits != 1) && (stopbits != 2)) { return ERR_SETTING; } if ((strchr(parityToken, 'N') != NULL) || (strchr(parityToken, 'n') != NULL)) { parity = 'N'; } else if ((strchr(parityToken, 'O') != NULL) || (strchr(parityToken, 'o') != NULL)) { parity = 'O'; } else if ((strchr(parityToken, 'E') != NULL) || (strchr(parityToken, 'e') != NULL)) { parity = 'E'; } else if ((strchr(parityToken, 'S') != NULL) || (strchr(parityToken, 's') != NULL)) { parity = 'S'; } else { return ERR_SETTING; } if ((strchr(flowControlToken, 'H') != NULL) || (strchr(flowControlToken, 'h') != NULL)) { flowControl = 'h'; } else if ((strchr(flowControlToken, 'S') != NULL) || (strchr(flowControlToken, 's') != NULL)) { flowControl = 's'; } else if ((strchr(flowControlToken, 'N') != NULL) || (strchr(flowControlToken, 'n') != NULL)) { flowControl = 'n'; } else { return ERR_SETTING; } return _comm_open(devname, psaveoptions, baud, databits, stopbits, parity, flowControl);}int comm_write(int fd,char *buf,int len){ return(write(fd,buf,len));}int comm_read(int fd,char *buf,int len,int time){ int bTemp,i; memset(buf,0x00,len); for(bTemp=0;bTemp<len;){ i= Comm_Wait(fd, 0, 1); if(i==1){ i=read(fd,buf+bTemp,len-bTemp); } if(i>0){ bTemp+=i; } if (gettickcount()>time){ return -1; } } return(bTemp);}/*int main(){ struct termios oldtio; int fd; fd = comm_open("/dev/ttyS0", &oldtio, (const char*)"115200, 8, 1, e"); printf("fd=%d\n", fd); comm_close(fd, &oldtio); return 0;}*/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -