Sample to read serial port data in C++ using poll

This C++ code demonstrates how to read data from a serial port using the poll function. It configures the serial port settings, sets up the poll file descriptor, and reads data from the serial port. The code also includes explanations of different flags for configuring and using the serial port. The program continuously reads data from the serial port and prints it in hexadecimal format. It can be compiled and run, and the format can be adjusted as needed.
这段 C++ 代码演示了如何使用 poll 函数从串行端口读取数据。它配置了串行端口的设置,设置了 poll 文件描述符,并从串行端口读取数据。代码还包括了对串行端口配置和使用的不同标志的解释。程序不断地从串行端口读取数据并以十六进制格式打印出来。它可以被编译和运行,并且可以根据需要进行格式调整。

Updated C++ Program: read_serial.cpp

Serial Port Configuration (8N1)

  1. opt.c_cflag &= ~CSIZE;
      • Clears the current character size mask. CSIZE is a bitmask that represents the character size. Clearing it allows setting a new character size.
  1. opt.c_cflag |= (CS8 | CLOCAL | CREAD);
      • CS8: Sets the character size to 8 bits.
      • CLOCAL: Ignores modem control lines. This is important for ports that do not involve modems.
      • CREAD: Enables the receiver, allowing the port to read input data.
  1. opt.c_cflag &= ~(PARENB | CSTOPB | CRTSCTS);
      • PARENB: Disables parity generation and detection.
      • CSTOPB: Clears the CSTOPB, which means it configures for one stop bit. Two stop bits would be selected if this flag was set.
      • CRTSCTS: Disables hardware flow control (RTS/CTS).

串行端口配置(8N1)

  1. opt.c_cflag &= ~CSIZE;
      • 清除当前字符大小掩码。CSIZE 是代表字符大小的位掩码。清除它允许设置一个新的字符大小。
  1. opt.c_cflag |= (CS8 | CLOCAL | CREAD);
      • CS8:将字符大小设置为 8 位。
      • CLOCAL:忽略调制解调器控制线。这对于不涉及调制解调器的端口很重要。
      • CREAD:启用接收器,允许端口读取输入数据。
  1. opt.c_cflag &= ~(PARENB | CSTOPB | CRTSCTS);
      • PARENB:禁用奇偶校验生成和检测。
      • CSTOPB:清除 CSTOPB,这意味着它配置为一个停止位。如果设置了这个标志,则会选择两个停止位。
      • CRTSCTS:禁用硬件流控制(RTS/CTS)。

Handling Stop Bits

  1. if (stop_ == 2) opt.c_cflag |= CSTOPB; else opt.c_cflag &= ~CSTOPB;
      • This conditional block sets the number of stop bits. If stop_ is 2, it sets CSTOPB for two stop bits; otherwise, it clears CSTOPB for one stop bit.

处理停止位

  1. if (stop_ == 2) opt.c_cflag |= CSTOPB; else opt.c_cflag &= ~CSTOPB;
      • 这个条件块设置停止位的数量。如果 stop_ 是2,则为两个停止位设置 CSTOPB;否则,清除 CSTOPB 以设置一个停止位。

Input Flags (opt.c_iflag)

  1. opt.c_iflag &= ~(IGNBRK | BRKINT | PARMRK | ISTRIP | INLCR | IGNCR | ICRNL | IXON);
      • This line disables various input processing features:
        • Ignore break condition.
        • Disable break interrupt.
        • Do not mark parity errors.
        • Do not strip off the eighth bit.
        • Do not map NL to CR, CR to NL, and ignore CR.
        • Disable software flow control (XON/XOFF).

输入标志(opt.c_iflag

  1. opt.c_iflag &= ~(IGNBRK | BRKINT | PARMRK | ISTRIP | INLCR | IGNCR | ICRNL | IXON);
      • 这行代码禁用各种输入处理功能:
        • 忽略中断条件。
        • 禁用中断信号。
        • 不标记奇偶校验错误。
        • 不去除第八位。
        • 不将 NL 映射为 CR,CR 映射为 NL,并忽略 CR。
        • 禁用软件流控制(XON/XOFF)。

Local Flags (opt.c_lflag)

  1. opt.c_lflag &= ~(ECHO | ECHONL | ICANON | ISIG | IEXTEN);
      • Turns off:
        • Echoing of input characters.
        • Echoing of NL.
        • Canonical input (line-oriented input processing).
        • Signal generation (INTR, QUIT, SUSP, or DSUSP).
        • Any implementation-defined input processing.

本地标志(opt.c_lflag

  1. opt.c_lflag &= ~(ECHO | ECHONL | ICANON | ISIG | IEXTEN);
      • 关闭:
        • 输入字符的回显。
        • NL 的回显。
        • 规范输入(基于行的输入处理)。
        • 信号生成(INTR,QUIT,SUSP,或 DSUSP)。
        • 任何实现定义的输入处理。

Output Flags (opt.c_oflag)

  1. opt.c_oflag &= ~OPOST;
      • Disables output processing.

输出标志(opt.c_oflag

  1. opt.c_oflag &= ~OPOST;
      • 禁用输出处理。

Control Characters (opt.c_cc[VMIN] and opt.c_cc[VTIME])

  1. opt.c_cc[VMIN] = 1; opt.c_cc[VTIME] = 1;
      • VMIN (Minimum number of characters to read): The code sets this to 1, meaning the read() call will return once at least one character is received.
      • VTIME (Time to wait for data): Set to 1 (in deciseconds), it introduces a small timeout after the first character is received, after which read() will return if no additional character has arrived.

控制字符(opt.c_cc[VMIN]opt.c_cc[VTIME]

  1. opt.c_cc[VMIN] = 1; opt.c_cc[VTIME] = 1;
      • VMIN(读取的最小字符数):代码将其设置为1,意味着一旦收到至少一个字符,read() 调用就会返回。
      • VTIME(等待数据的时间):设置为1(以十分之一秒为单位),在收到第一个字符后引入一个小的超时,之后如果没有其他字符到达,read() 将返回。

Explanation

  • The buffer buf is read as unsigned char to properly handle byte values.
  • Inside the read loop, each byte read from the serial port is converted to hexadecimal format using std::hex and printed with std::setw(2) and std::setfill('0') to ensure two-digit hex numbers.
  • std::uppercase is used to print hexadecimal digits in uppercase.

说明

  • 缓冲区 buf 作为 unsigned char 读取,以正确处理字节值。
  • 在读取循环中,从串行端口读取的每个字节都使用 std::hex 转换为十六进制格式,并使用 std::setw(2)std::setfill('0') 打印,以确保两位十六进制数字。
  • 使用 std::uppercase 以大写形式打印十六进制数字。

Compile and Run

Compile the program with g++:
Run the compiled program:

Note

  • Ensure you have appropriate permissions to access the serial port (sudo or add your user to the dialout group).
  • This program will continue running indefinitely. Use Ctrl+C to stop it.
  • The program prints each byte in hexadecimal format, separated by spaces, and groups of bytes are separated by newlines. You can adjust the formatting to suit your needs.

注意

  • 确保您有适当的权限访问串行端口(使用 sudo 或将您的用户添加到 dialout 组)。
  • 这个程序将无限期地运行。使用 Ctrl+C 来停止它。
  • 该程序以十六进制格式打印每个字节,字节之间用空格分隔,字节组之间用换行符分隔。您可以根据需要调整格式。
Loading...