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. }

Linux系统串口接收数据编的更多相关文章

  1. rsync Linux系统下的数据镜像备份工具

    rsync是Linux系统下的数据镜像备份工具,从软件的命名上就可以看出来了——remote sync.rsync支持大多数的类Unix系统,无论是Linux.Solaris还是BSD上都经过了良好的 ...

  2. Django项目:CMDB(服务器硬件资产自动采集系统)--07--06CMDB测试Linux系统采集硬件数据的命令02

    #settings.py """ Django settings for AutoCmdb project. Generated by 'django-admin sta ...

  3. Django项目:CMDB(服务器硬件资产自动采集系统)--06--06CMDB测试Linux系统采集硬件数据的命令01

    #base.py # ————————01CMDB获取服务器基本信息———————— from config import settings #配置文件 class BasePlugin(object ...

  4. C# 串口接收数据中serialPort.close()死锁

    最近在做一个有关高铁模拟仓显示系统的客户端程序,在这个程序中要运用串口serialPort传输数据,因为每次接收数据结束后要更新UI界面,所以就用到了的Invoke,将更新UI的程序代码封装到一个方法 ...

  5. linux系统串口编程实例

    在嵌入式开发中一些设备如WiFi.蓝牙......都会通过串口进行主机与从机间通信,串口一般以每次1bit位进行传输,效率相对慢. 在linux系统下串口的编程有如下几个步骤,最主要的是串口初始化! ...

  6. STM32 ucosii 串口接收数据 遇到的问题及解决思路

    写一个程序,用到了ucos ii ,串口在中断中接收数据(一包数据 8个字节 包含: 1byte包头 5byte数据 1byte校验和 1byte 包尾 ) ,数据由上位机每隔500ms发送一次,在串 ...

  7. Linux 系统串口信息查看

    先确认系统启动的时候串口的信息. ECM_5412@chenfl:~$ dmesg | grep tty [ 0.000000] console [tty0] enabled [ 2.511678] ...

  8. C# 解决串口接收数据不完整

    方法1: 使 用缓存机制完成.首先通过定义一个成员变量List<byte> buffer = new List<byte> (4096);用来存放所有的数据,在接收函数里,通过 ...

  9. linux内核网络接收数据流程图【转】

    转自:http://blog.chinaunix.net/uid-23069658-id-3141409.html 4.3 数据接收流程图   各层主要函数以及位置功能说明:          1)s ...

随机推荐

  1. IAR for MSP430 关于添加自定义头文件的两种方法【转】

    前言:第一次接触这个软件,编译一个例程一直出现没有包含头文件的错误,在网上找了好几个方法都没什么效果,看到了篇文章,利用里面的方法1解决了,特此复制下来保存学习用. 原文链接:https://blog ...

  2. 【codeforces 807B】T-Shirt Hunt

    [题目链接]:http://codeforces.com/contest/807/problem/B [题意] 你在另外一场已经结束的比赛中有一个排名p; 然后你现在在进行另外一场比赛 然后你当前有一 ...

  3. PHP学习总结(2)——PHP入门篇之PHP代码标识

    认识PHP代码标识 想在页面中编写PHP​代码非常容易,如下面代码: <?php echo "想学习php吗?来慕课网吧";?> 就像你可以编写JavaScript脚本 ...

  4. redis 在 Linux 和 Windows 上的安装配置

    最近需要在服务器上安装 redis,虽然只是一个小事情,但这个过程中也遇到了不少的问题,所以做一个总结,也希望能给到其他人一些帮助. 本文记录了 linux 系统和 windows 系统的 redis ...

  5. 基于【SpringBoot】的微服务【Jenkins】自动化部署

    最近,也是抽空整理了一些在工作中积累的经验,通过博客记录下来分享给大家,希望能对大家有所帮助: 一.关于自动化部署 关于自动化部署的优点,我就不在这里赘述了:只要想想手工打包.上传.部署.重启的种种, ...

  6. Unknown tag (s:property).

    Unknown tag (s:property). 在jsp文件中加入此句话:<%@ taglib uri="/struts-tags" prefix="s&quo ...

  7. pl/sql sql窗口允许输出和允许变量替换

    pl/sql sql窗口允许输出和允许变量替换 允许输出:类似在命令窗口中输入的 setserveroutput on; 允许变量替换:如果点击了这个,类似于执行 set define off命令 在 ...

  8. [ES6] Proxy & Reflect

    Proxy and Reflect API works nicely together. About how to use Proxy, check this post. Let's see abou ...

  9. js面向对象编程: js类定义函数时prototype和this差别?

    在面向对象编写js脚本时,定义实例方法主要有两种 例如以下: function ListCommon2(afirst) { var first=afirst; this.do1=function () ...

  10. 【机房重构】—上机&amp;订餐

    前几天通过UML图中的时序图.让我对于机房重构中的每一条线理解的更加清晰.曾经认为上机特别的乱,在一次偶遇中,得知了原来它能够转化成我们平时订餐.以下就听我说一说上机&订餐的故事吧! 又是发生 ...