You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

153 lines
3.2 KiB
C++

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <termios.h>
#include <errno.h>
#include "SerialMsgHandler.hpp"
SerialMsgHandler::SerialMsgHandler() {}
SerialMsgHandler::~SerialMsgHandler()
{
ClosePort();
}
// 打开串口
bool SerialMsgHandler::OpenPort(const std::string &port, const std::string &baudrate)
{
std::string tty = "/dev/" + port;
int baund = B9600;
ClosePort();
fd = open(tty.c_str(), O_RDWR | O_NOCTTY | O_NDELAY);
if (fd == -1)
{
perror("打开串口失败");
return false;
}
// 恢复串口为阻塞状态
if (fcntl(fd, F_SETFL, 0) < 0)
{
perror("设置阻塞模式失败");
close(fd);
fd = -1;
return false;
}
// 检查是否是终端设备
if (!isatty(fd))
{
fprintf(stderr, "%s 不是终端设备\n", tty.c_str());
close(fd);
fd = -1;
return false;
}
if (baudrate == "115200")
{
baund = B115200;
}
else if (baudrate == "9600")
{
baund = B9600;
}
else if (baudrate == "19200")
{
baund = B19200;
}
else if (baudrate == "57600")
{
baund = B57600;
}
else
{
baund = B9600;
}
// ========== 新增:保存波特率 ==========
baudrate_ = baund;
return setPortAttributes(baund);
}
// 设置串口参数
bool SerialMsgHandler::setPortAttributes(int baudrate)
{
struct termios options;
// ========== 新增:调试打印配置前的状态 ==========
std::cout << "[DEBUG] setPortAttributes: configuring port with baudrate=" << baudrate << std::endl;
// 获取当前串口设置
if (tcgetattr(fd, &options) != 0)
{
perror("获取串口属性失败");
return false;
}
// 设置波特率
cfsetispeed(&options, baudrate);
cfsetospeed(&options, baudrate);
// 设置数据位8位数据位
options.c_cflag &= ~CSIZE;
options.c_cflag |= CS8;
// 设置校验位:无校验
options.c_cflag &= ~PARENB;
options.c_iflag &= ~(INPCK | INLCR | ICRNL | IGNCR);
// 设置停止位1位停止位
options.c_cflag &= ~CSTOPB;
// 设置流控制:无流控制
options.c_cflag &= ~CRTSCTS;
// 设置原始输入模式
options.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG);
// 设置原始输出模式
options.c_oflag &= ~OPOST;
// 设置最小字符数和等待时间
options.c_cc[VMIN] = 0; // 读取的最小字符数
options.c_cc[VTIME] = 10; // 读取超时时间单位0.1秒)
// 清空输入输出缓冲区
tcflush(fd, TCIOFLUSH);
// 应用设置
if (tcsetattr(fd, TCSANOW, &options) != 0)
{
perror("设置串口属性失败");
return false;
}
return true;
}
// ========== 新增:刷新串口配置 ==========
bool SerialMsgHandler::refreshPort()
{
if (fd == -1) {
std::cout << "[DEBUG] refreshPort: fd is -1, skip" << std::endl;
return false;
}
// ========== 调试打印 ==========
std::cout << "[DEBUG] refreshPort: reconfiguring port, baudrate=" << baudrate_ << std::endl;
return setPortAttributes(baudrate_);
}