108 lines
2.3 KiB
C++
108 lines
2.3 KiB
C++
|
|
// SerialPort.cpp
|
||
|
|
#include "SerialPort.h"
|
||
|
|
#include <fcntl.h>
|
||
|
|
#include <unistd.h>
|
||
|
|
#include <cerrno>
|
||
|
|
#include <cstring>
|
||
|
|
#include <iostream>
|
||
|
|
|
||
|
|
SerialPort::SerialPort() : fd(-1) {}
|
||
|
|
|
||
|
|
SerialPort::~SerialPort()
|
||
|
|
{
|
||
|
|
closePort();
|
||
|
|
}
|
||
|
|
|
||
|
|
speed_t SerialPort::getBaudrate(int baudrate)
|
||
|
|
{
|
||
|
|
switch (baudrate)
|
||
|
|
{
|
||
|
|
case 115200:
|
||
|
|
return B115200;
|
||
|
|
case 57600:
|
||
|
|
return B57600;
|
||
|
|
case 38400:
|
||
|
|
return B38400;
|
||
|
|
case 19200:
|
||
|
|
return B19200;
|
||
|
|
case 9600:
|
||
|
|
return B9600;
|
||
|
|
case 4800:
|
||
|
|
return B4800;
|
||
|
|
case 2400:
|
||
|
|
return B2400;
|
||
|
|
default:
|
||
|
|
return B115200;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
bool SerialPort::openPort(const std::string &portName, int baudrate)
|
||
|
|
{
|
||
|
|
fd = open(portName.c_str(), O_RDWR | O_NOCTTY | O_NONBLOCK);
|
||
|
|
if (fd < 0)
|
||
|
|
{
|
||
|
|
std::cerr << "打开串口失败: " << strerror(errno) << std::endl;
|
||
|
|
return false;
|
||
|
|
}
|
||
|
|
|
||
|
|
if (tcgetattr(fd, &tty) != 0)
|
||
|
|
{
|
||
|
|
std::cerr << "tcgetattr 失败: " << strerror(errno) << std::endl;
|
||
|
|
close(fd);
|
||
|
|
fd = -1;
|
||
|
|
return false;
|
||
|
|
}
|
||
|
|
|
||
|
|
cfsetospeed(&tty, getBaudrate(baudrate));
|
||
|
|
cfsetispeed(&tty, getBaudrate(baudrate));
|
||
|
|
|
||
|
|
tty.c_cflag = (tty.c_cflag & ~CSIZE) | CS8;
|
||
|
|
tty.c_cflag |= (CLOCAL | CREAD);
|
||
|
|
tty.c_cflag &= ~(PARENB | PARODD);
|
||
|
|
tty.c_cflag &= ~CSTOPB;
|
||
|
|
tty.c_cflag &= ~CRTSCTS;
|
||
|
|
|
||
|
|
tty.c_iflag &= ~(IXON | IXOFF | IXANY);
|
||
|
|
tty.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG);
|
||
|
|
tty.c_oflag &= ~OPOST;
|
||
|
|
|
||
|
|
tty.c_cc[VMIN] = 1;
|
||
|
|
tty.c_cc[VTIME] = 0;
|
||
|
|
|
||
|
|
if (tcsetattr(fd, TCSANOW, &tty) != 0)
|
||
|
|
{
|
||
|
|
std::cerr << "tcsetattr 失败: " << strerror(errno) << std::endl;
|
||
|
|
close(fd);
|
||
|
|
fd = -1;
|
||
|
|
return false;
|
||
|
|
}
|
||
|
|
|
||
|
|
return true;
|
||
|
|
}
|
||
|
|
|
||
|
|
void SerialPort::closePort()
|
||
|
|
{
|
||
|
|
if (fd >= 0)
|
||
|
|
{
|
||
|
|
close(fd);
|
||
|
|
fd = -1;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
bool SerialPort::writeData(const uint8_t *data, size_t size)
|
||
|
|
{
|
||
|
|
if (fd < 0)
|
||
|
|
{
|
||
|
|
std::cerr << "串口未打开" << std::endl;
|
||
|
|
return false;
|
||
|
|
}
|
||
|
|
|
||
|
|
ssize_t written = write(fd, data, size);
|
||
|
|
if (written < 0)
|
||
|
|
{
|
||
|
|
std::cerr << "写串口失败: " << strerror(errno) << std::endl;
|
||
|
|
return false;
|
||
|
|
}
|
||
|
|
return written == (ssize_t)size;
|
||
|
|
}
|