【问题标题】:Why does the raspberrypi not send the requested serial output?为什么树莓派不发送请求的串行输出?
【发布时间】:2019-07-31 15:33:16
【问题描述】:

我想通过 raspberrypi 的引脚发送一些串行输出,以便与无人机飞行控制器进行串行通信。控制器仅以奇怪的 100000 波特率运行。

  1. 我的代码并不总是正确设置波特率。有时我必须重新启动并重新启动代码 5 次才能获得正确的波特率。

  2. 代码不发送请求的数据。它发送更多。控制台的串行输出被禁用(通过 raspi-config)。

我尝试用 python 编写它,但代码运行速度太慢(我也需要使用 OpenCV 进行图像处理)所以我切换到 C++。 python代码工作正常。我已经尝试了 wjwood 的串行库:http://wjwwood.github.com/serial/,但由于奇怪的波特率,它也无法正常工作。使用 stty 命令设置波特率也失败了。 我尝试使用 setispeed 函数和旧的 termios 结构设置波特率。这也没有用。

这是我的代码:

#include <fcntl.h>
#include <unistd.h>
#include <stropts.h>
#include <asm/termios.h>

#include <iostream>

int main()
{
   int fd_ = ::open("/dev/ttyAMA0", O_RDWR);

   struct termios2 options;

   ioctl(fd_, TCGETS2, &options);
   options.c_cflag |= PARENB;
   options.c_cflag &= ~CBAUD;
   options.c_cflag |= BOTHER;
   options.c_ispeed = 100000;
   options.c_ospeed = 100000;
   options.c_cc[VTIME] = 10;
   options.c_cc[VMIN] = 0;

   unsigned char buf[25];
   for (int i = 0; i != 25; i++)
   {
      buf[i] = 2 * i;
   }
   ioctl(fd_, TCSETS2, &options);

   for (int i = 0; i != 25; i++)
   {
      std::cout << static_cast<int>(buf[i]) << " ";
   }
   std::cout << std::endl;

   ::write(fd_, &buf, 25);
   ::close(fd_);
}

预期是串行输出,例如:0x00 0x02 0x04 ... 0x30。 但我得到:0x5E 0x4F 0x5E 0x40 ... 0x00 0x02 0x04 ... 0x30。

我发送的越多,额外的无用字节就会阻塞总线并混淆飞行控制器。

【问题讨论】:

  • 控制器只能以奇怪的 100000 波特率运行,这让事情变得很困难。您需要提供有效的speed_t 值,而 100000 可能无效。 How to set baud rate to 307200 on Linux? 有帮助吗?
  • 我之前看到了那个帖子,并使用代码设置了 baurate。如果它可以设置波特率,它会一直如此,直到重新启动。但奇怪的额外字节是更大的问题。
  • 这应该没有帮助(如果它以某种方式起作用,我将不得不更深入地阅读标准对数组和指针之间关系的说明)但我总是对像::write(fd_, &amp;buf, 25); 这样的东西。 buf 是一个数组。它会自动衰减为指针。使用::write(fd_, buf, 25); 消除代码中潜在的混淆点。
  • 串行链路要求两端的波特率、字符大小、奇偶校验和停止位数的配置相同。你忽略了这个“无人机飞控”上的串口是如何配置的。您的程序只配置了两个参数,而将其他两个参数留给机会。 IOW 您的 termios 配置不完整。不要期望可靠的串行通信。顺便说一句,您如何确定 “错误” 串行输出是什么?
  • 控制器使用 100000 波特,每字节 8 位(默认设置),偶校验(如设置),一个停止位(默认)。我用逻辑分析仪测量了串行通信。唯一的问题是波特率,其余设置正确。正确的输出由第一个循环确定(0 到 48,步长为 to,这应该在串行总线上以十六进制形式获得 0x00、0x02 等。但总线上还有更多,就像我写的那样。

标签: c++ raspberry-pi serial-port termios raspberry-pi-zero


【解决方案1】:

感谢sawdust,我知道问题出在“默认设置”的标志上。因为他们不是。为了修复我的代码,我在this guide 关于 Linux 串行编程的帮助下添加了这些标志:

options.c_cflag &= ~CRTSCTS;
options.c_cflag |= CREAD | CLOCAL;
options.c_lflag &= ~ICANON;
options.c_lflag &= ~ECHO;
options.c_lflag &= ~ECHOE;
options.c_lflag &= ~ECHONL;
options.c_lflag &= ~ISIG;
options.c_iflag &= ~(IXON | IXOFF | IXANY);
options.c_iflag &= ~(IGNBRK|BRKINT|PARMRK|ISTRIP|INLCR|IGNCR|ICRNL);
options.c_oflag &= ~OPOST; 
options.c_oflag &= ~ONLCR;

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-09-04
    • 2021-10-18
    • 1970-01-01
    • 2016-12-07
    • 2020-07-14
    • 2019-07-16
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多