Linux下读写UART串口的代码 .

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

两个有用的函数~

  1.   
  2. /** 
  3. *@brief  设置串口通信速率 
  4. *@param  fd     类型 int  打开串口的文件句柄 
  5. *@param  speed  类型 int  串口速度 
  6. *@return  void 
  7. */  
  8. int speed_arr[] = {B115200, B38400, B19200, B9600, B4800, B2400, B1200, B300,  
  9.                    B115200, B38400, B19200, B9600, B4800, B2400, B1200, B300, };  
  10. int name_arr[] = {115200, 38400, 19200, 9600, 4800, 2400, 1200,  300,   
  11.                   115200, 38400, 19200, 9600, 4800, 2400, 1200,  300, };  
  12. void set_speed(int fd, int speed){  
  13.   int   i;   
  14.   int   status;   
  15.   struct termios   Opt;  
  16.   tcgetattr(fd, &Opt);   
  17.   for ( i= 0;  i < sizeof(speed_arr) / sizeof(int);  i++) {   
  18.     if  (speed == name_arr[i]) {       
  19.       tcflush(fd, TCIOFLUSH);       
  20.       cfsetispeed(&Opt, speed_arr[i]);    
  21.       cfsetospeed(&Opt, speed_arr[i]);     
  22.       status = tcsetattr(fd, TCSANOW, &Opt);    
  23.       if  (status != 0) {          
  24.         perror("tcsetattr fd1");    
  25.         return;       
  26.       }      
  27.       tcflush(fd,TCIOFLUSH);     
  28.     }    
  29.   }  
  30. }  

/**
*@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);   
    }  
  }
}

  1.   
  2. /** 
  3. *@brief   设置串口数据位,停止位和效验位 
  4. *@param  fd     类型  int  打开的串口文件句柄 
  5. *@param  databits 类型  int 数据位   取值 为 7 或者8 
  6. *@param  stopbits 类型  int 停止位   取值为 1 或者2 
  7. *@param  parity  类型  int  效验类型 取值为N,E,O,,S 
  8. */  
  9. int set_Parity(int fd,int databits,int stopbits,int parity)  
  10. {   
  11.     struct termios options;   
  12.     if  ( tcgetattr( fd,&options)  !=  0) {   
  13.         perror("SetupSerial 1");       
  14.         return(FALSE);    
  15.     }  
  16.     options.c_cflag &= ~CSIZE;   
  17.     switch (databits) /*设置数据位数*/  
  18.     {     
  19.     case 7:       
  20.         options.c_cflag |= CS7;   
  21.         break;  
  22.     case 8:       
  23.         options.c_cflag |= CS8;  
  24.         break;     
  25.     default:      
  26.         fprintf(stderr,"Unsupported data size\n"); return (FALSE);    
  27.     }  
  28.     switch (parity)   
  29.     {     
  30.         case 'n':  
  31.         case 'N':      
  32.             options.c_cflag &= ~PARENB;   /* Clear parity enable */  
  33.             options.c_iflag &= ~INPCK;     /* Enable parity checking */   
  34.             break;    
  35.         case 'o':     
  36.         case 'O':       
  37.             options.c_cflag |= (PARODD | PARENB); /* 设置为奇效验*/    
  38.             options.c_iflag |= INPCK;             /* Disnable parity checking */   
  39.             break;    
  40.         case 'e':    
  41.         case 'E':     
  42.             options.c_cflag |= PARENB;     /* Enable parity */      
  43.             options.c_cflag &= ~PARODD;   /* 转换为偶效验*/       
  44.             options.c_iflag |= INPCK;       /* Disnable parity checking */  
  45.             break;  
  46.         case 'S':   
  47.         case 's':  /*as no parity*/     
  48.             options.c_cflag &= ~PARENB;  
  49.             options.c_cflag &= ~CSTOPB;break;    
  50.         default:     
  51.             fprintf(stderr,"Unsupported parity\n");      
  52.             return (FALSE);    
  53.         }    
  54.     /* 设置停止位*/    
  55.     switch (stopbits)  
  56.     {     
  57.         case 1:      
  58.             options.c_cflag &= ~CSTOPB;    
  59.             break;    
  60.         case 2:      
  61.             options.c_cflag |= CSTOPB;    
  62.            break;  
  63.         default:      
  64.              fprintf(stderr,"Unsupported stop bits\n");    
  65.              return (FALSE);   
  66.     }   
  67.     /* Set input parity option */   
  68.     if (parity != 'n')     
  69.         options.c_iflag |= INPCK;   
  70.     tcflush(fd,TCIFLUSH);  
  71.     options.c_cc[VTIME] = 150; /* 设置超时15 seconds*/     
  72.     options.c_cc[VMIN] = 0; /* Update the options and do it NOW */  
  73.     if (tcsetattr(fd,TCSANOW,&options) != 0)     
  74.     {   
  75.         perror("SetupSerial 3");     
  76.         return (FALSE);    
  77.     }   
  78.     options.c_lflag  &= ~(ICANON | ECHO | ECHOE | ISIG);  /*Input*/  
  79.     options.c_oflag  &= ~OPOST;   /*Output*/  
  80.     return (TRUE);    
  81. }  

/**
*@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\n"); 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\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')   
		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设备的文件句柄

  1.    set_speed(fd,115200);  
  2.    if (set_Parity(fd,8,1,'N') == FALSE)  {  
  3. printf("Set Parity Error\n");  
  4.    }  
    set_speed(fd,115200);
    if (set_Parity(fd,8,1,'N') == FALSE)  {
	printf("Set Parity Error\n");
    }

总的测试代码如下。

  1. #include <sys/types.h>   
  2.   
  3. #include <sys/stat.h>   
  4. #include <fcntl.h>   
  5. #include <termios.h>   
  6. #include <stdio.h>   
  7. #define BAUDRATE        B115200   
  8. #define UART_DEVICE     "/dev/ttyS3"   
  9.   
  10. #define FALSE  -1   
  11. #define TRUE   0   
  12.   
  13. /** 
  14. *@brief  设置串口通信速率 
  15. *@param  fd     类型 int  打开串口的文件句柄 
  16. *@param  speed  类型 int  串口速度 
  17. *@return  void 
  18. */  
  19. int speed_arr[] = {B115200, B38400, B19200, B9600, B4800, B2400, B1200, B300,  
  20.                    B115200, B38400, B19200, B9600, B4800, B2400, B1200, B300, };  
  21. int name_arr[] = {115200, 38400, 19200, 9600, 4800, 2400, 1200,  300,   
  22.                   115200, 38400, 19200, 9600, 4800, 2400, 1200,  300, };  
  23. void set_speed(int fd, int speed){  
  24.   int   i;   
  25.   int   status;   
  26.   struct termios   Opt;  
  27.   tcgetattr(fd, &Opt);   
  28.   for ( i= 0;  i < sizeof(speed_arr) / sizeof(int);  i++) {   
  29.     if  (speed == name_arr[i]) {       
  30.       tcflush(fd, TCIOFLUSH);       
  31.       cfsetispeed(&Opt, speed_arr[i]);    
  32.       cfsetospeed(&Opt, speed_arr[i]);     
  33.       status = tcsetattr(fd, TCSANOW, &Opt);    
  34.       if  (status != 0) {          
  35.         perror("tcsetattr fd1");    
  36.         return;       
  37.       }      
  38.       tcflush(fd,TCIOFLUSH);     
  39.     }    
  40.   }  
  41. }  
  42.   
  43. /** 
  44. *@brief   设置串口数据位,停止位和效验位 
  45. *@param  fd     类型  int  打开的串口文件句柄 
  46. *@param  databits 类型  int 数据位   取值 为 7 或者8 
  47. *@param  stopbits 类型  int 停止位   取值为 1 或者2 
  48. *@param  parity  类型  int  效验类型 取值为N,E,O,,S 
  49. */  
  50. int set_Parity(int fd,int databits,int stopbits,int parity)  
  51. {   
  52.     struct termios options;   
  53.     if  ( tcgetattr( fd,&options)  !=  0) {   
  54.         perror("SetupSerial 1");       
  55.         return(FALSE);    
  56.     }  
  57.     options.c_cflag &= ~CSIZE;   
  58.     switch (databits) /*设置数据位数*/  
  59.     {     
  60.     case 7:       
  61.         options.c_cflag |= CS7;   
  62.         break;  
  63.     case 8:       
  64.         options.c_cflag |= CS8;  
  65.         break;     
  66.     default:      
  67.         fprintf(stderr,"Unsupported data size\n"); return (FALSE);    
  68.     }  
  69.     switch (parity)   
  70.     {     
  71.         case 'n':  
  72.         case 'N':      
  73.             options.c_cflag &= ~PARENB;   /* Clear parity enable */  
  74.             options.c_iflag &= ~INPCK;     /* Enable parity checking */   
  75.             break;    
  76.         case 'o':     
  77.         case 'O':       
  78.             options.c_cflag |= (PARODD | PARENB); /* 设置为奇效验*/    
  79.             options.c_iflag |= INPCK;             /* Disnable parity checking */   
  80.             break;    
  81.         case 'e':    
  82.         case 'E':     
  83.             options.c_cflag |= PARENB;     /* Enable parity */      
  84.             options.c_cflag &= ~PARODD;   /* 转换为偶效验*/       
  85.             options.c_iflag |= INPCK;       /* Disnable parity checking */  
  86.             break;  
  87.         case 'S':   
  88.         case 's':  /*as no parity*/     
  89.             options.c_cflag &= ~PARENB;  
  90.             options.c_cflag &= ~CSTOPB;break;    
  91.         default:     
  92.             fprintf(stderr,"Unsupported parity\n");      
  93.             return (FALSE);    
  94.         }    
  95.     /* 设置停止位*/    
  96.     switch (stopbits)  
  97.     {     
  98.         case 1:      
  99.             options.c_cflag &= ~CSTOPB;    
  100.             break;    
  101.         case 2:      
  102.             options.c_cflag |= CSTOPB;    
  103.            break;  
  104.         default:      
  105.              fprintf(stderr,"Unsupported stop bits\n");    
  106.              return (FALSE);   
  107.     }   
  108.     /* Set input parity option */   
  109.     if (parity != 'n')     
  110.         options.c_iflag |= INPCK;   
  111.     tcflush(fd,TCIFLUSH);  
  112.     options.c_cc[VTIME] = 150; /* 设置超时15 seconds*/     
  113.     options.c_cc[VMIN] = 0; /* Update the options and do it NOW */  
  114.     if (tcsetattr(fd,TCSANOW,&options) != 0)     
  115.     {   
  116.         perror("SetupSerial 3");     
  117.         return (FALSE);    
  118.     }   
  119.     options.c_lflag  &= ~(ICANON | ECHO | ECHOE | ISIG);  /*Input*/  
  120.     options.c_oflag  &= ~OPOST;   /*Output*/  
  121.     return (TRUE);    
  122. }  
  123.   
  124. int main(int argc, char *argv[])  
  125. {  
  126.   
  127.     int    fd, c=0, res;  
  128.   
  129.     char  buf[256];  
  130.   
  131.     printf("Start...\n");  
  132.     fd = open(UART_DEVICE, O_RDWR);  
  133.   
  134.     if (fd < 0) {  
  135.         perror(UART_DEVICE);  
  136.         exit(1);  
  137.     }  
  138.   
  139.     printf("Open...\n");  
  140.     set_speed(fd,115200);  
  141.     if (set_Parity(fd,8,1,'N') == FALSE)  {  
  142.         printf("Set Parity Error\n");  
  143.         exit (0);  
  144.     }  
  145.   
  146.     printf("Reading...\n");  
  147.     while(1) {  
  148.         res = read(fd, buf, 255);  
  149.   
  150.         if(res==0)  
  151.             continue;  
  152.         buf[res]=0;  
  153.   
  154.         printf("%s", buf);  
  155.           
  156.         if (buf[0] == 0x0d)  
  157.             printf("\n");  
  158.           
  159.         if (buf[0] == '@'break;  
  160.     }  
  161.   
  162.     printf("Close...\n");  
  163.     close(fd);  
  164.   
  165.     return 0;  
  166. }  
#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\n"); 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\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')   
		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...\n");
    fd = open(UART_DEVICE, O_RDWR);

    if (fd < 0) {
        perror(UART_DEVICE);
        exit(1);
    }

    printf("Open...\n");
    set_speed(fd,115200);
	if (set_Parity(fd,8,1,'N') == FALSE)  {
		printf("Set Parity Error\n");
		exit (0);
	}

    printf("Reading...\n");
    while(1) {
        res = read(fd, buf, 255);

        if(res==0)
            continue;
        buf[res]=0;

        printf("%s", buf);
        
        if (buf[0] == 0x0d)
        	printf("\n");
        
        if (buf[0] == '@') break;
    }

    printf("Close...\n");
    close(fd);

    return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值