以下是一个简单的例子,展示如何在 Linux 下通过串口发送和接收数据:
头文件 serial_communication.h
cpp
#ifndef SERIAL_COMMUNICATION_H
#define SERIAL_COMMUNICATION_H
#include <termios.h>
#include <fcntl.h>
#include <unistd.h>
#include <string>
#include <iostream>
class SerialPort {
public:
SerialPort(const std::string &portName);
~SerialPort();
bool openPort();
void closePort();
bool writeData(const std::string &data);
std::string readData();
private:
std::string portName;
int fd; // 文件描述符
struct termios oldtio, newtio; // termios 配置结构体
bool configurePort();
};
#endif // SERIAL_COMMUNICATION_H
实现文件 serial_communication.cpp
cpp
#include "serial_communication.h"
SerialPort::SerialPort(const std::string &portName)
: portName(portName), fd(-1) {}
SerialPort::~SerialPort() {
closePort();
}
bool SerialPort::openPort() {
// 打开串口设备
fd = open(portName.c_str(), O_RDWR | O_NOCTTY | O_NDELAY);
if (fd == -1) {
std::cerr << "Failed to open serial port: " << portName << std::endl;
return false;
}
// 配置串口
if (!configurePort()) {
return false;
}
return true;
}
void SerialPort::closePort() {
if (fd != -1) {
close(fd);
}
}
bool SerialPort::configurePort() {
// 获取当前串口配置
if (tcgetattr(fd, &oldtio) != 0) {
std::cerr << "Failed to get serial port settings" << std::endl;
return false;
}
// 设置新的串口参数
newtio = oldtio;
newtio.c_cflag = B9600 | CS8 | CLOCAL | CREAD; // 设置波特率、数据位、启用接收
newtio.c_iflag = IGNPAR; // 忽略无效字符
newtio.c_oflag = 0; // 无特殊输出处理
newtio.c_lflag = 0; // 禁用行模式
newtio.c_cc[VMIN] = 1; // 最小字符数
newtio.c_cc[VTIME] = 0; // 等待时间
// 设置串口
if (tcsetattr(fd, TCSANOW, &newtio) != 0) {
std::cerr << "Failed to set serial port settings" << std::endl;
return false;
}
return true;
}
bool SerialPort::writeData(const std::string &data) {
ssize_t bytesWritten = write(fd, data.c_str(), data.length());
if (bytesWritten == -1) {
std::cerr << "Failed to write data to serial port" << std::endl;
return false;
}
return true;
}
std::string SerialPort::readData() {
char buffer[256];
ssize_t bytesRead = read(fd, buffer, sizeof(buffer) - 1);
if (bytesRead == -1) {
std::cerr << "Failed to read data from serial port" << std::endl;
return "";
}
buffer[bytesRead] = '\0'; // Null-terminate the string
return std::string(buffer);
}
使用示例:main.cpp
cpp
#include <iostream>
#include "serial_communication.h"
int main() {
SerialPort serial("/dev/ttyS0"); // 使用 ttyS0 串口设备(可以根据实际情况修改)
if (!serial.openPort()) {
return -1; // 打开串口失败
}
// 发送数据
if (!serial.writeData("Hello, Serial Port!")) {
return -1; // 写数据失败
}
// 读取数据
std::string data = serial.readData();
std::cout << "Received: " << data << std::endl;
serial.closePort(); // 关闭串口
return 0;
}
自动获取串口设备的方法:
可以使用 opendir
和 readdir
函数遍历 /dev
目录下的串口设备文件,列出所有可能的串口设备。下面是一个简单的示例,展示如何自动列出系统中所有的串口设备。
cpp
#include <iostream>
#include <dirent.h>
#include <string>
void listSerialPorts() {
DIR *dir = opendir("/dev");
if (dir == nullptr) {
std::cerr << "Failed to open /dev directory!" << std::endl;
return;
}
struct dirent *entry;
while ((entry = readdir(dir)) != nullptr) {
// 检查文件名是否以 "tty" 开头
std::string name(entry->d_name);
if (name.find("ttyS") == 0 || name.find("ttyUSB") == 0) {
std::cout << "Found serial port: /dev/" << name << std::endl;
}
}
closedir(dir);
}
int main() {
listSerialPorts(); // 列出所有串口设备
return 0;
}