Linux系統串口接收資料編程__html5

來源:互聯網
上載者:User

         之前基於IBM deveplopworks社區的代碼,做了串口初始化和發送的程式,今天在此基礎上添加了讀取串口資料的程式。首先是最簡單的迴圈讀取程式,第二個是通過非強制中斷方式,使用訊號signal機制讀取串口,這裡需要注意的是硬體中斷是裝置驅動層級的,而讀寫串口是使用者級行為,只能通過訊號機制類比中斷,訊號機制的發生和處理其實於硬體中斷無異,第三個是通過select系統調用,在沒有資料時阻塞進程,串口有資料需要讀時喚醒進程。第二個和第三個例子都能用來後台讀取資料,值得學習。

代碼一:迴圈讀取資料

#include<stdio.h>#include<stdlib.h>#include<unistd.h>#include<sys/types.h>#include<sys/stat.h>#include<fcntl.h>#include<termios.h>#include<errno.h>#define FALSE -1#define TRUE 0int speed_arr[] = { B38400, B19200, B9600, B4800, B2400, B1200, B300,B38400, B19200, B9600, B4800, B2400, B1200, B300, };int name_arr[] = {38400,  19200,  9600,  4800,  2400,  1200,  300, 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);       }    }}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; options.c_cc[VMIN] = 0; /* Update the options and do it NOW */if (tcsetattr(fd,TCSANOW,&options) != 0)   { perror("SetupSerial 3");   return (FALSE);  } return (TRUE);  }int main(){printf("This program updates last time at %s   %s\n",__TIME__,__DATE__);printf("STDIO COM1\n");int fd;fd = open("/dev/ttyS0",O_RDWR);if(fd == -1){perror("serialport error\n");}else{printf("open ");printf("%s",ttyname(fd));printf(" succesfully\n");}set_speed(fd,115200);if (set_Parity(fd,8,1,'N') == FALSE)  {printf("Set Parity Error\n");exit (0);}char buf[] = "fe55aa07bc010203040506073d";write(fd,&buf,26);char buff[512];int nread;while(1){if((nread = read(fd, buff, 512))>0){printf("\nLen: %d\n",nread);buff[nread+1] = '\0';printf("%s",buff);}}close(fd);return 0;}

代碼清單二:通過signal機制讀取資料

#include<stdio.h>#include<stdlib.h>#include<unistd.h>#include<sys/types.h>#include<sys/stat.h>#include<sys/signal.h>#include<fcntl.h>#include<termios.h>#include<errno.h>#define FALSE -1#define TRUE 0#define flag 1#define noflag 0int wait_flag = noflag;int STOP = 0;int res;int speed_arr[] =  { B38400, B19200, B9600, B4800, B2400, B1200, B300, B38400, B19200, B9600,B4800, B2400, B1200, B300, };int name_arr[] =  { 38400, 19200, 9600, 4800, 2400, 1200, 300, 38400, 19200, 9600, 4800, 2400,1200, 300, };voidset_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);}    }}intset_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;  options.c_cc[VMIN] = 0;/* Update the options and do it NOW */  if (tcsetattr (fd, TCSANOW, &options) != 0)    {      perror ("SetupSerial 3");      return (FALSE);    }  return (TRUE);}voidsignal_handler_IO (int status){  printf ("received SIGIO signale.\n");  wait_flag = noflag;}intmain (){  printf ("This program updates last time at %s   %s\n", __TIME__, __DATE__);  printf ("STDIO COM1\n");  int fd;  struct sigaction saio;  fd = open ("/dev/ttyUSB0", O_RDWR);  if (fd == -1)    {      perror ("serialport error\n");    }  else    {      printf ("open ");      printf ("%s", ttyname (fd));      printf (" succesfully\n");    }  saio.sa_handler = signal_handler_IO;  sigemptyset (&saio.sa_mask);  saio.sa_flags = 0;  saio.sa_restorer = NULL;  sigaction (SIGIO, &saio, NULL);  //allow the process to receive SIGIO  fcntl (fd, F_SETOWN, getpid ());  //make the file descriptor asynchronous  fcntl (fd, F_SETFL, FASYNC);  set_speed (fd, 115200);  if (set_Parity (fd, 8, 1, 'N') == FALSE)    {      printf ("Set Parity Error\n");      exit (0);    }  char buf[255];while (STOP == 0)    {      usleep (100000);      /* after receving SIGIO ,wait_flag = FALSE,input is availabe and can be read */      if (wait_flag == 0){  memset (buf, 0, sizeof(buf));  res = read (fd, buf, 255);  printf ("nread=%d,%s\n", res, buf);//  if (res ==1)//    STOP = 1;/*stop loop if only a CR was input */  wait_flag = flag;/*wait for new input */}    }  close (fd);  return 0;}


代碼三:通過select系統調用進行io多路切換,實現非同步讀取串口資料

#include<stdio.h>#include<stdlib.h>#include<unistd.h>#include<sys/types.h>#include<sys/stat.h>#include<sys/signal.h>#include<fcntl.h>#include<termios.h>#include<errno.h>#define FALSE -1#define TRUE 0#define flag 1#define noflag 0int wait_flag = noflag;int STOP = 0;int res;int speed_arr[] =  { B38400, B19200, B9600, B4800, B2400, B1200, B300, B38400, B19200, B9600,B4800, B2400, B1200, B300, };int name_arr[] =  { 38400, 19200, 9600, 4800, 2400, 1200, 300, 38400, 19200, 9600, 4800, 2400,1200, 300, };voidset_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);}    }}intset_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;  options.c_cc[VMIN] = 0;/* Update the options and do it NOW */  if (tcsetattr (fd, TCSANOW, &options) != 0)    {      perror ("SetupSerial 3");      return (FALSE);    }  return (TRUE);}voidsignal_handler_IO (int status){  printf ("received SIGIO signale.\n");  wait_flag = noflag;}intmain (){  printf ("This program updates last time at %s   %s\n", __TIME__, __DATE__);  printf ("STDIO COM1\n");  int fd;  fd = open ("/dev/ttyUSB0", O_RDWR);  if (fd == -1)    {      perror ("serialport error\n");    }  else    {      printf ("open ");      printf ("%s", ttyname (fd));      printf (" succesfully\n");    }  set_speed (fd, 115200);  if (set_Parity (fd, 8, 1, 'N') == FALSE)    {      printf ("Set Parity Error\n");      exit (0);    }  char buf[255];  fd_set rd;  int nread = 0;  while(1)  {  FD_ZERO(&rd);FD_SET(fd, &rd);while(FD_ISSET(fd, &rd)){if(select(fd+1, &rd, NULL,NULL,NULL) < 0){perror("select error\n");}else{while((nread = read(fd, buf, sizeof(buf))) > 0){printf("nread = %d,%s\n",nread, buf);printf("test\n");memset(buf, 0 , sizeof(buf));}}}  }  close (fd);  return 0;}



聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.