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)
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.
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.
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)
opt.c_cflag &= ~CSIZE;
- 清除当前字符大小掩码。
CSIZE
是代表字符大小的位掩码。清除它允许设置一个新的字符大小。
opt.c_cflag |= (CS8 | CLOCAL | CREAD);
CS8
:将字符大小设置为 8 位。CLOCAL
:忽略调制解调器控制线。这对于不涉及调制解调器的端口很重要。CREAD
:启用接收器,允许端口读取输入数据。
opt.c_cflag &= ~(PARENB | CSTOPB | CRTSCTS);
PARENB
:禁用奇偶校验生成和检测。CSTOPB
:清除 CSTOPB,这意味着它配置为一个停止位。如果设置了这个标志,则会选择两个停止位。CRTSCTS
:禁用硬件流控制(RTS/CTS)。
Handling Stop Bits
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 setsCSTOPB
for two stop bits; otherwise, it clearsCSTOPB
for one stop bit.
处理停止位
if (stop_ == 2) opt.c_cflag |= CSTOPB; else opt.c_cflag &= ~CSTOPB;
- 这个条件块设置停止位的数量。如果
stop_
是2,则为两个停止位设置CSTOPB
;否则,清除CSTOPB
以设置一个停止位。
Input Flags (opt.c_iflag
)
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
)
opt.c_iflag &= ~(IGNBRK | BRKINT | PARMRK | ISTRIP | INLCR | IGNCR | ICRNL | IXON);
- 这行代码禁用各种输入处理功能:
- 忽略中断条件。
- 禁用中断信号。
- 不标记奇偶校验错误。
- 不去除第八位。
- 不将 NL 映射为 CR,CR 映射为 NL,并忽略 CR。
- 禁用软件流控制(XON/XOFF)。
Local Flags (opt.c_lflag
)
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
)
opt.c_lflag &= ~(ECHO | ECHONL | ICANON | ISIG | IEXTEN);
- 关闭:
- 输入字符的回显。
- NL 的回显。
- 规范输入(基于行的输入处理)。
- 信号生成(INTR,QUIT,SUSP,或 DSUSP)。
- 任何实现定义的输入处理。
Output Flags (opt.c_oflag
)
opt.c_oflag &= ~OPOST;
- Disables output processing.
输出标志(opt.c_oflag
)
opt.c_oflag &= ~OPOST;
- 禁用输出处理。
Control Characters (opt.c_cc[VMIN]
and opt.c_cc[VTIME]
)
opt.c_cc[VMIN] = 1; opt.c_cc[VTIME] = 1;
VMIN
(Minimum number of characters to read): The code sets this to 1, meaning theread()
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 whichread()
will return if no additional character has arrived.
控制字符(opt.c_cc[VMIN]
和 opt.c_cc[VTIME]
)
opt.c_cc[VMIN] = 1; opt.c_cc[VTIME] = 1;
VMIN
(读取的最小字符数):代码将其设置为1,意味着一旦收到至少一个字符,read()
调用就会返回。VTIME
(等待数据的时间):设置为1(以十分之一秒为单位),在收到第一个字符后引入一个小的超时,之后如果没有其他字符到达,read()
将返回。
Explanation
- The buffer
buf
is read asunsigned 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 withstd::setw(2)
andstd::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 thedialout
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...