在无限循环之外,SerialRead不能正常工作

时间:2016-11-22 14:43:48

标签: c serial-port uart

我已在此处阅读了所有相关问题,但未找到解决方案。

我试图从串口读取一个字节。

  • 当我处于无限循环中并且检查是否有一些字节可用时,它总是正常工作并显示我发送给它的内容。
  • 但是当我在无限循环之外检查时,它只捕获一个字节,显示它,然后关闭串行端口。

这是我的代码

// Checks if 1 data byte is available in the RX buffer at the moment
int serialHasChar(int fd)
{
  struct pollfd fds;
  fds.fd = fd;
  fds.events = (POLLIN | POLLPRI);  // POLLIN : There is data to read, POLLPRI: There is urgent data to read
  if(poll(&fds, 1, 0) > 0)
    {
      return 1;
    }
  else
    {
      return 0;
    }
}

int serialOpen(const char *port, const uint baud)
    {
      int fd = -1;

  fd = open(port, O_RDWR | O_NOCTTY | O_NDELAY);

  if (fd == -1)
    {
      printf("[ERROR] Couldn't open port \"%s\": %s\n", port, strerror(errno));
      return -1;
    }
  else
    {
      printf("Serial port %s successfully opened\n", port);
    }

  struct termios options;
  tcgetattr(fd, &options);      // Get the current attributes of the Serial port
  options.c_iflag = IGNPAR;
  options.c_oflag = 0;
  options.c_lflag = 0;
  options.c_cflag = B115200 | CS8 | CLOCAL | CREAD;
  tcflush(fd, TCIFLUSH);          
  tcsetattr(fd, TCSANOW, &options);   

  return fd;
}

void serialClose(int fd)
{
  tcflush(fd, TCIOFLUSH);
  close(fd);
      printf("Serial port successfully closed\n");
}


// Receive one byte
uint8_t serialReadChar(int fd)
{
  uint8_t ch;
  //tcflow(fd, TCOON);
  read(fd, &ch, 1);
  //tcflow(fd, TCOOFF);
  printf("One byte received : 0x%.2x\n", ch);
  return ch;
}

int main()
{
  uint8_t bytes = 0;
  uint8_t ch = 0;

  // Open serial port
  int fd = serialOpen("/dev/ttyAMA0", 115200);

  // This works
  while(1)
    {
      if (serialHasChar(fd)) {
    ch = serialReadChar(fd);
      }
    }

  /* This doesn't work
  while(serialHasChar(fd) == 0);

  while(serialHasChar(fd))
    {
      ch = serialReadChar(fd);
      bytes++;
      //bytes = serialNumOfAvailableBytes(fd);
    }
  */

  serialClose(fd);

  return 0;
} 

我不明白为什么会这样!有人能帮助我吗? 感谢

更新 我在上面的代码中添加了serialHasChar()函数的定义

3 个答案:

答案 0 :(得分:0)

与它无关的代码与不起作用的代码完全相同。

只要serialHasChar返回非空值,就会调用serialReadChar

while(1)
{
  if (serialHasChar(fd)) {
    ch = serialReadChar(fd);
  }
}

但是在下面的代码中(那个不起作用的代码)它有点不同:你调用serialHasChar直到它返回一个非空值。但是,您再次拨打serialHasChar,而不是像在有效的代码段中调用serialReadChar一样。

while(serialHasChar(fd) == 0);

while(serialHasChar(fd))
{
  ch = serialReadChar(fd);
}

你可能需要这个:

while(serialHasChar(fd) == 0);

do
{
  ch = serialReadChar(fd);
} while(serialHasChar(fd));

答案 1 :(得分:0)

试试这个:

while(serialHasChar(fd) == 0);

while(serialHasChar(fd))
{
    ch = serialReadChar(fd);
    bytes++;
    while(serialHasChar(fd) == 0);
}

答案 2 :(得分:0)

如果没有额外的循环,代码将无法正常工作。

只要从串行接口读取所有可用字节,即使新数据到达端口,您也将离开循环并且永远不会再读取一个字节。

由于您可以比大多数串行端口传输数据更快地读取数据,因此很快就会在缓冲区中耗尽字节数,即在您注意到的第一个字节之后。 然后你需要弥补差距,直到下一个字节可用。

在您的工作解决方案中,您大部分时间都会从serialHasChar(fd)获得0,因此不会调用serialReadChar(fd),而只是继续循环。