/* * 初始化配置rs232串口设备 * 参数 fd: 设备文件描述符 * speed: rs232串口设备波特率 * databits: rs232串口设备数据位位数 * parity: rs232串口设备数据奇偶校验设置 * stopbits: rs232串口设备数据停止位位数 * 返回值: 配置成功返回零, 否则返回非零. * * */ int serial_port_init(int fd,int speed,int databits,char parity,int stopbits) { struct termios oldtio,newtio; int status,i; #ifdef DEBUG printf("%s fd = %d\n speed = %d\tdatabits = %d\tparity = %c\tstopbits = %d\n", __func__, fd, speed, databits, parity, stopbits); #endif #if 1 /* 保存之前的串口配置 */ bzero(&newtio,sizeof(struct termios)); if(tcgetattr(fd,&oldtio)!=0){ perror("tcgetattr "); return -1; } newtio=oldtio; #endif newtio.c_cflag |= CLOCAL; newtio.c_cflag |= CREAD; newtio.c_cflag &= ~ISTRIP; #ifdef RAW_UART cfmakeraw(&newtio); #endif /* 设置数据位数 */ switch (databits){ case 7: /* 七位数据位 */ newtio.c_cflag &= ~CSIZE; newtio.c_cflag |= CS7; break; case 8: /* 八位数据位 */ newtio.c_cflag &= ~CSIZE; newtio.c_cflag |= CS8; break; default: printf("%s unsupported data size\n", __func__); return -1; } /*设置校验位*/ switch(parity){ case 'n': /* 无校验位 */ case 'N': /* 无校验位 */ newtio.c_cflag &= ~PARENB; //newtio.c_cflag &= ~INPCK; break; case 'o': case 'O': newtio.c_cflag |= (PARODD | PARENB); /* 设置为奇效验*/ newtio.c_iflag |= INPCK; break; case 'e': case 'E': newtio.c_cflag |= PARENB; newtio.c_cflag &= ~PARODD; /* 转换为偶效验*/ newtio.c_iflag |= INPCK; break; case 's': case 'S': newtio.c_cflag &= ~PARENB; newtio.c_cflag &= ~CSTOPB; break; default: printf("%s unsupported parity\n", __func__); return -1; } /* 设置停止位 */ switch (stopbits) { case 1: /* 一个停止位 */ newtio.c_cflag &= ~CSTOPB; break; case 2: /* 两个停止位 */ newtio.c_cflag |= CSTOPB; break; default: printf("%s Unsupported stop bits\n", __func__); return -1; } /* 設置波特率 */ switch(speed){ case 9600: cfsetispeed(&newtio,B115200); cfsetospeed(&newtio,B115200); break; case 460800: cfsetispeed(&newtio,B460800); cfsetospeed(&newtio,B460800); break; case 115200: cfsetispeed(&newtio,B115200); cfsetospeed(&newtio,B115200); break; default: printf("%s not set speed fo serial port\n", __func__); } newtio.c_cc[VTIME]=0; /* 等待時間 */ newtio.c_cc[VMIN]=1; tcdrain(fd); /* 使程序阻塞,直到缓冲区数据发送完 */ tcflush(fd,TCIOFLUSH); /* 更新配置 */ if ((tcsetattr(fd,TCSANOW,&newtio)) != 0){ perror("tcsetattr "); return -1; } return 0; } /* * 打开rs232串口设备 * 参数: device: rs232设备 * speed: rs232设备的波特率 * databits: rs232设备的数据位位数 * parity: rs232设备的奇偶校验设置 * stopbits: rs232设备的停止位位数 * 返回值: fd: 设备文件描述符 * * */ int serial_port_open(char *device, int speed, int databits, int parity, int stopbits) { /* 打开rs232串口设备 */ int fd = open(device, O_RDWR|O_NOCTTY|O_NDELAY); if(fd<=0){ printf("open %s error !\n", device); exit(1); } /* 测试rs232设备 */ if(fcntl(fd,F_SETFL,0)<0){ perror("fcntl F_SETFL\n"); } /* 测试rs232设备 */ if(isatty(fd) == 0){ perror("this is not a terminal device \n"); } /* 初始化配置rs232串口设备 */ if(serial_port_init(fd, speed, databits, parity, stopbits)!=0){ printf("serial port init %s fail !\n", device); close(fd); exit(1); } return fd; } /* * 关闭rs232串口设备 * * */ int serial_port_close(int fd) { return close(fd); } /* * 从rs232串口设备读数据 * 参数: fd: 设备文件描述符 * buf: 数据将存到的缓冲区指针 * len: 缓冲区的大小 * * 返回值: num: 实际从rs232读到的数据长度 * * */ int serial_port_read(int fd, char *buf, int len) { int num = 0; /* 判断fd和buf的合法性 */ if((fd > 0) && (buf != NULL)){ /* 从rs232串口设备读数据 */ num = read(fd, buf, len); } return num; } /* * 向rs232串口设备写数据 * 参数: fd: 设备文件描述符 * buf: 待写入的数据的数据缓冲区指针 * len: 缓冲区的大小 * * 返回值: num: 实际写入到rs23设备的数据长度 * */ int serial_port_write(int fd, char *buf, int len) { int num = 0; /* 判断fd和buf的合法性 */ if((fd > 0) && (buf != NULL)){ /* 向s232串口设备写数据 */ num = write(fd, buf, len); } return num; }