在开始以前,首先要说明的是串口通讯所用到的 SerialPort
类并不包含在 System.Device.Gpio
NuGet 包中,而是在 System.IO.Ports
NuGet 包中。之因此在这里介绍串口通讯,是由于在嵌入式中串口通讯是与其余设备进行交互的一种重要方式,并且在某些没有屏幕的设备中充当着程序调试的工具。css
串口是串行接口的简称,这是一个很是大的概念,在嵌入式中串口一般指 UART (Universal Asynchronous Receiver/Transmitter,通用异步收发器)。使用串口进行的通讯叫作串行通讯,与之相对的一个概念是并行通讯。串行通讯是指数据一位一位的按顺序传输,而并行通讯则是多位数据同时传输。如图1所示,DATA BUS
到 UART 1
之间是并行通讯,UART 1
到 UART 2
之间是串行通讯。git
图1:串行通讯与并行通讯github
串口通讯的数据帧格式如图2所示,一般一帧共包括 10 位:1 个起始位,8 个数据位和 1 个中止位。有一些特殊的数据帧在中止位前面包含 1 位的奇偶校验位,还有的中止位有 2 个比特。其中起始位为低电平(0),标志着数据传输的开始;中止位为高电平(1),表示数据帧传输结束;数据位则为实际发送的数据,使用高低电平来表示比特信息,若是发送的内容是文本,那么这段数据为字符的二进制编码(ASCII,UTF-8……)。数据传输的速率咱们使用波特率(Baud Rate)来表示,即每秒钟传送的码元符号的个数[1]。好比数据传输速率为 9600 字符/s,那么这时的波特率为 9600。docker
图2:串口通讯的数据帧c#
设备进行串口通讯时,设备的连线如图3所示,两个设备的信号线,即发送端(TXD)与接收端(RXD)交叉相连,而且须要共地。在 Raspberry Pi 的引脚上共引出了 1 组串口,即 UART 0
,对应 8 和 10 号引脚。异步
图3:串口设备的链接async
串口操做的相关类位于 System.IO.Ports
命名空间下。函数
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(); }
SerialPort sp = new SerialPort(portName: "/dev/ttyUSB0") { BaudRate = 115200, Encoding = Encoding.UTF8, ReadTimeout = 500, WriteTimeout = 500, }
sp.Open();
sp.WriteLine($"Text content."); string content = sp.ReadLine();
sp.Close();
名称 | 数量 |
---|---|
USB 串口 | x1 |
杜邦线 | 若干 |
USB 串口设备只要 Raspberry Pi 支持便可,这里使用的是 FT232RL
。工具
示例地址:https://github.com/ZhangGaoxing/dotnet-core-iot-demo/tree/master/src/SerialCommunicationui
docker build -t serial-sample -f Dockerfile . docker run --rm -it --device /dev/ttyUSB0 --device /dev/ttyS0 serial-sample
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(); } }