Laravel  
laravel
文档
数据库
架构
入门
php技术
    
Laravelphp
laravel / php / java / vue / mysql / linux / python / javascript / html / css / c++ / c#

c++ 串口通讯

作者:烟寂断魂   发布日期:2025-04-27   浏览:103

#include <iostream>
#include <string>
#ifdef _WIN32
#include <windows.h>
#else
#include <unistd.h>
#include <fcntl.h>
#include <termios.h>
#endif

class SerialPort {
public:
    SerialPort(const std::string& portName, int baudRate) {
        #ifdef _WIN32
            // Windows平台下的串口初始化代码
            hSerial = CreateFileA(portName.c_str(), GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
            if (hSerial == INVALID_HANDLE_VALUE) {
                std::cerr << "Error opening serial port" << std::endl;
                return;
            }
            DCB dcbSerialParams = { 0 };
            dcbSerialParams.DCBlength = sizeof(dcbSerialParams);
            GetCommState(hSerial, &dcbSerialParams);
            dcbSerialParams.BaudRate = baudRate;
            dcbSerialParams.ByteSize = 8;
            dcbSerialParams.StopBits = ONESTOPBIT;
            dcbSerialParams.Parity = NOPARITY;
            SetCommState(hSerial, &dcbSerialParams);
        #else
            // Linux平台下的串口初始化代码
            fd = open(portName.c_str(), O_RDWR | O_NOCTTY | O_SYNC);
            if (fd < 0) {
                std::cerr << "Error opening serial port" << std::endl;
                return;
            }
            struct termios tty;
            memset(&tty, 0, sizeof(tty));
            if (tcgetattr(fd, &tty) != 0) {
                std::cerr << "Error from tcgetattr" << std::endl;
                return;
            }
            cfsetospeed(&tty, baudRate);
            cfsetispeed(&tty, baudRate);

            tty.c_cflag = (tty.c_cflag & ~CSIZE) | CS8;     // 8-bit chars
            tty.c_iflag &= ~IGNBRK;                         // disable break processing
            tty.c_lflag = 0;                                // no signaling chars, no echo, no canonical processing
            tty.c_oflag = 0;                                // no remapping, no delays
            tty.c_cc[VMIN]  = 0;                            // read doesn't block
            tty.c_cc[VTIME] = 5;                            // 0.5 seconds read timeout

            tty.c_iflag &= ~(IXON | IXOFF | IXANY);         // shut off xon/xoff ctrl
            tty.c_cflag |= (CLOCAL | CREAD);                // ignore modem controls, enable reading
            tty.c_cflag &= ~(PARENB | PARODD);              // shut off parity
            tty.c_cflag |= 0;                               // set parity to none
            tty.c_cflag &= ~CSTOPB;                         // 1 stop bit
            tty.c_cflag &= ~CRTSCTS;                        // no hardware flowcontrol

            if (tcsetattr(fd, TCSANOW, &tty) != 0) {
                std::cerr << "Error from tcsetattr" << std::endl;
                return;
            }
        #endif
    }

    ~SerialPort() {
        #ifdef _WIN32
            if (hSerial != INVALID_HANDLE_VALUE) {
                CloseHandle(hSerial);
            }
        #else
            if (fd >= 0) {
                close(fd);
            }
        #endif
    }

    bool writeData(const std::string& data) {
        #ifdef _WIN32
            DWORD bytesSent;
            WriteFile(hSerial, data.c_str(), data.size(), &bytesSent, NULL);
            return bytesSent == data.size();
        #else
            int bytesSent = write(fd, data.c_str(), data.size());
            return bytesSent == data.size();
        #endif
    }

    std::string readData(int numBytes) {
        #ifdef _WIN32
            DWORD bytesRead;
            char buffer[numBytes];
            ReadFile(hSerial, buffer, numBytes, &bytesRead, NULL);
            return std::string(buffer, bytesRead);
        #else
            char buffer[numBytes];
            int bytesRead = read(fd, buffer, numBytes);
            return std::string(buffer, bytesRead);
        #endif
    }

private:
    #ifdef _WIN32
        HANDLE hSerial;
    #else
        int fd;
    #endif
};

int main() {
    SerialPort serial("/dev/ttyUSB0", B9600);  // 替换为你的串口设备和波特率
    if (!serial.writeData("Hello, World!\n")) {
        std::cerr << "Failed to write to serial port" << std::endl;
        return 1;
    }

    std::string response = serial.readData(100);
    std::cout << "Received: " << response << std::endl;

    return 0;
}

解释说明:

  1. SerialPort:封装了串口通信的初始化、读写操作。

    • 构造函数:根据操作系统(Windows 或 Linux)初始化串口,设置波特率、数据位、停止位等参数。
    • 析构函数:关闭串口。
    • writeData 方法:向串口发送数据。
    • readData 方法:从串口读取指定数量的数据。
  2. main 函数:创建一个 SerialPort 对象,尝试发送一条消息并读取响应。

  3. 跨平台支持

    • 使用预处理指令 #ifdef _WIN32 来区分 Windows 和 Linux 系统,分别使用不同的 API 进行串口通信。
    • Windows 使用 CreateFileA, WriteFile, ReadFile 等 API。
    • Linux 使用 open, write, read, tcsetattr 等系统调用。
  4. 注意

    • 需要根据实际的串口设备名称(如 /dev/ttyUSB0COM3)和波特率进行调整。
    • 该示例代码假设你已经安装了必要的开发库和工具链。

上一篇:mqtt c++

下一篇:c++获取时间戳

大家都在看

c++闭包

c++单引号和双引号的区别

c++ 注释

c++如何判断素数

c++freopen怎么用

c++ 获取系统时间

c++进制转换函数

c++ tcp

c++ gcd函数

c++ cli

Laravel PHP 深圳智简公司。版权所有©2023-2043 LaravelPHP 粤ICP备2021048745号-3

Laravel 中文站