我正在Linux上编写用于串行端口数据传输的程序,但发现每次发送方打开端口时,接收方都会获得一个额外的空字节'\x00'
。
这是发件人的代码:
#include <unistd.h>
#include <termios.h>
#include <fcntl.h>
int main(int argc, char* argv[]) {
int fd_com_ = open("/dev/ttyAM0", O_RDWR | O_NOCTTY | O_NONBLOCK);
struct termios attrs_;
attrs_.c_iflag = IGNBRK;
attrs_.c_oflag = 0;
attrs_.c_cflag = (CLOCAL | CREAD);
attrs_.c_cflag |= CS8;
attrs_.c_lflag = 0;
attrs_.c_cc[VMIN] = 0;
attrs_.c_cc[VTIME] = 0;
cfsetspeed(&attrs_, B115200);
tcsetattr(fd_com_, TCSANOW, &attrs_);
const char *s = "abcd";
write(fd_com_, s, 4);
sleep(1);
write(fd_com_, s, 4);
sleep(1);
close(fd_com_);
fd_com_ = open("/dev/ttyAM0", O_RDWR | O_NOCTTY | O_NONBLOCK);
write(fd_com_, s, 4);
return 0;
}
接收器具有相同的配置,但接收"\x00abcdabcd\x00abcd"
。如何解决此问题,以便接收方可以获得"abcdabcdabcd"
?
更新
接收者代码:
#include <stdio.h>
#include <unistd.h>
#include <termios.h>
#include <fcntl.h>
int main(int argc, char* argv[]) {
int fd_com_ = open("/dev/ttyUSB0", O_RDWR | O_NOCTTY | O_NONBLOCK);
struct termios attrs_;
attrs_.c_iflag = IGNBRK;
attrs_.c_oflag = 0;
attrs_.c_cflag = (CLOCAL | CREAD);
attrs_.c_cflag |= CS8;
attrs_.c_lflag = 0;
attrs_.c_cc[VMIN] = 0;
attrs_.c_cc[VTIME] = 0;
cfsetspeed(&attrs_, B115200);
tcsetattr(fd_com_, TCSANOW, &attrs_);
char buf[100];
ssize_t sz;
while(1) {
sz = read(fd_com_, buf, 100);
if (sz > 0) {
for (ssize_t i=0; i<sz; i++) {
printf("%02hhx\n", buf[i]);
}
}
sleep(1);
}
return 0;
}
答案 0 :(得分:3)
请查看ARM板的文档,了解ARM的UART是如何连接的,以及如何在硬件和平台驱动程序中配置它。
根据您的描述,我认为当打开ARM上的UART端口时,物理UART(即ARM内的硬件外设模块或外部有线UART芯片)可以从某个未知的空闲状态启用或恢复状态到正确的-12伏RS232空闲状态。这种转换可能足以让您的PC的UART识别起始位并接收伪造的字符。
您可能需要使用示波器检查串行线,以了解实际打开端口时会发生什么。
答案 1 :(得分:1)
初始\x0
表示发生了奇偶校验或帧错误。
发生此错误,因为未正确设置termios字段。
所以初始线路的高/低状态和启动/停止位数和奇偶校验
没有正确设置。
你可能会读到:http://man7.org/linux/man-pages/man3/termios.3.html 讨论了每个领域及其内容和含义。
(链接页面太长,无法在此处发布)