Windows串口读取
要使用 C++ 读取串口数据,你需要使用串口编程库。在 Windows 平台上,可以使用 WinAPI 提供的串口编程接口。以下是一个简单的示例程序,用于打开 COM1 串口端口,读取数据并输出到控制台:
#include <iostream>
#include <windows.h>int main()
{HANDLE hSerial;DCB dcbSerialParams = { 0 };COMMTIMEOUTS timeouts = { 0 };DWORD bytesRead;// 打开 COM1 串口端口hSerial = CreateFile("COM1", GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);if (hSerial == INVALID_HANDLE_VALUE){std::cerr << "Error opening serial port." << std::endl;return 1;}// 配置串口参数dcbSerialParams.DCBlength = sizeof(dcbSerialParams);if (!GetCommState(hSerial, &dcbSerialParams)){std::cerr << "Error getting serial port state." << std::endl;CloseHandle(hSerial);return 1;}dcbSerialParams.BaudRate = CBR_9600;dcbSerialParams.ByteSize = 8;dcbSerialParams.Parity = NOPARITY;dcbSerialParams.StopBits = ONESTOPBIT;if (!SetCommState(hSerial, &dcbSerialParams)){std::cerr << "Error setting serial port state." << std::endl;CloseHandle(hSerial);return 1;}// 配置串口超时时间timeouts.ReadIntervalTimeout = 50;timeouts.ReadTotalTimeoutConstant = 50;timeouts.ReadTotalTimeoutMultiplier = 10;timeouts.WriteTotalTimeoutConstant = 50;timeouts.WriteTotalTimeoutMultiplier = 10;if (!SetCommTimeouts(hSerial, &timeouts)){std::cerr << "Error setting serial port timeouts." << std::endl;CloseHandle(hSerial);return 1;}// 读取串口数据并输出到控制台char buffer[1024];while (true){if (!ReadFile(hSerial, buffer, sizeof(buffer), &bytesRead, NULL)){std::cerr << "Error reading serial port." << std::endl;CloseHandle(hSerial);return 1;}if (bytesRead
Linux串口读取
在 Linux 上,你可以使用 POSIX 标准提供的串口编程接口。以下是一个简单的示例程序,用于打开 /dev/ttyS0 串口端口,读取数据并输出到控制台。
#include <iostream>
#include <fcntl.h>
#include <termios.h>
#include <unistd.h>int main()
{int fd;struct termios tty;char buffer[1024];ssize_t bytesRead;// 打开 /dev/ttyS0 串口端口fd = open("/dev/ttyS0", O_RDONLY | O_NOCTTY);if (fd == -1){std::cerr << "Error opening serial port." << std::endl;return 1;}// 配置串口参数if (tcgetattr(fd, &tty) != 0){std::cerr << "Error getting serial port attributes." << std::endl;close(fd);return 1;}cfsetospeed(&tty, B9600);cfsetispeed(&tty, B9600);tty.c_cflag |= (CLOCAL | CREAD);tty.c_cflag &= ~PARENB;tty.c_cflag &= ~CSTOPB;tty.c_cflag &= ~CSIZE;tty.c_cflag |= CS8;tty.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG);tty.c_iflag &= ~(INPCK | ISTRIP);tty.c_oflag &= ~OPOST;tty.c_cc[VMIN] = 1;tty.c_cc[VTIME] = 0;if (tcsetattr(fd, TCSANOW, &tty) != 0){std::cerr << "Error setting serial port attributes." << std::endl;close(fd);return 1;}// 读取串口数据并输出到控制台while (true){bytesRead = read(fd, buffer, sizeof(buffer));if (bytesRead == -1){std::cerr << "Error reading serial port." << std::endl;close(fd);return 1;}if (bytesRead > 0){std::cout.write(buffer, bytesRead);}}// 关闭串口close(fd);return 0;
}
该程序使用 open() 打开 /dev/ttyS0 串口端口,使用 tcgetattr() 和 tcsetattr() 配置串口参数,并使用 read() 读取串口数据。
RS-232和RS-485的差别
在串口编程中,232 和 485 都是串口协议的一种,它们之间的物理层和数据链路层不同,因此它们需要的硬件和软件配置也不同。
在代码实现中,串口通信的核心是通过串口读取和发送数据,这部分代码不会因为串口协议的不同而有太大的变化。但是,不同的串口协议可能需要不同的初始化和配置。下面是一些可能需要考虑的区别:
- 波特率:在串口通信中,波特率指的是数据传输速率,通常用 bps 表示。232 和 485 通常支持的波特率范围是相同的,但具体的传输速率可能需要根据不同的设备或场景进行调整。
- 数据位、停止位、校验位:这些是串口通信中的数据格式,不同的设备或场景可能需要不同的数据格式。232 和 485 支持的数据格式是相同的,但在实际应用中可能需要进行不同的设置。
- 硬件控制流:硬件控制流可以通过 RTS 和 CTS 信号进行控制,常用于数据流控制。232 通常使用硬件流控,而 485 通常使用软件流控。
- 信号控制:485 在物理层上需要进行收发切换,而 232 不需要。因此,在代码实现上,485 通常需要对收发控制信号进行配置和控制,例如使用 GPIO 控制收发切换。
总之,虽然 232 和 485 的代码在细节上可能存在一些差异,但是它们的核心都是通过串口读取和发送数据。因此,通过理解串口通信的基本原理,我们可以根据具体的需求进行相应的调整和配置。