小v电子技术博文 上海鲤鲸网络科技 小v单片机
arm linux 串口编程
  • 首页 > Linux
  • 作者:小v
  • 2017年12月12日 13:17 星期二
  • 浏览:94
  • 字号:
  • 评论:0
  • 在imx6ul上调试 串口 使用cat  /dev/ttymxc3 发现没有数据输出 ,也只能用c语言写程序测试了。

    拜读某网友的文章,他说linux的串口有三种读取方式,第一种是最简单的循环轮训读取,这个就跟单片机的死循环一直检测某个端口一样的道理。

    第二种是就是通过软中断的方式,使用信号signal机制模拟中断,这个信号的发生和处理无异于硬件中断,具体的和单片机的uart_hander()硬件中断一样,单片机中串口有数据到达时会直接进入中断服务函数,在arm linux操作系统下,通过函数 signal(SIGINT,SignHandler);函数引入中断。第三种是通过是select的机制系统调用,在没有数据时阻塞进程,也可以设置成非阻塞形式,串口有数据唤醒进程即可。

    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\n"); 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\n");      
    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\n");    
    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\n",__TIME__,__DATE__);  
    110.     printf("STDIO COM1\n");  
    111.     int fd;  
    112.     fd = open("/dev/ttyS0",O_RDWR);  
    113.     if(fd == -1)  
    114.     {  
    115.         perror("serialport error\n");  
    116.     }  
    117.     else  
    118.     {  
    119.         printf("open ");  
    120.         printf("%s",ttyname(fd));  
    121.         printf(" succesfully\n");  
    122.     }  
    123.   
    124.     set_speed(fd,115200);  
    125.     if (set_Parity(fd,8,1,'N') == FALSE)  {  
    126.         printf("Set Parity Error\n");  
    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("\nLen: %d\n",nread);  
    138.             buff[nread+1] = '\0';  
    139.             printf("%s",buff);  
    140.         }  
    141.     }  
    142.     close(fd);  
    143.     return 0;  
    144. }  

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

    [cpp] view plain copy
    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\n");  
    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\n");  
    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\n");  
    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.\n");  
    131.   wait_flag = noflag;  
    132. }  
    133.   
    134. int  
    135. main ()  
    136. {  
    137.   printf ("This program updates last time at %s   %s\n", __TIME__, __DATE__);  
    138.   printf ("STDIO COM1\n");  
    139.   int fd;  
    140.   struct sigaction saio;  
    141.   fd = open ("/dev/ttyUSB0", O_RDWR);  
    142.   if (fd == -1)  
    143.     {  
    144.       perror ("serialport error\n");  
    145.     }  
    146.   else  
    147.     {  
    148.       printf ("open ");  
    149.       printf ("%s", ttyname (fd));  
    150.       printf (" succesfully\n");  
    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\n");  
    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\n", 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 plain copy
    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\n");  
    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\n");  
    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\n");  
    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.\n");  
    131.   wait_flag = noflag;  
    132. }  
    133.   
    134. int  
    135. main ()  
    136. {  
    137.   printf ("This program updates last time at %s   %s\n", __TIME__, __DATE__);  
    138.   printf ("STDIO COM1\n");  
    139.   int fd;  
    140.   fd = open ("/dev/ttyUSB0", O_RDWR);  
    141.   if (fd == -1)  
    142.     {  
    143.       perror ("serialport error\n");  
    144.     }  
    145.   else  
    146.     {  
    147.       printf ("open ");  
    148.       printf ("%s", ttyname (fd));  
    149.       printf (" succesfully\n");  
    150.     }  
    151.   
    152.   set_speed (fd, 115200);  
    153.   if (set_Parity (fd, 81'N') == FALSE)  
    154.     {  
    155.       printf ("Set Parity Error\n");  
    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\n");  
    171.         }  
    172.         else  
    173.         {  
    174.             while((nread = read(fd, buf, sizeof(buf))) > 0)  
    175.             {  
    176.                 printf("nread = %d,%s\n",nread, buf);  
    177.                 printf("test\n");  
    178.                 memset(buf, 0 , sizeof(buf));  
    179.             }  
    180.         }  
    181.     }  
    182.   }  
    183.   close (fd);  
    184.   return 0;  
    185. }  



      您阅读这篇文章共花了:  
     本文无需标签!
    二维码加载中...
    本文作者:小v      文章标题: arm linux 串口编程
    本文地址:http://www.xiaovdiy.cn/?post=381
    版权声明:若无注明,本文皆为“”原创,转载请保留文章出处。

    返回顶部| 首页| 手气不错| 捐赠支持| 自定义链接| 自定义链接| 自定义链接| 手机版本|后花园

    Copyright © 2014-2017   京ICP备14059411 Copyright 2014-2015 上海鲤鲸网络科技工作室 版权所有 All Rights Reserved

    sitemap