如何使用 C 从 Linux 中的串口读取数据?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/8600275/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-06 03:46:40  来源:igfitidea点击:

How do I read data from serial port in Linux using C?

clinuxserial-port

提问by Amit Singh Tomar

I am new to serial programming in Linux using C. I have found a small piece of code to write data on serial port which I am sharing here. After running this code I may assume that data has written on a specific port. Now I would like to open another terminal and using separate code want to read the data written on that specific port - how do I do that?

我是使用 C 在 Linux 中进行串行编程的新手。我找到了一小段代码来在串行端口上写入数据,我在这里分享。运行此代码后,我可能会假设数据已写入特定端口。现在我想打开另一个终端并使用单独的代码想要读取写入该特定端口的数据 - 我该怎么做?

#include <stdio.h>   /* Standard input/output definitions */
#include <string.h>  /* String function definitions */
#include <unistd.h>  /* UNIX standard function definitions */
#include <fcntl.h>   /* File control definitions */
#include <errno.h>   /* Error number definitions */
#include <termios.h> /* POSIX terminal control definitions */

/*
 * 'open_port()' - Open serial port 1.
 *
 * Returns the file descriptor on success or -1 on error.
 */
int
open_port(void)
{
  int fd; /* File descriptor for the port */

  fd = open("/dev/ttyS0", O_RDWR | O_NOCTTY | O_NDELAY);
  if (fd == -1)
  {
   /* Could not open the port. */
    perror("open_port: Unable to open /dev/ttyS0 - ");
  }
  else
    fcntl(fd, F_SETFL, 0);

  n = write(fd, "ATZ\r", 4);
  if (n < 0)
    fputs("write() of 4 bytes failed!\n", stderr);

  return (fd);
}

The code above will write the data on a specific port.

上面的代码将在特定端口上写入数据。

回答by Jonathan Leffler

In theory, all you have to do is open the relevant port for reading, and use read()to get the data.

理论上,你要做的就是打开相关的端口进行读取,并使用read()来获取数据。

int
read_port(void)
{
    int fd = open("/dev/ttyS0", O_RDONLY | O_NOCTTY);
    if (fd == -1)
    {
        /* Could not open the port. */
        perror("open_port: Unable to open /dev/ttyS0 - ");
    }

    char buffer[32];
    int n = read(fd, buffer, sizeof(buffer));
    if (n < 0)
        fputs("read failed!\n", stderr);
    return (fd);
}

There are differences; notably, the read needs a buffer to put the data in. The code shown discards the first message read. Note that a short read simply indicates that there was less data available than requested at the time when the read completed. It does not automatically indicate an error. Think of a command line; some commands might be one or two characters (ls) where others might be quite complex (find /some/where -name '*.pdf' -mtime -3 -print). The fact that the same buffer is used to read both isn't a problem; one readgives 3 characters (newline is included), the other 47 or so.

有差异;值得注意的是,读取需要一个缓冲区来放入数据。显示的代码丢弃读取的第一条消息。请注意,短读取仅表示在读取完成时可用的数据少于请求的数据。它不会自动指示错误。想想命令行;一些命令可能是一两个字符 ( ls),而其他命令可能非常复杂 ( find /some/where -name '*.pdf' -mtime -3 -print)。使用同一个缓冲区读取两者的事实不是问题;一个read给出 3 个字符(包括换行符),另一个给出 47 个左右。

回答by datenwolf

The program posted makes a lot of assumptions about the state of the port. In a real world application you should do all the important setup explicitly. I think the best source for learning serial port programming under POSIX is the

发布的程序对端口的状态做了很多假设。在现实世界的应用程序中,您应该明确地进行所有重要的设置。我认为学习 POSIX 下串口编程的最佳来源是

Serial Programming Guide for POSIX Operating Systems

POSIX 操作系统串行编程指南

I'm mirroring it here: https://www.cmrr.umn.edu/~strupp/serial.html

我在这里镜像:https: //www.cmrr.umn.edu/~strupp/serial.html