首页 技术 正文
技术 2022年11月14日
0 收藏 452 点赞 4,871 浏览 9596 个字

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

之前基于IBM deveplopworks社区的代码,做了串口初始化和发送的程序,今天在此基础上添加了读取串口数据的程序。首先是最简单的循环读取程序,第二个是通过软中断方式,使用信号signal机制读取串口,这里需要注意的是硬件中断是设备驱动层级的,而读写串口是用户级行为,只能通过信号机制模拟中断,信号机制的发生和处理其实于硬件中断无异,第三个是通过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. #define FALSE -1
  10. #define TRUE 0
  11. int speed_arr[] = { B38400, B19200, B9600, B4800, B2400, B1200, B300,B38400, B19200, B9600, B4800, B2400, B1200, B300, };
  12. int name_arr[] = {38400,  19200,  9600,  4800,  2400,  1200,  300, 38400, 19200,  9600, 4800, 2400, 1200,  300, };
  13. void set_speed(int fd, int speed){
  14. int   i;
  15. int   status;
  16. struct termios   Opt;
  17. tcgetattr(fd, &Opt);
  18. for ( i= 0;  i < sizeof(speed_arr) / sizeof(int);  i++) {
  19. if  (speed == name_arr[i]) {
  20. tcflush(fd, TCIOFLUSH);
  21. cfsetispeed(&Opt, speed_arr[i]);
  22. cfsetospeed(&Opt, speed_arr[i]);
  23. status = tcsetattr(fd, TCSANOW, &Opt);
  24. if  (status != 0) {
  25. perror(“tcsetattr fd1”);
  26. return;
  27. }
  28. tcflush(fd,TCIOFLUSH);
  29. }
  30. }
  31. }
  32. int set_Parity(int fd,int databits,int stopbits,int parity)
  33. {
  34. struct termios options;
  35. if  ( tcgetattr( fd,&options)  !=  0) {
  36. perror(“SetupSerial 1”);
  37. return(FALSE);
  38. }
  39. options.c_cflag &= ~CSIZE;
  40. switch (databits)
  41. {
  42. case 7:
  43. options.c_cflag |= CS7;
  44. break;
  45. case 8:
  46. options.c_cflag |= CS8;
  47. break;
  48. default:
  49. fprintf(stderr,”Unsupported data size\n”); return (FALSE);
  50. }
  51. switch (parity)
  52. {
  53. case ‘n’:
  54. case ‘N’:
  55. options.c_cflag &= ~PARENB;   /* Clear parity enable */
  56. options.c_iflag &= ~INPCK;     /* Enable parity checking */
  57. break;
  58. case ‘o’:
  59. case ‘O’:
  60. options.c_cflag |= (PARODD | PARENB);
  61. options.c_iflag |= INPCK;             /* Disnable parity checking */
  62. break;
  63. case ‘e’:
  64. case ‘E’:
  65. options.c_cflag |= PARENB;     /* Enable parity */
  66. options.c_cflag &= ~PARODD;
  67. options.c_iflag |= INPCK;       /* Disnable parity checking */
  68. break;
  69. case ‘S’:
  70. case ‘s’:  /*as no parity*/
  71. options.c_cflag &= ~PARENB;
  72. options.c_cflag &= ~CSTOPB;break;
  73. default:
  74. fprintf(stderr,”Unsupported parity\n”);
  75. return (FALSE);
  76. }
  77. switch (stopbits)
  78. {
  79. case 1:
  80. options.c_cflag &= ~CSTOPB;
  81. break;
  82. case 2:
  83. options.c_cflag |= CSTOPB;
  84. break;
  85. default:
  86. fprintf(stderr,”Unsupported stop bits\n”);
  87. return (FALSE);
  88. }
  89. /* Set input parity option */
  90. if (parity != ‘n’)
  91. options.c_iflag |= INPCK;
  92. tcflush(fd,TCIFLUSH);
  93. options.c_cc[VTIME] = 150;
  94. options.c_cc[VMIN] = 0; /* Update the options and do it NOW */
  95. if (tcsetattr(fd,TCSANOW,&options) != 0)
  96. {
  97. perror(“SetupSerial 3”);
  98. return (FALSE);
  99. }
  100. return (TRUE);
  101. }
  102. int main()
  103. {
  104. printf(“This program updates last time at %s   %s\n”,__TIME__,__DATE__);
  105. printf(“STDIO COM1\n”);
  106. int fd;
  107. fd = open(“/dev/ttyS0”,O_RDWR);
  108. if(fd == -1)
  109. {
  110. perror(“serialport error\n”);
  111. }
  112. else
  113. {
  114. printf(“open “);
  115. printf(“%s”,ttyname(fd));
  116. printf(” succesfully\n”);
  117. }
  118. set_speed(fd,115200);
  119. if (set_Parity(fd,8,1,’N’) == FALSE)  {
  120. printf(“Set Parity Error\n”);
  121. exit (0);
  122. }
  123. char buf[] = “fe55aa07bc010203040506073d”;
  124. write(fd,&buf,26);
  125. char buff[512];
  126. int nread;
  127. while(1)
  128. {
  129. if((nread = read(fd, buff, 512))>0)
  130. {
  131. printf(“\nLen: %d\n”,nread);
  132. buff[nread+1] = ‘\0’;
  133. printf(“%s”,buff);
  134. }
  135. }
  136. close(fd);
  137. return 0;
  138. }

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

  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. #define FALSE -1
  11. #define TRUE 0
  12. #define flag 1
  13. #define noflag 0
  14. int wait_flag = noflag;
  15. int STOP = 0;
  16. int res;
  17. int speed_arr[] =
  18. { B38400, B19200, B9600, B4800, B2400, B1200, B300, B38400, B19200, B9600,
  19. B4800, B2400, B1200, B300, };
  20. int name_arr[] =
  21. { 38400, 19200, 9600, 4800, 2400, 1200, 300, 38400, 19200, 9600, 4800, 2400,
  22. 1200, 300, };
  23. void
  24. set_speed (int fd, int speed)
  25. {
  26. int i;
  27. int status;
  28. struct termios Opt;
  29. tcgetattr (fd, &Opt);
  30. for (i = 0; i < sizeof (speed_arr) / sizeof (int); i++)
  31. {
  32. if (speed == name_arr[i])
  33. {
  34. tcflush (fd, TCIOFLUSH);
  35. cfsetispeed (&Opt, speed_arr[i]);
  36. cfsetospeed (&Opt, speed_arr[i]);
  37. status = tcsetattr (fd, TCSANOW, &Opt);
  38. if (status != 0)
  39. {
  40. perror (“tcsetattr fd1”);
  41. return;
  42. }
  43. tcflush (fd, TCIOFLUSH);
  44. }
  45. }
  46. }
  47. int
  48. set_Parity (int fd, int databits, int stopbits, int parity)
  49. {
  50. struct termios options;
  51. if (tcgetattr (fd, &options) != 0)
  52. {
  53. perror (“SetupSerial 1”);
  54. return (FALSE);
  55. }
  56. options.c_cflag &= ~CSIZE;
  57. switch (databits)
  58. {
  59. case 7:
  60. options.c_cflag |= CS7;
  61. break;
  62. case 8:
  63. options.c_cflag |= CS8;
  64. break;
  65. default:
  66. fprintf (stderr, “Unsupported data size\n”);
  67. 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;
  91. break;
  92. default:
  93. fprintf (stderr, “Unsupported parity\n”);
  94. return (FALSE);
  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;
  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. return (TRUE);
  120. }
  121. void
  122. signal_handler_IO (int status)
  123. {
  124. printf (“received SIGIO signale.\n”);
  125. wait_flag = noflag;
  126. }
  127. int
  128. main ()
  129. {
  130. printf (“This program updates last time at %s   %s\n”, __TIME__, __DATE__);
  131. printf (“STDIO COM1\n”);
  132. int fd;
  133. struct sigaction saio;
  134. fd = open (“/dev/ttyUSB0”, O_RDWR);
  135. if (fd == -1)
  136. {
  137. perror (“serialport error\n”);
  138. }
  139. else
  140. {
  141. printf (“open “);
  142. printf (“%s”, ttyname (fd));
  143. printf (” succesfully\n”);
  144. }
  145. saio.sa_handler = signal_handler_IO;
  146. sigemptyset (&saio.sa_mask);
  147. saio.sa_flags = 0;
  148. saio.sa_restorer = NULL;
  149. sigaction (SIGIO, &saio, NULL);
  150. //allow the process to receive SIGIO
  151. fcntl (fd, F_SETOWN, getpid ());
  152. //make the file descriptor asynchronous
  153. fcntl (fd, F_SETFL, FASYNC);
  154. set_speed (fd, 115200);
  155. if (set_Parity (fd, 8, 1, ‘N’) == FALSE)
  156. {
  157. printf (“Set Parity Error\n”);
  158. exit (0);
  159. }
  160. char buf[255];
  161. while (STOP == 0)
  162. {
  163. usleep (100000);
  164. /* after receving SIGIO ,wait_flag = FALSE,input is availabe and can be read */
  165. if (wait_flag == 0)
  166. {
  167. memset (buf, 0, sizeof(buf));
  168. res = read (fd, buf, 255);
  169. printf (“nread=%d,%s\n”, res, buf);
  170. //    if (res ==1)
  171. //      STOP = 1;       /*stop loop if only a CR was input */
  172. wait_flag = flag; /*wait for new input */
  173. }
  174. }
  175. close (fd);
  176. return 0;
  177. }

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

    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. #define FALSE -1
    11. #define TRUE 0
    12. #define flag 1
    13. #define noflag 0
    14. int wait_flag = noflag;
    15. int STOP = 0;
    16. int res;
    17. int speed_arr[] =
    18. { B38400, B19200, B9600, B4800, B2400, B1200, B300, B38400, B19200, B9600,
    19. B4800, B2400, B1200, B300, };
    20. int name_arr[] =
    21. { 38400, 19200, 9600, 4800, 2400, 1200, 300, 38400, 19200, 9600, 4800, 2400,
    22. 1200, 300, };
    23. void
    24. set_speed (int fd, int speed)
    25. {
    26. int i;
    27. int status;
    28. struct termios Opt;
    29. tcgetattr (fd, &Opt);
    30. for (i = 0; i < sizeof (speed_arr) / sizeof (int); i++)
    31. {
    32. if (speed == name_arr[i])
    33. {
    34. tcflush (fd, TCIOFLUSH);
    35. cfsetispeed (&Opt, speed_arr[i]);
    36. cfsetospeed (&Opt, speed_arr[i]);
    37. status = tcsetattr (fd, TCSANOW, &Opt);
    38. if (status != 0)
    39. {
    40. perror (“tcsetattr fd1”);
    41. return;
    42. }
    43. tcflush (fd, TCIOFLUSH);
    44. }
    45. }
    46. }
    47. int
    48. set_Parity (int fd, int databits, int stopbits, int parity)
    49. {
    50. struct termios options;
    51. if (tcgetattr (fd, &options) != 0)
    52. {
    53. perror (“SetupSerial 1”);
    54. return (FALSE);
    55. }
    56. options.c_cflag &= ~CSIZE;
    57. switch (databits)
    58. {
    59. case 7:
    60. options.c_cflag |= CS7;
    61. break;
    62. case 8:
    63. options.c_cflag |= CS8;
    64. break;
    65. default:
    66. fprintf (stderr, “Unsupported data size\n”);
    67. 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;
    91. break;
    92. default:
    93. fprintf (stderr, “Unsupported parity\n”);
    94. return (FALSE);
    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;
    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. return (TRUE);
    120. }
    121. void
    122. signal_handler_IO (int status)
    123. {
    124. printf (“received SIGIO signale.\n”);
    125. wait_flag = noflag;
    126. }
    127. int
    128. main ()
    129. {
    130. printf (“This program updates last time at %s   %s\n”, __TIME__, __DATE__);
    131. printf (“STDIO COM1\n”);
    132. int fd;
    133. fd = open (“/dev/ttyUSB0”, O_RDWR);
    134. if (fd == -1)
    135. {
    136. perror (“serialport error\n”);
    137. }
    138. else
    139. {
    140. printf (“open “);
    141. printf (“%s”, ttyname (fd));
    142. printf (” succesfully\n”);
    143. }
    144. set_speed (fd, 115200);
    145. if (set_Parity (fd, 8, 1, ‘N’) == FALSE)
    146. {
    147. printf (“Set Parity Error\n”);
    148. exit (0);
    149. }
    150. char buf[255];
    151. fd_set rd;
    152. int nread = 0;
    153. while(1)
    154. {
    155. FD_ZERO(&rd);
    156. FD_SET(fd, &rd);
    157. while(FD_ISSET(fd, &rd))
    158. {
    159. if(select(fd+1, &rd, NULL,NULL,NULL) < 0)
    160. {
    161. perror(“select error\n”);
    162. }
    163. else
    164. {
    165. while((nread = read(fd, buf, sizeof(buf))) > 0)
    166. {
    167. printf(“nread = %d,%s\n”,nread, buf);
    168. printf(“test\n”);
    169. memset(buf, 0 , sizeof(buf));
    170. }
    171. }
    172. }
    173. }
    174. close (fd);
    175. return 0;
    176. }
相关推荐
python开发_常用的python模块及安装方法
adodb:我们领导推荐的数据库连接组件bsddb3:BerkeleyDB的连接组件Cheetah-1.0:我比较喜欢这个版本的cheeta…
日期:2022-11-24 点赞:878 阅读:9,084
Educational Codeforces Round 11 C. Hard Process 二分
C. Hard Process题目连接:http://www.codeforces.com/contest/660/problem/CDes…
日期:2022-11-24 点赞:807 阅读:5,559
下载Ubuntn 17.04 内核源代码
zengkefu@server1:/usr/src$ uname -aLinux server1 4.10.0-19-generic #21…
日期:2022-11-24 点赞:569 阅读:6,408
可用Active Desktop Calendar V7.86 注册码序列号
可用Active Desktop Calendar V7.86 注册码序列号Name: www.greendown.cn Code: &nb…
日期:2022-11-24 点赞:733 阅读:6,181
Android调用系统相机、自定义相机、处理大图片
Android调用系统相机和自定义相机实例本博文主要是介绍了android上使用相机进行拍照并显示的两种方式,并且由于涉及到要把拍到的照片显…
日期:2022-11-24 点赞:512 阅读:7,818
Struts的使用
一、Struts2的获取  Struts的官方网站为:http://struts.apache.org/  下载完Struts2的jar包,…
日期:2022-11-24 点赞:671 阅读:4,901