当前位置: 首页 > 知识库问答 >
问题:

SerialRead在无限循环之外无法正常工作

臧兴学
2023-03-14

我已经阅读了这里所有的相关问题,但没有找到解决方案。

我正试图从串行端口一个接一个地读取字节。

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

这是我的密码

// 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个答案

常明亮
2023-03-14

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

一旦从串行接口读取所有可用字节,即使新数据到达端口,也将离开循环,不再读取字节。

由于读取速度比大多数串行端口传输数据的速度快得多,缓冲区中的字节很快就会用完,也就是说,正如您已经注意到的那样,在第一个字节之后。然后您需要桥接该间隙,直到下一个字节可用。

在您的工作解决方案中,您将在大多数情况下从序列HasChar(fd)获得0,因此不调用序列ReadChar(fd),而只是继续循环。

刁浩言
2023-03-14

试试这个:

while(serialHasChar(fd) == 0);

while(serialHasChar(fd))
{
    ch = serialReadChar(fd);
    bytes++;
    while(serialHasChar(fd) == 0);
}
郭俊拔
2023-03-14

起作用的代码与不起作用的代码并不完全相同。

这里只要serialHasChar返回一个非nul值,就可以调用serialReadChar

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

但是在下面的代码中(不起作用的代码)有点不同:你调用序列HasChar,直到它返回一个非nul值。但是,您第二次调用序列HasChar,而不是像在工作的代码段中那样调用序列ReadChar

while(serialHasChar(fd) == 0);

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

你可能需要这个:

while(serialHasChar(fd) == 0);

do
{
  ch = serialReadChar(fd);
} while(serialHasChar(fd));
 类似资料:
  • 问题内容: 我有这段代码,我想浏览页面底部所有可用的链接。单击它们后,我要确保打开的URL是正确的。我认为递归调用还为时过早。另一个问题是如何判断链接属于某个URL。 问题答案: 嗯,看来您几天前就受够了。我建议您使用page-object,它将帮助您避免使用硬代码,并在将来更轻松地更改css。 主页对象(home.js)可能像这样: 并且在您的测试中应该像: PS:如果您不知道如何创建页面对象,

  • 我试图使一个计算器与一定的输入,是输入像+5或/10 2。当我编译并运行它时,我会得到以下错误: 线程“main”java.util.NoSuchelementException 在java.util.scanner.throwfor(Scanner.java:907) 在java.util.scanner.next(Scanner.java:1416) 在calc.main(calc.java:

  • 问题内容: 我的问题很简短。我不明白为什么我的程序在捕获错误时会无限循环。我做了一个新的try- catch语句,但是它循环了,甚至复制,粘贴并修改了以前有效的程序中的适当变量。下面是语句本身,下面是整个程序。谢谢您的帮助! 程序: 问题答案: 您的程序将永远运行,因为在不更改扫描仪状态的情况下进行调用会一次又一次地引发异常:如果用户未输入,则调用不会更改扫描仪的外观,因此,当您在下一次迭代中进行

  • hasNext()的定义是“如果此扫描仪的输入中有另一个标记,则返回true。此方法可能会在等待输入扫描时阻塞。扫描仪不会前进超过任何输入。” 当我把 standardInput.hasNext() 放在 for 循环中时,程序会向无穷大运行。但是如果我把它放在 while-loop 中,它不会运行到无穷大。这两个程序之间的区别在哪里,为什么其中一个有效而另一个无效? for循环: while-l

  • 我正在用我的java书复习数据结构,我需要重新创建一个循环链表。我对这个无限循环的链表有问题,弄不清楚为什么。我可以将值插入到列表中,但是打印和删除这些值似乎会无限循环最初插入的值。我如何更改我的List类以避免无限循环? CircularList.Class 链接类

  • 我有一个带感应帽的覆盆子皮。我制作了一个二进制时钟,我想在Sense hat的显示器上显示并保持更新。然而,我想要的能力,开关时钟与操纵杆中间。一切都很好,除了我的时钟的更新循环阻止任何新的输入一旦启动。 我一直在考虑如何解决这个问题。如何允许脚本/时钟保持运行,并且仍然接受来自操纵杆的新操作。但是一旦while循环开始,我就卡住了。我不知道该用谷歌搜索什么。我已经开始研究async/await,