Linux串口

2019-07-13 01:15发布

可以参考http://www.cnblogs.com/lovemo1314/archive/2010/10/29/1864327.html 《从实践中学嵌入式linux应用程序开发》(华清远见嵌入式学院)第2章、嵌入式文件和I/O编程   设置串口属性的基本流程:
    • 保存原先串口配置

使用tcgetattr(fd,&old_cfg)函数,该函数得到有fd指向的终端的配置参数,并将它们保存于termios结构变量old_cfg中。若调试成功,函数返回值为0,若调试失败,函数返回值为-1; if(tcgetattr(fd,&old_cfg != 0 ) { perror("tcgetattr"); return -1; } 若调试成功,函数返回值为0,若调试失败,函数返回值为-1;
  • 激活选项

CLOCAL和CREAD分别用于本地连接和接收使能,因此首先要通过位掩码的方式激活这两个选项。 newtio.c_cflag |= CLOCAL | CREAD; 调用cfmakeraw()函数可以将终端设置为原始模式,在后面的实例中,采用原始模式进行串口数据通信。 cfmakeraw(&new_cfg);
  • 设置波特率

cfsetispeed(&new_cfg,B115200); cfsetospeed(&new_cfg,B115200);  
  • 设置字符大小

new_cfg.c_cflag &= ~CSIZE;//用数据位掩码清空数据位设置 new_cfg.c_cflag |= CS8;  
  • 设置奇偶校验位

//使能奇校验 new_cfg.c_cflag |= (PARODD | PARENB); new_cfg.c_iflag |= INPCK; //使能偶校验 new_cfg.c_cflag |= PARENB; new_cfg.c_cflag &= ~PARODD;//清除奇校验标志,配置为偶校验 new_cfg.c_iflag |= INPCK;
  • 设置停止位

new_cfg.c_cflag &= ~CSTOPB;//将停止位设置为一个bite new_cfg.c_cflag |= CSTOPB;//将停止位设置为两个bite
  • 设置最少字符和等待时间

new_cfg.c_cc[VTIME] = 0; new_cfg.c_cc[VMIN] = 0;
  • 清除串口缓冲

int tcdrain(int fd);//使程序阻塞,直到输出缓冲区的数据全部发送完毕 int tcflow(int fd,int action);//用于暂停或从新开始输入 int tcflush(int fd,int queue_selector);//用于清空输入/输出缓冲区
  • 激活配置

if((tcsetattr(fd,TCSANOW,&new_cfg)) != 0) { perror("tcsetattr"); return -1; } 串口配置实例: int set_com_config(int fd,int baud_rate,int data_bits,char parity.int stop_bits) { struct termios new_cfg,old_cfg; int speed; if(tcgetattr(fd,&old_cfg != 0) { perror("tcgetattr"); return -1; } new_cfg = old_cfg; cfmakeraw(&new_cfg); new_cfg.c_cflag &= ~CSIZE; switch(baud_rate) { case 2400: { speed = B2400; } break; case 4800: { speed = B4800; } break; case 9600: { speed = B9600; } break; case 19200: { speed = B19200; } break; case 38400: { speed = B38400; } break; case 115200: { speed = B115200; } break; } cfsetispeed(&new_cfg,speed); cfsetospeed(&new_cfg,speed); switch(data_bits) { case 7: { new_cfg.c_cflag |= CS7; } break; case 8: { new_cfg.c_cflag |= CS8; } break; } switch(parity) { default: case 'n': case 'N': { new_cfg.c_cflag |= ~PARENB; new_cfg.c_iflag |= ~INPCK; } break; case 'o': case 'O': { new_cfg.c_cflag |= (PARODD | PARENB); new_cfg.c_iflag |= INPCK; } break; case 'e': case 'E': { new_cfg.c_cflag |= PARENB; new_cfg.c_cflag &= ~PARODD; new_cfg.c_iflag |= INPCK; } break; case 's': case 'S': { new_cfg.c_cflag &= ~PARENB; new_cfg.c_cflag &= ~CSTOPB; } break; } switch(stop_bits) { default: case 1: { new_cfg.c_cflag &= ~CSTOPB; } break; case 2: { new_cfg.c_cflag |= CSTOPB; } break; } new_cfg.c_cc[VTIME] = 0; new_cfg.c_cc[VMIN] = 1; tcflush(fd,TCIFLUSH); if(tcsetattr(fd,TCSANOW,&new_cfg)) != 0) { perror("tcsetattr"); return -1; ` } return 0; }  
  • 串口使用:

  1. 打开串口

int open_port(int com_port) { int fd; #if(COM_TYPE == GNR_COM) char *dev[] = {"/dev/ttyS0","/dev/ttyS1","/dev/ttyS2"}; #else char *dev[] = {"/dev/ttyUSB0","/dev/ttyUSB1","/dev/ttyUSB2"}; #endif if((com_port < 0) || (com_port > MAX_COM_NUM)) { return -1; } fd = open(dev[com_port - 1].O_RDWR|O_NOCTTY|O_NDELAY); if(fd < 0) { perror("open serial port"); return -1; } if(fcntl(fd,F_SETFL,0) < 0) { perror("fcntl F_SETFL "); } if(isatty(fd) == 0) { perror("This is not a terminal device"); } return fd; }   2.  读写串口 /*com_writer.c*/ #include #include #include<string.h> #include #include #include #include"uart_api.h" int main(void) { int fd; char buff[BUFFER_SIZE]; if((fd = open_port(HOST_COM_PORT)) < 0) { perror("open_port"); return 1; } if(set_com_config(fd,115200,8,'N',1) < 0) { perror("set_com_config"); return 1; } do{ printf("input some words(enter 'quit' to exit):"); menset(buff,0,BUFFER_SIZE); if(fgets(buff,BUFFER_SIZE,stdin) == NULL) { perror("fgets"); break; } write(fd,buff,strlen(buff)); }while(strncmp(buff,"quit",4)); close(fd); return 0; } /*com_reader.c*/ #include #include #include<string.h> #include #include #include #include"uart_api.h" int main(void) { int fd; char buff[BUFFER_SIZE]; if((fd = open_port(TARGET_COM_PORT)) < 0) { perror("open_port"); return 1; } if(set_com_config(fd,115200,8,'N',1) < 0) { perror("set_com_config"); return 1; } do{ menset(buff,0,BUFFER_SIZE); if(read(fd,buff,BUFFER_SIZE) > 0) { printf("the received words are : %s",buff); } }while(strncmp(buff,"quit",4)); close(fd); return 0; }