張高興的 .NET Core IoT 入門指南:(五)串口通信入門

  • 2019 年 10 月 20 日
  • 筆記

在開始之前,首先要說明的是串口通信所用到的 SerialPort 類並不包含在 System.Device.Gpio NuGet 包中,而是在 System.IO.Ports NuGet 包中。之所以在這裡介紹串口通信,是因為在嵌入式中串口通信是與其他設備進行交互的一種重要方式,而且在某些沒有屏幕的設備中充當著程序調試的工具。

什麼是串口

串口是串行接口的簡稱,這是一個非常大的概念,在嵌入式中串口通常指 UART (Universal Asynchronous Receiver/Transmitter,通用異步收發器)。使用串口進行的通信叫做串行通信,與之相對的一個概念是並行通信。串行通信是指數據一位一位的按順序傳輸,而並行通信則是多位數據同時傳輸。如圖1所示,DATA BUSUART 1 之間是並行通信,UART 1UART 2 之間是串行通信。

圖1:串行通信與並行通信

串口通信的數據幀格式如圖2所示,通常一幀共包括 10 位:1 個起始位,8 個數據位和 1 個停止位。有一些特殊的數據幀在停止位前面包含 1 位的奇偶校驗位,還有的停止位有 2 個比特。其中起始位為低電平(0),標誌着數據傳輸的開始;停止位為高電平(1),表示數據幀傳輸結束;數據位則為實際發送的數據,使用高低電平來表示比特信息,如果發送的內容是文本,那麼這段數據為字符的二進制編碼(ASCII,UTF-8……)。數據傳輸的速率我們使用波特率(Baud Rate)來表示,即每秒鐘傳送的碼元符號的個數[1]。比如數據傳輸速率為 9600 字符/s,那麼這時的波特率為 9600。

圖2:串口通信的數據幀

設備進行串口通信時,設備的連線如圖3所示,兩個設備的信號線,即發送端(TXD)與接收端(RXD)交叉相連,並且需要共地。在 Raspberry Pi 的引腳上共引出了 1 組串口,即 UART 0 ,對應 8 和 10 號引腳。

圖3:串口設備的連接

相關類

串口操作的相關類位於 System.IO.Ports 命名空間下。

SerialPort

public class SerialPort : Component  {      // portName 為串口的名稱,可以使用靜態方法 GetPortNames() 獲取      public SerialPort(string portName);        // 傳輸的波特率      public int BaudRate { get; set; }      // 指定傳輸內容的編碼      public Encoding Encoding { get; set; }      // 新行格式,即設置換行的字符      public string NewLine { get; set; }      // 設置停止位的格式      public StopBits StopBits { get; set; }      // 設置校驗位的格式      public Parity Parity { get; set; }        // 打開串口通信流      public void Open();      // 關閉串口通信流      public void Close();        // 向串口通信流中寫一行字符      public void WriteLine(string text);      // 從串口通信流中讀一行字符      public string ReadLine();      // 讀取緩衝區中的所有可用內容,一般用於清空緩衝區,防止讀取舊的內容      public string ReadExisting();        // 獲取可用的串口名稱      public static string[] GetPortNames();  }

串口通信的步驟

  1. 配置串口通信參數,如波特率,內容編碼,新行格式,超時時間等。
SerialPort sp = new SerialPort(portName: "/dev/ttyUSB0")  {      BaudRate = 115200,      Encoding = Encoding.UTF8,      ReadTimeout = 500,      WriteTimeout = 500,  }
  1. 打開串口
sp.Open();
  1. 讀取和寫入文本
sp.WriteLine($"Text content.");  string content = sp.ReadLine();
  1. 關閉串口
sp.Close();

USB 串口通信實驗

硬件需求

名稱 數量
USB 串口 x1
杜邦線 若干

USB 串口設備只要 Raspberry Pi 支持即可,這裡使用的是 FT232RL

電路

  • GND – GND
  • RX – TX (Pin 8)
  • TX – RX (Pin 10)
  • USB – USB

使用 Docker 運行示例

示例地址:https://github.com/ZhangGaoxing/dotnet-core-iot-demo/tree/master/src/SerialCommunication

docker build -t serial-sample -f Dockerfile .  docker run --rm -it --device /dev/ttyUSB0 --device /dev/ttyS0 serial-sample

代碼

  1. 打開 Visual Studio ,新建一個 .NET Core 控制台應用程序,項目名稱為「SerialCommunication」。
  2. 引入 System.IO.Ports NuGet 包。
  3. Program.cs 中,將主函數代碼替換如下:
static void Main(string[] args)  {      using (SerialPort usb = new SerialPort(portName: "/dev/ttyUSB0"))      {          usb.BaudRate = 115200;          usb.Encoding = Encoding.UTF8;          usb.ReadTimeout = 500;          usb.WriteTimeout = 500;            usb.Open();            using (SerialPort rpi = new SerialPort(portName: "/dev/ttyS0"))          {              rpi.BaudRate = 115200;              rpi.Encoding = Encoding.UTF8;              rpi.ReadTimeout = 500;              rpi.WriteTimeout = 500;                rpi.Open();                for (int i = 0; i < 10; i++)              {                  rpi.WriteLine($"Hello {i}!");                  Console.WriteLine($"USB receive: {usb.ReadLine()}");              }                rpi.Close();          }            usb.Close();      }  }
  1. 發佈、拷貝、更改權限、運行

效果圖


  備註

下一篇文章將談談 Iot.Device.Bindings NuGet 包的使用。