• Linux下读写UART串口的代码


    Linux下读写UART串口的代码,从IBM Developer network上拿来的东西,操作比較的复杂,就直接跳过了,好在代码能用,记录一下~

    两个实用的函数~

    ////////////////////////////////////////////////////////////////////////////////
    /**
    *@brief  设置串口通信速率
    *@param  fd     类型 int  打开串口的文件句柄
    *@param  speed  类型 int  串口速度
    *@return  void
    */
    int speed_arr[] = {B115200, B38400, B19200, B9600, B4800, B2400, B1200, B300,
              		   B115200, B38400, B19200, B9600, B4800, B2400, B1200, B300, };
    int name_arr[] = {115200, 38400, 19200, 9600, 4800, 2400, 1200,  300, 
    		  		  115200, 38400, 19200, 9600, 4800, 2400, 1200,  300, };
    void set_speed(int fd, int speed){
      int   i; 
      int   status; 
      struct termios   Opt;
      tcgetattr(fd, &Opt); 
      for ( i= 0;  i < sizeof(speed_arr) / sizeof(int);  i++) { 
        if  (speed == name_arr[i]) {     
          tcflush(fd, TCIOFLUSH);     
          cfsetispeed(&Opt, speed_arr[i]);  
          cfsetospeed(&Opt, speed_arr[i]);   
          status = tcsetattr(fd, TCSANOW, &Opt);  
          if  (status != 0) {        
            perror("tcsetattr fd1");  
            return;     
          }    
          tcflush(fd,TCIOFLUSH);   
        }  
      }
    }

    ////////////////////////////////////////////////////////////////////////////////
    /**
    *@brief   设置串口数据位,停止位和效验位
    *@param  fd     类型  int  打开的串口文件句柄
    *@param  databits 类型  int 数据位   取值 为 7 或者8
    *@param  stopbits 类型  int 停止位   取值为 1 或者2
    *@param  parity  类型  int  效验类型 取值为N,E,O,,S
    */
    int set_Parity(int fd,int databits,int stopbits,int parity)
    { 
    	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
    "); return (FALSE);  
    	}
    	switch (parity) 
    	{   
    		case 'n':
    		case 'N':    
    			options.c_cflag &= ~PARENB;   /* Clear parity enable */
    			options.c_iflag &= ~INPCK;     /* Enable parity checking */ 
    			break;  
    		case 'o':   
    		case 'O':     
    			options.c_cflag |= (PARODD | PARENB); /* 设置为奇效验*/  
    			options.c_iflag |= INPCK;             /* Disnable parity checking */ 
    			break;  
    		case 'e':  
    		case 'E':   
    			options.c_cflag |= PARENB;     /* Enable parity */    
    			options.c_cflag &= ~PARODD;   /* 转换为偶效验*/     
    			options.c_iflag |= INPCK;       /* Disnable parity checking */
    			break;
    		case 'S': 
    		case 's':  /*as no parity*/   
    			options.c_cflag &= ~PARENB;
    			options.c_cflag &= ~CSTOPB;break;  
    		default:   
    			fprintf(stderr,"Unsupported parity
    ");    
    			return (FALSE);  
    		}  
    	/* 设置停止位*/  
    	switch (stopbits)
    	{   
    		case 1:    
    			options.c_cflag &= ~CSTOPB;  
    			break;  
    		case 2:    
    			options.c_cflag |= CSTOPB;  
    		   break;
    		default:    
    			 fprintf(stderr,"Unsupported stop bits
    ");  
    			 return (FALSE); 
    	} 
    	/* Set input parity option */ 
    	if (parity != 'n')   
    		options.c_iflag |= INPCK; 
    	tcflush(fd,TCIFLUSH);
    	options.c_cc[VTIME] = 150; /* 设置超时15 seconds*/   
    	options.c_cc[VMIN] = 0; /* Update the options and do it NOW */
    	if (tcsetattr(fd,TCSANOW,&options) != 0)   
    	{ 
    		perror("SetupSerial 3");   
    		return (FALSE);  
    	} 
    	options.c_lflag  &= ~(ICANON | ECHO | ECHOE | ISIG);  /*Input*/
    	options.c_oflag  &= ~OPOST;   /*Output*/
    	return (TRUE);  
    }

    调用的方法比較的简单,例如以下。fd是打开的tty设备的文件句柄

        set_speed(fd,115200);
        if (set_Parity(fd,8,1,'N') == FALSE)  {
    	printf("Set Parity Error
    ");
        }

    总的測试代码例如以下。

    #include <sys/types.h>
    
    #include <sys/stat.h>
    #include <fcntl.h>
    #include <termios.h>
    #include <stdio.h>
    #define BAUDRATE        B115200
    #define UART_DEVICE     "/dev/ttyS3"
    
    #define FALSE  -1
    #define TRUE   0
    ////////////////////////////////////////////////////////////////////////////////
    /**
    *@brief  设置串口通信速率
    *@param  fd     类型 int  打开串口的文件句柄
    *@param  speed  类型 int  串口速度
    *@return  void
    */
    int speed_arr[] = {B115200, B38400, B19200, B9600, B4800, B2400, B1200, B300,
              		   B115200, B38400, B19200, B9600, B4800, B2400, B1200, B300, };
    int name_arr[] = {115200, 38400, 19200, 9600, 4800, 2400, 1200,  300, 
    		  		  115200, 38400, 19200, 9600, 4800, 2400, 1200,  300, };
    void set_speed(int fd, int speed){
      int   i; 
      int   status; 
      struct termios   Opt;
      tcgetattr(fd, &Opt); 
      for ( i= 0;  i < sizeof(speed_arr) / sizeof(int);  i++) { 
        if  (speed == name_arr[i]) {     
          tcflush(fd, TCIOFLUSH);     
          cfsetispeed(&Opt, speed_arr[i]);  
          cfsetospeed(&Opt, speed_arr[i]);   
          status = tcsetattr(fd, TCSANOW, &Opt);  
          if  (status != 0) {        
            perror("tcsetattr fd1");  
            return;     
          }    
          tcflush(fd,TCIOFLUSH);   
        }  
      }
    }
    ////////////////////////////////////////////////////////////////////////////////
    /**
    *@brief   设置串口数据位,停止位和效验位
    *@param  fd     类型  int  打开的串口文件句柄
    *@param  databits 类型  int 数据位   取值 为 7 或者8
    *@param  stopbits 类型  int 停止位   取值为 1 或者2
    *@param  parity  类型  int  效验类型 取值为N,E,O,,S
    */
    int set_Parity(int fd,int databits,int stopbits,int parity)
    { 
    	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
    "); return (FALSE);  
    	}
    	switch (parity) 
    	{   
    		case 'n':
    		case 'N':    
    			options.c_cflag &= ~PARENB;   /* Clear parity enable */
    			options.c_iflag &= ~INPCK;     /* Enable parity checking */ 
    			break;  
    		case 'o':   
    		case 'O':     
    			options.c_cflag |= (PARODD | PARENB); /* 设置为奇效验*/  
    			options.c_iflag |= INPCK;             /* Disnable parity checking */ 
    			break;  
    		case 'e':  
    		case 'E':   
    			options.c_cflag |= PARENB;     /* Enable parity */    
    			options.c_cflag &= ~PARODD;   /* 转换为偶效验*/     
    			options.c_iflag |= INPCK;       /* Disnable parity checking */
    			break;
    		case 'S': 
    		case 's':  /*as no parity*/   
    			options.c_cflag &= ~PARENB;
    			options.c_cflag &= ~CSTOPB;break;  
    		default:   
    			fprintf(stderr,"Unsupported parity
    ");    
    			return (FALSE);  
    		}  
    	/* 设置停止位*/  
    	switch (stopbits)
    	{   
    		case 1:    
    			options.c_cflag &= ~CSTOPB;  
    			break;  
    		case 2:    
    			options.c_cflag |= CSTOPB;  
    		   break;
    		default:    
    			 fprintf(stderr,"Unsupported stop bits
    ");  
    			 return (FALSE); 
    	} 
    	/* Set input parity option */ 
    	if (parity != 'n')   
    		options.c_iflag |= INPCK; 
    	tcflush(fd,TCIFLUSH);
    	options.c_cc[VTIME] = 150; /* 设置超时15 seconds*/   
    	options.c_cc[VMIN] = 0; /* Update the options and do it NOW */
    	if (tcsetattr(fd,TCSANOW,&options) != 0)   
    	{ 
    		perror("SetupSerial 3");   
    		return (FALSE);  
    	} 
    	options.c_lflag  &= ~(ICANON | ECHO | ECHOE | ISIG);  /*Input*/
    	options.c_oflag  &= ~OPOST;   /*Output*/
    	return (TRUE);  
    }
    ////////////////////////////////////////////////////////////////////////////////
    int main(int argc, char *argv[])
    {
    
        int    fd, c=0, res;
    
        char  buf[256];
    
        printf("Start...
    ");
        fd = open(UART_DEVICE, O_RDWR);
    
        if (fd < 0) {
            perror(UART_DEVICE);
            exit(1);
        }
    
        printf("Open...
    ");
        set_speed(fd,115200);
    	if (set_Parity(fd,8,1,'N') == FALSE)  {
    		printf("Set Parity Error
    ");
    		exit (0);
    	}
    
        printf("Reading...
    ");
        while(1) {
            res = read(fd, buf, 255);
    
            if(res==0)
                continue;
            buf[res]=0;
    
            printf("%s", buf);
            
            if (buf[0] == 0x0d)
            	printf("
    ");
            
            if (buf[0] == '@') break;
        }
    
        printf("Close...
    ");
        close(fd);
    
        return 0;
    }


  • 相关阅读:
    第一天上班见面用英语打招呼
    wx.NET CLI wrapper for wxWidgets
    WSEventing、WSTransfer Web服务标准
    .net 应用迁移到Mono 工具 (Moma)
    PhalangerPHP的.NET编译器
    WPF/XML 资源及相关开源项目
    IronPython引出微软“秘密计划”
    微软软件 Office Accounting
    .NET 2.0 中使用Active Directory 应用程序模式 (ADAM)
    WSS and MOSS
  • 原文地址:https://www.cnblogs.com/ldxsuanfa/p/10071521.html
Copyright © 2020-2023  润新知