【发布时间】:2019-07-31 15:33:16
【问题描述】:
我想通过 raspberrypi 的引脚发送一些串行输出,以便与无人机飞行控制器进行串行通信。控制器仅以奇怪的 100000 波特率运行。
我的代码并不总是正确设置波特率。有时我必须重新启动并重新启动代码 5 次才能获得正确的波特率。
代码不发送请求的数据。它发送更多。控制台的串行输出被禁用(通过 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_, &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