使用串行端口时接收额外的空字节

时间:2014-12-14 15:42:32

标签: c linux serial-port

我正在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;
}

2 个答案:

答案 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 讨论了每个领域及其内容和含义。

(链接页面太长,无法在此处发布)