• Linux系统串口接收数据编


    http://blog.csdn.net/bg2bkk/article/details/8668576   

    之前基于IBM deveplopworks社区的代码,做了串口初始化和发送的程序,今天在此基础上添加了读取串口数据的程序。首先是最简单的循环读取程序,第二个是通过软中断方式,使用信号signal机制读取串口,这里需要注意的是硬件中断是设备驱动层级的,而读写串口是用户级行为,只能通过信号机制模拟中断,信号机制的发生和处理其实于硬件中断无异,第三个是通过select系统调用,在没有数据时阻塞进程,串口有数据需要读时唤醒进程。第二个和第三个例子都能用来后台读取数据,值得学习。

    代码一:循环读取数据

    [cpp] view plaincopy
     
    1. #include<stdio.h>  
    2. #include<stdlib.h>  
    3. #include<unistd.h>  
    4. #include<sys/types.h>  
    5. #include<sys/stat.h>  
    6. #include<fcntl.h>  
    7. #include<termios.h>  
    8. #include<errno.h>  
    9.   
    10. #define FALSE -1  
    11. #define TRUE 0  
    12.   
    13. int speed_arr[] = { B38400, B19200, B9600, B4800, B2400, B1200, B300,B38400, B19200, B9600, B4800, B2400, B1200, B300, };  
    14. int name_arr[] = {38400,  19200,  9600,  4800,  2400,  1200,  300, 38400, 19200,  9600, 4800, 2400, 1200,  300, };  
    15. void set_speed(int fd, int speed){  
    16.   int   i;   
    17.   int   status;   
    18.   struct termios   Opt;  
    19.   tcgetattr(fd, &Opt);   
    20.   for ( i= 0;  i < sizeof(speed_arr) / sizeof(int);  i++) {   
    21.     if  (speed == name_arr[i]) {       
    22.       tcflush(fd, TCIOFLUSH);       
    23.       cfsetispeed(&Opt, speed_arr[i]);    
    24.       cfsetospeed(&Opt, speed_arr[i]);     
    25.       status = tcsetattr(fd, TCSANOW, &Opt);    
    26.       if  (status != 0) {          
    27.         perror("tcsetattr fd1");    
    28.         return;       
    29.       }      
    30.       tcflush(fd,TCIOFLUSH);     
    31.     }    
    32.   }  
    33. }  
    34.   
    35. int set_Parity(int fd,int databits,int stopbits,int parity)  
    36. {   
    37.     struct termios options;   
    38.     if  ( tcgetattr( fd,&options)  !=  0) {   
    39.         perror("SetupSerial 1");       
    40.         return(FALSE);    
    41.     }  
    42.     options.c_cflag &= ~CSIZE;   
    43.     switch (databits)   
    44.     {     
    45.     case 7:       
    46.         options.c_cflag |= CS7;   
    47.         break;  
    48.     case 8:       
    49.         options.c_cflag |= CS8;  
    50.         break;     
    51.     default:      
    52.         fprintf(stderr,"Unsupported data size "); return (FALSE);    
    53.     }  
    54.     switch (parity)   
    55.     {     
    56.         case 'n':  
    57.         case 'N':      
    58.             options.c_cflag &= ~PARENB;   /* Clear parity enable */  
    59.             options.c_iflag &= ~INPCK;     /* Enable parity checking */   
    60.             break;    
    61.         case 'o':     
    62.         case 'O':       
    63.             options.c_cflag |= (PARODD | PARENB);   
    64.             options.c_iflag |= INPCK;             /* Disnable parity checking */   
    65.             break;    
    66.         case 'e':    
    67.         case 'E':     
    68.             options.c_cflag |= PARENB;     /* Enable parity */      
    69.             options.c_cflag &= ~PARODD;      
    70.             options.c_iflag |= INPCK;       /* Disnable parity checking */  
    71.             break;  
    72.         case 'S':   
    73.         case 's':  /*as no parity*/     
    74.             options.c_cflag &= ~PARENB;  
    75.             options.c_cflag &= ~CSTOPB;break;    
    76.         default:     
    77.             fprintf(stderr,"Unsupported parity ");      
    78.             return (FALSE);    
    79.         }    
    80.       
    81.     switch (stopbits)  
    82.     {     
    83.         case 1:      
    84.             options.c_cflag &= ~CSTOPB;    
    85.             break;    
    86.         case 2:      
    87.             options.c_cflag |= CSTOPB;    
    88.            break;  
    89.         default:      
    90.              fprintf(stderr,"Unsupported stop bits ");    
    91.              return (FALSE);   
    92.     }   
    93.     /* Set input parity option */   
    94.     if (parity != 'n')     
    95.         options.c_iflag |= INPCK;   
    96.     tcflush(fd,TCIFLUSH);  
    97.     options.c_cc[VTIME] = 150;   
    98.     options.c_cc[VMIN] = 0; /* Update the options and do it NOW */  
    99.     if (tcsetattr(fd,TCSANOW,&options) != 0)     
    100.     {   
    101.         perror("SetupSerial 3");     
    102.         return (FALSE);    
    103.     }   
    104.     return (TRUE);    
    105. }  
    106.   
    107. int main()  
    108. {  
    109.     printf("This program updates last time at %s   %s ",__TIME__,__DATE__);  
    110.     printf("STDIO COM1 ");  
    111.     int fd;  
    112.     fd = open("/dev/ttyS0",O_RDWR);  
    113.     if(fd == -1)  
    114.     {  
    115.         perror("serialport error ");  
    116.     }  
    117.     else  
    118.     {  
    119.         printf("open ");  
    120.         printf("%s",ttyname(fd));  
    121.         printf(" succesfully ");  
    122.     }  
    123.   
    124.     set_speed(fd,115200);  
    125.     if (set_Parity(fd,8,1,'N') == FALSE)  {  
    126.         printf("Set Parity Error ");  
    127.         exit (0);  
    128.     }  
    129.     char buf[] = "fe55aa07bc010203040506073d";  
    130.     write(fd,&buf,26);  
    131.     char buff[512];   
    132.     int nread;    
    133.     while(1)  
    134.     {  
    135.         if((nread = read(fd, buff, 512))>0)  
    136.         {  
    137.             printf(" Len: %d ",nread);  
    138.             buff[nread+1] = '';  
    139.             printf("%s",buff);  
    140.         }  
    141.     }  
    142.     close(fd);  
    143.     return 0;  
    144. }  


    代码清单二:通过signal机制读取数据

    [cpp] view plaincopy
     
    1. #include<stdio.h>  
    2. #include<stdlib.h>  
    3. #include<unistd.h>  
    4. #include<sys/types.h>  
    5. #include<sys/stat.h>  
    6. #include<sys/signal.h>  
    7. #include<fcntl.h>  
    8. #include<termios.h>  
    9. #include<errno.h>  
    10.   
    11. #define FALSE -1  
    12. #define TRUE 0  
    13. #define flag 1  
    14. #define noflag 0  
    15.   
    16. int wait_flag = noflag;  
    17. int STOP = 0;  
    18. int res;  
    19.   
    20. int speed_arr[] =  
    21.   { B38400, B19200, B9600, B4800, B2400, B1200, B300, B38400, B19200, B9600,  
    22. B4800, B2400, B1200, B300, };  
    23. int name_arr[] =  
    24.   { 38400, 19200, 9600, 4800, 2400, 1200, 300, 38400, 19200, 9600, 4800, 2400,  
    25. 1200, 300, };  
    26. void  
    27. set_speed (int fd, int speed)  
    28. {  
    29.   int i;  
    30.   int status;  
    31.   struct termios Opt;  
    32.   tcgetattr (fd, &Opt);  
    33.   for (i = 0; i < sizeof (speed_arr) / sizeof (int); i++)  
    34.     {  
    35.       if (speed == name_arr[i])  
    36.     {  
    37.       tcflush (fd, TCIOFLUSH);  
    38.       cfsetispeed (&Opt, speed_arr[i]);  
    39.       cfsetospeed (&Opt, speed_arr[i]);  
    40.       status = tcsetattr (fd, TCSANOW, &Opt);  
    41.       if (status != 0)  
    42.         {  
    43.           perror ("tcsetattr fd1");  
    44.           return;  
    45.         }  
    46.       tcflush (fd, TCIOFLUSH);  
    47.     }  
    48.     }  
    49. }  
    50.   
    51. int  
    52. set_Parity (int fd, int databits, int stopbits, int parity)  
    53. {  
    54.   struct termios options;  
    55.   if (tcgetattr (fd, &options) != 0)  
    56.     {  
    57.       perror ("SetupSerial 1");  
    58.       return (FALSE);  
    59.     }  
    60.   options.c_cflag &= ~CSIZE;  
    61.   switch (databits)  
    62.     {  
    63.     case 7:  
    64.       options.c_cflag |= CS7;  
    65.       break;  
    66.     case 8:  
    67.       options.c_cflag |= CS8;  
    68.       break;  
    69.     default:  
    70.       fprintf (stderr, "Unsupported data size ");  
    71.       return (FALSE);  
    72.     }  
    73.   switch (parity)  
    74.     {  
    75.     case 'n':  
    76.     case 'N':  
    77.       options.c_cflag &= ~PARENB;   /* Clear parity enable */  
    78.       options.c_iflag &= ~INPCK;    /* Enable parity checking */  
    79.       break;  
    80.     case 'o':  
    81.     case 'O':  
    82.       options.c_cflag |= (PARODD | PARENB);  
    83.       options.c_iflag |= INPCK; /* Disnable parity checking */  
    84.       break;  
    85.     case 'e':  
    86.     case 'E':  
    87.       options.c_cflag |= PARENB;    /* Enable parity */  
    88.       options.c_cflag &= ~PARODD;  
    89.       options.c_iflag |= INPCK; /* Disnable parity checking */  
    90.       break;  
    91.     case 'S':  
    92.     case 's':           /*as no parity */  
    93.       options.c_cflag &= ~PARENB;  
    94.       options.c_cflag &= ~CSTOPB;  
    95.       break;  
    96.     default:  
    97.       fprintf (stderr, "Unsupported parity ");  
    98.       return (FALSE);  
    99.     }  
    100.   
    101.   switch (stopbits)  
    102.     {  
    103.     case 1:  
    104.       options.c_cflag &= ~CSTOPB;  
    105.       break;  
    106.     case 2:  
    107.       options.c_cflag |= CSTOPB;  
    108.       break;  
    109.     default:  
    110.       fprintf (stderr, "Unsupported stop bits ");  
    111.       return (FALSE);  
    112.     }  
    113.   /* Set input parity option */  
    114.   if (parity != 'n')  
    115.     options.c_iflag |= INPCK;  
    116.   tcflush (fd, TCIFLUSH);  
    117.   options.c_cc[VTIME] = 150;  
    118.   options.c_cc[VMIN] = 0;   /* Update the options and do it NOW */  
    119.   if (tcsetattr (fd, TCSANOW, &options) != 0)  
    120.     {  
    121.       perror ("SetupSerial 3");  
    122.       return (FALSE);  
    123.     }  
    124.   return (TRUE);  
    125. }  
    126.   
    127. void  
    128. signal_handler_IO (int status)  
    129. {  
    130.   printf ("received SIGIO signale. ");  
    131.   wait_flag = noflag;  
    132. }  
    133.   
    134. int  
    135. main ()  
    136. {  
    137.   printf ("This program updates last time at %s   %s ", __TIME__, __DATE__);  
    138.   printf ("STDIO COM1 ");  
    139.   int fd;  
    140.   struct sigaction saio;  
    141.   fd = open ("/dev/ttyUSB0", O_RDWR);  
    142.   if (fd == -1)  
    143.     {  
    144.       perror ("serialport error ");  
    145.     }  
    146.   else  
    147.     {  
    148.       printf ("open ");  
    149.       printf ("%s", ttyname (fd));  
    150.       printf (" succesfully ");  
    151.     }  
    152.   
    153.   saio.sa_handler = signal_handler_IO;  
    154.   sigemptyset (&saio.sa_mask);  
    155.   saio.sa_flags = 0;  
    156.   saio.sa_restorer = NULL;  
    157.   sigaction (SIGIO, &saio, NULL);  
    158.   
    159.   //allow the process to receive SIGIO  
    160.   fcntl (fd, F_SETOWN, getpid ());  
    161.   //make the file descriptor asynchronous  
    162.   fcntl (fd, F_SETFL, FASYNC);  
    163.   
    164.   set_speed (fd, 115200);  
    165.   if (set_Parity (fd, 8, 1, 'N') == FALSE)  
    166.     {  
    167.       printf ("Set Parity Error ");  
    168.       exit (0);  
    169.     }  
    170.   
    171.   char buf[255];  
    172. while (STOP == 0)  
    173.     {  
    174.       usleep (100000);  
    175.       /* after receving SIGIO ,wait_flag = FALSE,input is availabe and can be read */  
    176.       if (wait_flag == 0)  
    177.     {  
    178.       memset (buf, 0, sizeof(buf));  
    179.       res = read (fd, buf, 255);  
    180.       printf ("nread=%d,%s ", res, buf);  
    181. //    if (res ==1)  
    182. //      STOP = 1;       /*stop loop if only a CR was input */  
    183.       wait_flag = flag; /*wait for new input */  
    184.     }  
    185.     }  
    186.   
    187.   
    188.   close (fd);  
    189.   return 0;  
    190. }  



    代码三:通过select系统调用进行io多路切换,实现异步读取串口数据

    [python] view plaincopy
     
      1. #include<stdio.h>  
      2. #include<stdlib.h>  
      3. #include<unistd.h>  
      4. #include<sys/types.h>  
      5. #include<sys/stat.h>  
      6. #include<sys/signal.h>  
      7. #include<fcntl.h>  
      8. #include<termios.h>  
      9. #include<errno.h>  
      10.   
      11. #define FALSE -1  
      12. #define TRUE 0  
      13. #define flag 1  
      14. #define noflag 0  
      15.   
      16. int wait_flag = noflag;  
      17. int STOP = 0;  
      18. int res;  
      19.   
      20. int speed_arr[] =  
      21.   { B38400, B19200, B9600, B4800, B2400, B1200, B300, B38400, B19200, B9600,  
      22. B4800, B2400, B1200, B300, };  
      23. int name_arr[] =  
      24.   { 384001920096004800240012003003840019200960048002400,  
      25. 1200300, };  
      26. void  
      27. set_speed (int fd, int speed)  
      28. {  
      29.   int i;  
      30.   int status;  
      31.   struct termios Opt;  
      32.   tcgetattr (fd, &Opt);  
      33.   for (i = 0; i < sizeof (speed_arr) / sizeof (int); i++)  
      34.     {  
      35.       if (speed == name_arr[i])  
      36.     {  
      37.       tcflush (fd, TCIOFLUSH);  
      38.       cfsetispeed (&Opt, speed_arr[i]);  
      39.       cfsetospeed (&Opt, speed_arr[i]);  
      40.       status = tcsetattr (fd, TCSANOW, &Opt);  
      41.       if (status != 0)  
      42.         {  
      43.           perror ("tcsetattr fd1");  
      44.           return;  
      45.         }  
      46.       tcflush (fd, TCIOFLUSH);  
      47.     }  
      48.     }  
      49. }  
      50.   
      51. int  
      52. set_Parity (int fd, int databits, int stopbits, int parity)  
      53. {  
      54.   struct termios options;  
      55.   if (tcgetattr (fd, &options) != 0)  
      56.     {  
      57.       perror ("SetupSerial 1");  
      58.       return (FALSE);  
      59.     }  
      60.   options.c_cflag &= ~CSIZE;  
      61.   switch (databits)  
      62.     {  
      63.     case 7:  
      64.       options.c_cflag |= CS7;  
      65.       break;  
      66.     case 8:  
      67.       options.c_cflag |= CS8;  
      68.       break;  
      69.     default:  
      70.       fprintf (stderr, "Unsupported data size ");  
      71.       return (FALSE);  
      72.     }  
      73.   switch (parity)  
      74.     {  
      75.     case 'n':  
      76.     case 'N':  
      77.       options.c_cflag &= ~PARENB;   /* Clear parity enable */  
      78.       options.c_iflag &= ~INPCK;    /* Enable parity checking */  
      79.       break;  
      80.     case 'o':  
      81.     case 'O':  
      82.       options.c_cflag |= (PARODD | PARENB);  
      83.       options.c_iflag |= INPCK; /* Disnable parity checking */  
      84.       break;  
      85.     case 'e':  
      86.     case 'E':  
      87.       options.c_cflag |= PARENB;    /* Enable parity */  
      88.       options.c_cflag &= ~PARODD;  
      89.       options.c_iflag |= INPCK; /* Disnable parity checking */  
      90.       break;  
      91.     case 'S':  
      92.     case 's':           /*as no parity */  
      93.       options.c_cflag &= ~PARENB;  
      94.       options.c_cflag &= ~CSTOPB;  
      95.       break;  
      96.     default:  
      97.       fprintf (stderr, "Unsupported parity ");  
      98.       return (FALSE);  
      99.     }  
      100.   
      101.   switch (stopbits)  
      102.     {  
      103.     case 1:  
      104.       options.c_cflag &= ~CSTOPB;  
      105.       break;  
      106.     case 2:  
      107.       options.c_cflag |= CSTOPB;  
      108.       break;  
      109.     default:  
      110.       fprintf (stderr, "Unsupported stop bits ");  
      111.       return (FALSE);  
      112.     }  
      113.   /* Set input parity option */  
      114.   if (parity != 'n')  
      115.     options.c_iflag |= INPCK;  
      116.   tcflush (fd, TCIFLUSH);  
      117.   options.c_cc[VTIME] = 150;  
      118.   options.c_cc[VMIN] = 0;   /* Update the options and do it NOW */  
      119.   if (tcsetattr (fd, TCSANOW, &options) != 0)  
      120.     {  
      121.       perror ("SetupSerial 3");  
      122.       return (FALSE);  
      123.     }  
      124.   return (TRUE);  
      125. }  
      126.   
      127. void  
      128. signal_handler_IO (int status)  
      129. {  
      130.   printf ("received SIGIO signale. ");  
      131.   wait_flag = noflag;  
      132. }  
      133.   
      134. int  
      135. main ()  
      136. {  
      137.   printf ("This program updates last time at %s   %s ", __TIME__, __DATE__);  
      138.   printf ("STDIO COM1 ");  
      139.   int fd;  
      140.   fd = open ("/dev/ttyUSB0", O_RDWR);  
      141.   if (fd == -1)  
      142.     {  
      143.       perror ("serialport error ");  
      144.     }  
      145.   else  
      146.     {  
      147.       printf ("open ");  
      148.       printf ("%s", ttyname (fd));  
      149.       printf (" succesfully ");  
      150.     }  
      151.   
      152.   set_speed (fd, 115200);  
      153.   if (set_Parity (fd, 81'N') == FALSE)  
      154.     {  
      155.       printf ("Set Parity Error ");  
      156.       exit (0);  
      157.     }  
      158.   
      159.   char buf[255];  
      160.   fd_set rd;  
      161.   int nread = 0;  
      162.   while(1)  
      163.   {  
      164.     FD_ZERO(&rd);  
      165.     FD_SET(fd, &rd);  
      166.     while(FD_ISSET(fd, &rd))  
      167.     {  
      168.         if(select(fd+1, &rd, NULL,NULL,NULL) < 0)  
      169.         {  
      170.             perror("select error ");  
      171.         }  
      172.         else  
      173.         {  
      174.             while((nread = read(fd, buf, sizeof(buf))) > 0)  
      175.             {  
      176.                 printf("nread = %d,%s ",nread, buf);  
      177.                 printf("test ");  
      178.                 memset(buf, 0 , sizeof(buf));  
      179.             }  
      180.         }  
      181.     }  
      182.   }  
      183.   close (fd);  
      184.   return 0;  
      185. }  
  • 相关阅读:
    HDU 1301 Jungle Roads (最小生成树)
    POJ 1733 Parity game (并查集)
    HDU 3038 How Many Answers Are Wrong (并查集)
    CentOS用yum安装搭建LAMP
    Linux下php安装Redis扩展
    PHPExcel用法
    利用phpmailer类邮件发送
    Vim编辑器配置
    vhost文件设置
    ThinkPHP验证码类
  • 原文地址:https://www.cnblogs.com/cainiaoaixuexi/p/3481166.html
Copyright © 2020-2023  润新知