|
|
#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
|
|
|
{
|
|
|
baund = B9600;
|
|
|
}
|
|
|
|
|
|
return setPortAttributes(baund);
|
|
|
}
|
|
|
|
|
|
// 设置串口参数
|
|
|
bool SerialMsgHandler::setPortAttributes(int baudrate)
|
|
|
{
|
|
|
struct termios options;
|
|
|
|
|
|
// 获取当前串口设置
|
|
|
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;
|
|
|
}
|