Wiki
UART序列埠通訊
約 4 分鐘閱讀
本文由簡體中文內容確定性轉換,並受版本化術語表保護。
1.Linux 序列埠通訊
序列埠通訊是機器人和嵌入式專案中最常見的底層通訊方式之一。
在實際專案中,上位機經常需要通過序列埠和 STM32、ESP32、Arduino、感測器模組、除錯板等裝置進行資料互動。例如:
- 上位機向 STM32 傳送電機速度指令
- STM32 向上位機返回編碼器資料
- 讀取 IMU、GPS、雷射測距模組等感測器資料
- 使用 USB 轉序列埠模組進行除錯
- 在 ROS 2 底盤控制中和下位機通訊
序列埠通訊的特點是簡單、通用、成本低,特別適合上位機和微控制器之間的點對點通訊。
1.1.序列埠通訊是什麼
序列埠通訊通常指 UART 通訊。在 Linux 上,常見的 USB 轉序列埠裝置會被識別為類似下面的裝置檔案:
/dev/ttyUSB0
/dev/ttyUSB1
/dev/ttyACM0
程式只需要開啟對應的裝置檔案,並設定好波特率、資料位、停止位、校驗位等引數,就可以進行資料收發。
常見引數包括:
| 引數 | 說明 |
|---|---|
| 裝置名 | 例如 /dev/ttyUSB0、/dev/ttyACM0 |
| 波特率 | 例如 115200、921600 |
| 資料位 | 常見為 8 位 |
| 停止位 | 常見為 1 位 |
| 校驗位 | 常見為無校驗 |
| 流控 | 一般專案中常關閉硬體流控 |
在機器人專案中,序列埠通常不會只發送普通字串,而是會設計自己的二進位制通訊協議,例如幀頭、長度、命令字、資料區、CRC 校驗等。
1.2.Linux 下常見序列埠庫
Linux 下使用序列埠通訊有多種方案,常見的包括:
| 方案 | 型別 | 特點 | 適合場景 |
|---|---|---|---|
| termios | Linux 原生介面 | 最底層、依賴少、通用性強,但程式碼相對繁瑣 | 想深入理解 Linux 序列埠機制 |
| boost::asio | 通用 C++ 庫 | 支援同步/非同步,程式碼結構較清晰,跨平臺能力較好 | 推薦用於 C++ 工程封裝 |
| libserial | 第三方序列埠庫 | 使用簡單,比 termios 更易上手 | 普通序列埠收發專案 |
| serial_driver | ROS 2 生態封裝 | 更方便接入 ROS 2,但不適合只依賴 ROS 2 以外的專案 | 純 ROS 2 專案或參考實現 |
| pyserial | Python 序列埠庫 | 使用非常簡單,適合快速測試 | Python 除錯指令碼 |
這些庫本質上都是為了完成序列埠的開啟、配置、讀取和寫入,只是封裝層次不同。
1.3.各方案對比
| 方案 | 優點 | 缺點 |
|---|---|---|
| termios | Linux 原生、依賴最少、底層能力強 | 配置繁瑣,初學者容易寫錯 |
| boost::asio | C++ 工程友好,非同步通訊方便,適合封裝 driver | 需要理解 asio 的基本模型 |
| libserial | 簡單易用,上手快 | 靈活性和工程可控性不如自己封裝 |
| serial_driver | 和 ROS 2 生態結合方便 | 離開 ROS 2 後複用性較差 |
| pyserial | 除錯快,適合指令碼 | 不適合作為高效能 C++ 底層驅動主線 |
1.4.本教程建議選擇
本教程建議優先選擇:
boost::asio
原因是:
- 比直接使用
termios更適合 C++ 工程開發 - 可以封裝成普通 C++ driver,方便複用
- 不依賴 ROS 2,OpenCV、Qt、普通 C++ 專案都能使用
- 後續也可以很自然地接入
ros2_control hardware_interface - 比較適合機器人上位機和 STM32 通訊場景
推薦的工程結構是:
上层项目:ROS 2 / OpenCV / Qt / 普通 C++ 程序
↓
自己封装的 SerialDriver 类
↓
boost::asio
↓
/dev/ttyUSB0
↓
STM32 / ESP32 / 传感器
1.5.與 ROS 2 的關係
學習 Linux 序列埠通訊,並不代表不用 ROS 2。
在 ROS 2 專案中,可以將序列埠通訊封裝成一個普通 C++ 類,然後在 ROS 2 節點或 ros2_control hardware_interface 中呼叫它。
例如:
ros2_control controller
↓
hardware_interface
↓
自己封装的 SerialDriver
↓
boost::asio
↓
STM32
這樣做的好處是,序列埠通訊程式碼不會和 ROS 2 強繫結。以後即使寫 OpenCV 專案、Qt 上位機或者普通 C++ 除錯程式,也可以繼續複用同一套序列埠 driver。
1.6.本章學習目標
學習完本章後,應該能夠掌握:
- Linux 下序列埠裝置的基本概念
- 如何檢視和開啟
/dev/ttyUSB0等序列埠裝置 - 序列埠波特率、資料位、停止位、校驗位等基本引數
- 使用 C++ 進行序列埠資料收發
- 設計簡單的上位機與下位機通訊協議
- 將序列埠通訊封裝成可複用的 C++ 類
- 為後續接入 ROS 2、OpenCV、Qt 專案打基礎