linux 下的termios读写

以下是一个简单的例子,展示如何在 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;
}

自动获取串口设备的方法:

可以使用 opendirreaddir 函数遍历 /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;
}
相关推荐
原神启动15 分钟前
Docker 场景化作业:生产环境容器操作实训
运维·docker·容器
云老大TG:@yunlaoda36010 分钟前
如何通过华为云国际站代理商CSBS进行备份策略设置?
运维·数据库·华为云
老王熬夜敲代码1 小时前
解决IP不够用的问题
linux·网络·笔记
zly35001 小时前
linux查看正在运行的nginx的当前工作目录(webroot)
linux·运维·nginx
来自于狂人1 小时前
华为云Stack服务实例创建失败通用排查对照表(备考+生产故障定位必备)
服务器·数据库·华为云
QT 小鲜肉1 小时前
【Linux命令大全】001.文件管理之file命令(实操篇)
linux·运维·前端·网络·chrome·笔记
呼啦啦呼啦啦啦啦啦啦1 小时前
docker制作镜像的两种方式(保姆级教学)
运维·docker·容器
问道飞鱼2 小时前
【Linux知识】Linux 虚拟机磁盘扩缩容操作指南(按文件系统分类)
linux·运维·服务器·磁盘扩缩容
egoist20232 小时前
【Linux仓库】超越命令行用户:手写C语言Shell解释器,解密Bash背后的进程创建(附源码)
linux·c语言·bash·xshell·环境变量·命令行参数·内建命令
Lenyiin2 小时前
《 Linux 修炼全景指南: 八 》别再碎片化学习!掌控 Linux 开发工具链:gcc、g++、GDB、Bash、Python 与工程化实践
linux·python·bash·gdb·gcc·g++·lenyiin