Serial库是一个面向对象的跨平台串行通信库。它提供了一个简单而一致的接口,以处理各种串行协议。这篇文章将从以下多个方面详细阐述serial库的特点和使用方法。
一、初始化串行通信
对于串行通信设备,如何初始化才能使用?在使用serial库之前,需要对串行口设置进行初始化。这些设置包括波特率、数据位、停止位、校验位等,如下所示:
#include "serial/serial.h" serial::Serial my_serial("/dev/ttyUSB0", 115200, serial::Timeout::simpleTimeout(1000)); void init_serial() { my_serial.setBaudrate(9600); my_serial.setBytesize(serial::eightbits); my_serial.setParity(serial::parity_none); my_serial.setStopbits(serial::stopbits_one); }
这里创建了一个名为my_serial的串行通信对象,将其绑定到设备/dev/ttyUSB0上,并设置波特率为115200。之后调用my_serial的四个函数,依次设置数据位、校验位和停止位。需要注意的是,在设置完这些参数之后,还需要调用setBaudrate()函数重新设置波特率,以保证波特率设置正确。
二、读写串行数据
串行通信是双向的,用户需要能够读取来自串行设备的数据,同时还需要向其发送数据。为此,serial库提供了以下两个函数:
size_t read(uint8_t *buf, size_t size); size_t write(const uint8_t *data, size_t length);
read()函数从串行口中读取数据,将其存储在缓冲区中,然后返回实际读取的字节数。用户需要提供缓冲区指针和要读取的字节数。write()函数将数据写入串行口,需要提供发送数据的指针和字节数。下面是一个例子:
void serial_write_data() { std::string write_data("Hello, world!"); my_serial.write(write_data); } void serial_read_data() { std::vectorread_data; read_data.resize(10); size_t bytes_read = my_serial.read(read_data.data(), 10); }
这里的serial_write_data()函数将字符串"Hello, world!"写入串行口,而serial_read_data()函数从串行口中读取了10个字节的数据存储在read_data中。
三、控制串行通信流
有时候,当没有足够的数据时,读取操作会被阻塞。在这种情况下,根据用户需求进行流的控制非常重要。serial库提供了以下控制函数,以控制流的状态:
void flushInput(); void flushOutput(); void flush(); void pause(); void resume();
flushInput()函数清除输入缓冲区,flushOutput()清除输出缓冲区,flush()函数清除输入输出缓冲区。pause()和resume()将控制通信流。调用pause()时,串行口将不再读取或写入数据。调用resume()时,流将恢复,并尝试建立新的连接。下面是一个例子:
void serial_control_flow() { my_serial.pause(); // pause the flow my_serial.flushInput(); // clear input buffer my_serial.flushOutput(); // clear output buffer my_serial.resume(); // resume the flow }
四、串行端口信息
串行口的一些信息,如其设备名称、波特率等,对于一些应用程序而言是非常重要的。serial库提供了以下函数来获取这些信息:
std::string getPort() const; uint32_t getBaudrate() const; uint8_t getBytesize() const; uint8_t getParity() const; uint8_t getStopbits() const; bool isOpen() const;
getPort()函数返回串行通信对象使用的设备名称。getBaudrate()返回当前波特率,getBytesize()返回数据位,getParity()返回校验位类型,getStopbits()返回停止位类型,而isOpen()函数则检查端口是否已打开。下面是一个例子:
void serial_port_info() { std::string port_name = my_serial.getPort(); uint32_t baudrate = my_serial.getBaudrate(); uint8_t bytesize = my_serial.getBytesize(); uint8_t parity = my_serial.getParity(); uint8_t stopbits = my_serial.getStopbits(); bool is_open = my_serial.isOpen(); }
五、错误处理
由于串行通信与硬件相关,因此在使用过程中可能会出现错误。serial库提供了以下几种错误处理方式:
enum SerialExceptionType { timeout, port_not_open, already_open, open_failed, configuration_failed, read_failed, write_failed, ioctl_failed, other_error }; class SerialException : public std::exception { public: SerialException() : type_(other_error){} SerialException(const SerialExceptionType& type) : type_(type){} virtual const char *what() const noexcept override { return "serial exception"; } virtual const char *type() const noexcept { switch (type_) { case timeout: return "timed out"; case port_not_open: return "port not open"; case already_open: return "port already open"; case open_failed: return "failed to open port"; case configuration_failed: return "failed to configure port"; case read_failed: return "read failed"; case write_failed: return "write failed"; case ioctl_failed: return "ioctl failed"; case other_error: default: return "other error"; } } SerialExceptionType type() const noexcept { return type_; } private: SerialExceptionType type_; };
SerialException作为serial库的异常类,提供了几种错误类型。例如timeout表示读或写操作因超时而失败,port_not_open表示串行端口未被打开,already_open表示已经打开的端口再次被打开,open_failed表示打开端口失败,configuration_failed表示无法对端口进行正确的配置,而read_failed和write_failed表示读或写操作失败。
六、总结
serial库是一个功能强大且易于使用的库,非常适合处理各种串行通信协议。它提供了一些重要的功能,如初始化通信、读写通信、控制通信流、获取串行端口信息和错误处理等。使用serial库能够让用户轻松地进行串行通信。code示例:
#include "serial/serial.h" serial::Serial my_serial("/dev/ttyUSB0", 115200, serial::Timeout::simpleTimeout(1000)); void init_serial() { my_serial.setBaudrate(9600); my_serial.setBytesize(serial::eightbits); my_serial.setParity(serial::parity_none); my_serial.setStopbits(serial::stopbits_one); } void serial_write_data() { std::string write_data("Hello, world!"); my_serial.write(write_data); } void serial_read_data() { std::vectorread_data; read_data.resize(10); size_t bytes_read = my_serial.read(read_data.data(), 10); } void serial_control_flow() { my_serial.pause(); my_serial.flushInput(); my_serial.flushOutput(); my_serial.resume(); } void serial_port_info() { std::string port_name = my_serial.getPort(); uint32_t baudrate = my_serial.getBaudrate(); uint8_t bytesize = my_serial.getBytesize(); uint8_t parity = my_serial.getParity(); uint8_t stopbits = my_serial.getStopbits(); bool is_open = my_serial.isOpen(); }