【问题标题】:Read return garbage data in serial port programming in linuxlinux下串口编程读取返回垃圾数据
【发布时间】:2016-01-28 10:45:05
【问题描述】:

我想使用 RS232 端口与我的 PC 通信。我可以使用 write() 函数打开“/dev/ttyS0”并写入数据,但使用 read() 无法从“dev/ttyS0”读取正确的数据>。 read() 函数读取了不需要的数据。请告诉我如何解决这个问题?

我的程序代码在这里:

#include <stdio.h>
#include <string.h>
#include <fcntl.h>
#include <termios.h>
#include <unistd.h>

int main()
{
    int n = 0, fd = 0, bytes = 0;

    char buffer[10];

    struct termios term;

    fd = open("/dev/ttyS0", O_RDWR | O_NOCTTY | O_NDELAY);

    if (fd == -1)
    {
        perror("open");
        return;
    }
    else
    {
        fcntl(fd, F_SETFL, 0);
        perror("Port");
    }

    tcgetattr(fd, &term);

    cfsetispeed(&term, B115200);
    cfsetospeed(&term, B115200);

    term.c_cflag |= (CLOCAL | CREAD);
    term.c_cflag &= ~PARENB;
    term.c_cflag &= ~CSTOPB;
    term.c_cflag &= ~CSIZE;
    term.c_cflag |= CS8;
    term.c_cflag &= ~CRTSCTS;
    term.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG);
    term.c_iflag &= ~(IXON | IXOFF | IXANY);
    term.c_oflag &= ~OPOST; 

    term.c_cc[VMIN] = 0;
    term.c_cc[VTIME] = 10;


    tcsetattr(fd, TCSANOW, &term); 

    printf("Enter the string...\n");
        scanf("%s", buffer);

        write(fd, buffer, sizeof(buffer));
        perror("write");

//  fcntl(fd, F_SETFL, FNDELAY);    

    sleep(1);

    bytes = read(fd, buffer, sizeof(buffer));
    perror("read");

    buffer[bytes] = '\0';
    printf("Bytes : %d\n", bytes);
    printf("%s\n", buffer);
    memset(buffer, '\0', 10);   
}

【问题讨论】:

  • 请举例说明您正在阅读什么数据以及您期望什么
  • 为什么要使用非阻塞 IO?你知道这是什么效果吗?
  • 例如“Hello world”读写垃圾数据
  • @FUZxxl:好点。也许fd 在调用tcgetattr 时还没有准备好(所以它可能只是返回-EAGAIN。代码不会检查任何错误,所以我建议使用strace 来查看进行了哪些系统调用,以及它们的返回值是什么。另外,请使用已知良好的终端模拟器,如 minicom 以确保一切正常。
  • @PeterCordes 库函数永远不会清除 errno。这是 POSIX 规则。

标签: c linux serial-port


【解决方案1】:

正如我已经回答 HERE 一样,以下代码运行良好。您是否尝试更改串行线?你确定你是在短接串行 DB9 连接器的 pin 2 和 pin 3 吗?

int main()
{
    int n = 0, fd = 0, bytes = 0;
    char ch = 0;

    char buffer[128], *bufPtr;
    int nBytes = 0, tries = 0, x = 0;

    struct termios term;

    fd = open("/dev/ttyUSB0", O_RDWR | O_NOCTTY | O_NDELAY);

    if (fd == -1)
    {
        perror("open");
        return;
    }
    else
    {
        fcntl(fd, F_SETFL, 0);
        perror("Port");
    }

    if (n = tcgetattr(fd, &term) == -1)
    {
        perror("tcgetattr");
        return;
    }

    if (n = cfsetispeed(&term, B115200) == -1)
    {
        perror("cfsetispeed");
        return;
    }

    if (n = cfsetospeed(&term, B115200) == -1)
    {
        perror("cfsetospeed");
        return;
    }

    term.c_cflag |= (CLOCAL | CREAD);
    term.c_cflag &= ~PARENB;
    term.c_cflag &= ~CSTOPB;
    term.c_cflag &= ~CSIZE;
    term.c_cflag |= CS8;
    term.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG);
    term.c_iflag &= ~(IXON | IXOFF | IXANY);
    term.c_cflag &= ~CRTSCTS;
    term.c_oflag &= ~OPOST;

    if (n = tcsetattr(fd, TCSANOW, &term) == -1)
    {
        perror("tcsetattr");
        return;
    }

    char stringToSend[128];

    printf("Enter the string...\n");
    scanf("%s", stringToSend);

    size_t len = strlen(stringToSend) +1 ;

    write(fd,stringToSend, len);
    perror("write");

    size_t receivedBytes = 0;
    bytes = 0;
    memset(buffer, 0x00, sizeof(buffer));
    while (receivedBytes<len)
    {
       bytes = read(fd, &buffer[receivedBytes], sizeof(buffer)-1);
       perror("read");

       if (bytes > 0)
           receivedBytes += bytes;
    }

    printf("Bytes : %d and data: %s\n", receivedBytes, buffer);
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-31
    • 2013-10-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多