LINUX下USB转串口编程中的一点心得

串口设备的名字

普通物理串口是ttySx,比如ttyS0, ttyS1等,USB转串口的设备名为ttyUSBx,比如ttyUSB0, ttyUSB1等

设置读写RAW模式

这一步非常重要,不设置就收不到数据,一个字节都没有,下面是设置RAW模式的代码

int SetRawMode(int fd)
{
  struct termios opt;
  opt.c_iflag &= ~(IGNBRK|BRKINT|PARMRK|ISTRIP|INLCR|IGNCR|ICRNL|IXON);
  opt.c_oflag &= ~OPOST;
  opt.c_lflag &= ~(ECHO|ECHONL|ICANON|ISIG|IEXTEN);
  opt.c_cflag &= ~(CSIZE|PARENB);
  opt.c_cflag |= CS8;
  
  if (tcsetattr(fd, TCSANOW, &opt)!=0) {
    fprintf(stderr, "set rawmode fail
");
    return -1;
  } else {
    fprintf(stderr, "set rawmode ok
");
    return 0;
  }
}

  

读写超时控制

尤其是读操作,否则经常收不全数据,下面是读的示例代码

int ReadFix(int fd, char* buffer, int FixLen, int Timeout)
{
  struct timeval timeout;
  fd_set readfds, writefds;
  int index = 0, rt = 0, s = 0, ms = 0;

  s = Timeout/1000;
  ms = Timeout%1000;
  timeout.tv_sec = s;
  timeout.tv_usec = ms*1000;
  FD_ZERO(&readfds);
  FD_SET(fd, &readfds);
  switch(select(fd+1, &readfds, NULL, NULL, &timeout)) {
  case 0:
    fprintf(stderr, "read timeout
");
    break;
  case -1:
    fprintf(stderr, "read fail
");
    break;
  default:
    if (FD_ISSET(fd, &readfds)) {
      while (1) {
        rt = read(fd, buffer+index, FixLen-index);
        if (rt<=0) {
          break;
        }
        index += rt;
        if (index >= FixLen) break;
      }
    }
    break;
  }
  
  return index;
}

  

调用流程示例

int main(int argc, char* argv[])
{
  char szSendBuf[128], szRecvBuf[128];
  int rt = 0;
  
  OpenSerial();
  
  SetRawMode();
  rt = WriteFix(szSendBuf, nSendLen, 5000);
  rt = ReadFix(szRecvBuf, 20, 5000);
  if (rt<=0) {
    // 读失败
    return -1;
  }
  if (rt<20) {
    // 未读完,继续读,此处最好循环处理
    rt = ReadFix(szRecvBuf+rt, 20-rt, 5000);
  }
  CloseSerial();
  return 0;
}

  

原文地址:https://www.cnblogs.com/cner/p/13071325.html