以下是使用Boost库进行C++串口通信的示例代码,包含详细的步骤和说明:
#include <iostream>
#include <boost/asio.hpp>
#include <boost/bind/bind.hpp>
using namespace boost::asio;
using namespace boost::system;
class SerialPort {
public:
SerialPort(io_context& io, const std::string& port_name)
: port_(io, port_name), timer_(io) {
// 配置串口参数
port_.set_option(serial_port_base::baud_rate(9600));
port_.set_option(serial_port_base::character_size(8));
port_.set_option(serial_port_base::stop_bits(serial_port_base::stop_bits::one));
port_.set_option(serial_port_base::parity(serial_port_base::parity::none));
port_.set_option(serial_port_base::flow_control(serial_port_base::flow_control::none));
}
void start() {
// 启动异步读取
async_read();
}
void write(const std::string& data) {
async_write(data);
}
private:
void async_read() {
port_.async_read_some(buffer(read_buf_),
boost::bind(&SerialPort::handle_read, this,
boost::placeholders::_1, boost::placeholders::_2));
}
void handle_read(const error_code& ec, size_t bytes_transferred) {
if (!ec) {
// 处理接收到的数据
std::cout << "Received: ";
std::cout.write(read_buf_.data(), bytes_transferred);
std::cout << std::endl;
// 继续异步读取
async_read();
} else {
std::cerr << "Read error: " << ec.message() << std::endl;
close();
}
}
void async_write(const std::string& data) {
boost::asio::async_write(port_, buffer(data),
boost::bind(&SerialPort::handle_write, this,
boost::placeholders::_1, boost::placeholders::_2));
}
void handle_write(const error_code& ec, size_t bytes_transferred) {
if (!ec) {
std::cout << "Sent " << bytes_transferred << " bytes" << std::endl;
} else {
std::cerr << "Write error: " << ec.message() << std::endl;
close();
}
}
void close() {
if (port_.is_open()) {
error_code ec;
port_.close(ec);
if (ec) {
std::cerr << "Close error: " << ec.message() << std::endl;
}
}
}
serial_port port_;
deadline_timer timer_;
std::array<char, 128> read_buf_;
};
int main() {
try {
io_context io;
// 根据系统修改串口设备名(Windows: "COM1",Linux: "/dev/ttyS0")
SerialPort serial(io, "/dev/ttyS0");
serial.start();
// 启动IO服务(阻塞直到所有异步操作完成)
io.run();
} catch (const std::exception& e) {
std::cerr << "Exception: " << e.what() << std::endl;
}
return 0;
}
使用说明
-
安装依赖:
- 需要安装Boost库(至少1.66版本)
- Linux安装命令:
sudo apt-get install libboost-all-dev
- Windows可使用vcpkg或Boost官方安装程序
-
编译命令:
# Linux g++ -std=c++11 serial_example.cpp -o serial -lboost_system -lpthread # Windows(使用MinGW) g++ -std=c++11 serial_example.cpp -o serial.exe -IC:/boost/include -LC:/boost/lib -lboost_system-mgwXXX -lws2_32
-
参数配置:
- 修改串口设备名称(
/dev/ttyS0
或COM1
) - 根据设备要求调整波特率等参数(默认9600, 8N1)
- 修改串口设备名称(
-
功能扩展:
- 添加数据解析逻辑到
handle_read
- 实现同步读写接口
- 添加超时处理机制
- 添加数据解析逻辑到
关键点说明
-
异步操作模型:
- 使用
async_read_some
和async_write
实现非阻塞通信 - IO上下文(
io_context
)负责事件循环调度
- 使用
-
错误处理:
- 通过
error_code
参数检查操作状态 - 发生错误时自动关闭串口
- 通过
-
跨平台支持:
- Windows和Linux使用相同的API接口
- 只需修改设备名称即可移植
-
线程安全:
- 建议使用
strand
包装异步操作(多线程时需要)
- 建议使用
同步通信示例(补充)
如果需要简单同步操作,可以使用以下方法:
// 同步读取(阻塞)
size_t read_bytes = read(port, buffer(read_buf), transfer_all());
// 同步写入(阻塞)
size_t written_bytes = write(port, buffer("AT\r\n"));
建议根据具体需求选择同步或异步模型。异步模型更适合需要同时处理多个I/O操作的场景,而同步模型更简单直接。