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::vector read_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::vector read_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(); }
原創文章,作者:小藍,如若轉載,請註明出處:https://www.506064.com/zh-hant/n/242591.html