Linux c/c++ 串口编程
·
封装了一下Linux下的串口操作
serial.h:
#ifndef _SERIAL_H_
#define _SERIAL_H_
#include <cstddef>
#include <termios.h>
class Serial
{
public:
Serial();
int openPort(const char *path);
int set(speed_t speed);
int send(const void *buf, size_t size, int sec, int msec, bool clBuf);
int recv(void *buf, size_t size, int sec, int msec);
int closePort();
private:
int fd;
};
#endif // _SERIAL_H_
serial.cpp:
#include "serial.h"
#include <iostream>
#include <fcntl.h>
#include <sys/select.h>
#include <unistd.h>
Serial::Serial()
{
fd = -1;
}
int Serial::openPort(const char *path)
{
fd = open(path, O_RDWR);
if (fd == -1)
{
return -1;
}
return 0;
}
int Serial::set(speed_t speed)
{
struct termios options;
if (fd == -1)
{
std::cout << __LINE__ << " serial fd error" << std::endl;
return -1;
}
// 获取当前串口设置
tcgetattr(fd, &options);
// 设置串口工作在本地模式
options.c_cflag |= CLOCAL | CREAD;
cfmakeraw(&options);
// 设置波特率
if (cfsetispeed(&options, speed) < 0 || cfsetospeed(&options, speed) < 0)
{
perror("set speed fail");
return -1;
}
// 8位数据位
options.c_cflag &= ~CSIZE; // 用数据位掩码清空数据位设置
options.c_cflag |= CS8;
// 无奇偶校验
options.c_cflag &= ~PARENB;
// 一个停止位
options.c_cflag &= ~CSTOPB;
// 设置最小等待时间和最少字符数量
options.c_cc[VTIME] = 0;
options.c_cc[VMIN] = 1;
// 清空输入和输出缓冲区
tcflush(fd, TCIOFLUSH);
// 配置生效
if (tcsetattr(fd, TCSANOW, &options) < 0)
{
perror("tcsetattr fail");
return -1;
}
return 0;
}
int Serial::send(const void *buf, size_t size, int sec, int msec, bool clBuf)
{
int ret = -1;
uint8_t tempBuf[1024];
fd_set write_set;
struct timeval tv;
if (fd == -1)
{
std::cout << __LINE__ << " serial fd error" << std::endl;
return -1;
}
// clBuf为true时清空接收缓冲区中的数据,确保在发送数据之前不会有未读取的数据残留
if (clBuf)
{
tcflush(fd, TCIFLUSH);
}
FD_ZERO(&write_set);
FD_SET(fd, &write_set);
tv.tv_sec = sec;
tv.tv_usec = msec * 1000;
ret = select(fd + 1, 0, &write_set, 0, &tv);
switch (ret)
{
case 0:
break;
case -1:
break;
default:
if (FD_ISSET(fd, &write_set))
{
ret = write(fd, buf, size);
}
break;
}
return ret;
}
int Serial::recv(void *buf, size_t size, int sec, int msec)
{
int ret = -1;
fd_set read_set;
struct timeval tv;
if (fd == -1)
{
std::cout << __LINE__ << " serial fd error" << std::endl;
return -1;
}
FD_ZERO(&read_set);
FD_SET(fd, &read_set);
tv.tv_sec = sec;
tv.tv_usec = msec * 1000;
ret = select(fd + 1, &read_set, 0, 0, &tv);
switch (ret)
{
case 0:
break;
case -1:
break;
default:
if (FD_ISSET(fd, &read_set))
{
ret = read(fd, buf, size);
}
break;
}
return ret;
}
int Serial::closePort()
{
int ret;
ret = close(fd);
fd = -1;
return ret;
}
更多推荐
所有评论(0)