歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
您现在的位置: Linux教程網 >> UnixLinux >  >> Linux編程 >> Linux編程

Linux下串口通信編程

由於串口通信需要自己寫代碼進行測試,同時要輪詢測試各波特率是否工作正常。按照網上的代碼,Linux下運行後總是或多或少有一些問題,後來借鑒APUE中關於tty_raw代碼部分進行修改,終於可以正常運行,通信不丟數,不修改數據。

同時在測試數據位為5,6時發現結果不正確,然後與其它同事了解後,發現串口下數據位5bit代表只會發送一個字節5bit。而不會自己進行拆分然後重組,得到原來的數據。例如,發送0xff,數據位5時,收到0x1f,數據位6時,收到0x3f,數據位7時,收到0x7f,數據位8時,收到0xff。同時串口配置的關鍵代碼向大家公開,供借鑒使用。

struct BaudRate{
 int speed;
 int bitmap;
};
struct BaudRate baudlist[] =
{
{ 50, B50 },
{ 75, B75 },
{ 110, B110 },
{ 134, B134 },
{ 150, B150 },
{ 200, B200 },
{ 300, B300 },
{ 600, B600 },
{ 1200, B1200 },
{ 1800, B1800 },
{ 2400, B2400 },
{ 4800, B4800 },
{ 9600, B9600 },
{ 19200, B19200 },
{ 38400, B38400 },
{ 57600, B57600 },
{ 115200, B115200 },
{ 230400, B230400 },
{ 460800, B460800 },
{ 500000, B500000 },
{ 576000, B576000 },
{ 921600, B921600 },
{ 1000000, B1000000 },
{ 1152000, B1152000 },
{ 1500000, B1500000 },
{ 2000000, B2000000 },
{ 2500000, B2500000 },
{ 3000000, B3000000 },
{ 3500000, B3500000 },
{ 4000000, B4000000 }, };
int comDatabits[] =
{ 5, 6, 7, 8 };
int comStopbits[] =
{ 1, 2 };
int comParity[] =
{ 'n', 'o', 'e' };

 

int set_com(int fd,int speed,int databits,int stopbits,int parity)
{
 int i;
 struct termios opt;

 if( tcgetattr(fd ,&opt) != 0)
 {
  perror("get attr failed!\n");
  return -1;
 }

 for (i = 0; i < sizeof(baudlist) / sizeof(baudlist[0]); i++)
 {
  struct BaudRate *rate = &baudlist[i];
  if (speed == rate->speed)
  {
   cfsetispeed(&opt, rate->bitmap);
   cfsetospeed(&opt, rate->bitmap);
   break;
  }
 }
// //修改控制模式,保證程序不會占用串口
// opt.c_cflag |= CLOCAL;
// //修改控制模式,使得能夠從串口中讀取輸入數據
// opt.c_cflag |= CREAD;

 opt.c_cflag &= ~CSIZE;
 switch (databits)
 {
 case 5:
  opt.c_cflag |= CS5;
  break;
 case 6:
  opt.c_cflag |= CS6;
  break;
 case 7:
  opt.c_cflag |= CS7;
  break;
 case 8:
  opt.c_cflag |= CS8;
  break;
 default:
  printf("Unsupported data size\n");
  return -1;
 }

 switch(parity)
 {
  case 'n':
  case 'N':
   opt.c_cflag &= ~PARENB;
   opt.c_iflag &= ~INPCK;
   break;
  case 'o':
  case 'O':
   opt.c_cflag |= (PARODD|PARENB);
   opt.c_iflag |= INPCK;
   break;
  case 'e':
  case 'E':
   opt.c_cflag |= PARENB;
   opt.c_cflag &= ~PARODD;
   opt.c_iflag |= INPCK;
   break;
  default:
   printf("Unsupported parity\n");
   return -1;
 }

 switch(stopbits)
 {
  case 1:
   opt.c_cflag &= ~CSTOPB;
   break;
  case 2:
   opt.c_cflag |=  CSTOPB;
   break;
  default:
   printf("Unsupported stop bits\n");
   return -1;
 }

 opt.c_iflag &= ~(IXON | IXOFF | IXANY | BRKINT | ICRNL | INPCK | ISTRIP);
 opt.c_lflag &=  ~(ICANON | ECHO | ECHOE | IEXTEN | ISIG);
 opt.c_oflag &= ~OPOST;
 opt.c_cc[VTIME] = 100;
 opt.c_cc[VMIN] = 0;

 tcflush(fd, TCIOFLUSH);
 if (tcsetattr(fd, TCSANOW, &opt) != 0)
 {
  perror("set attr failed!\n");
  return -1;
 }
 return 0;
}

Linux下串口通信示例程序  http://www.linuxidc.com/Linux/2010-06/26870.htm

Copyright © Linux教程網 All Rights Reserved