1、串口簡介編程
串行接口(串口)一般指COM接口,是採用串行通訊方式的擴展接口。串口按位(bit)發送和接收字節。儘管比按字節(byte)的並行通訊慢,可是串口能夠在使用一根線發送數據的同時用另外一根線接收數據。特別適用於遠距離通訊。數組
1、查看串口:右鍵 個人電腦-管理-設備管理器-端口,選擇一個端口,雙擊查看屬性。微信
二、 串口屬性:從上圖中能夠看到串口屬性,串口通訊最重要的屬性參數是波特率、數據位、中止位和奇偶校驗。對於兩個進行通訊的端口,這些參數必須匹配。工具
(1)波特率:這是一個衡量符號傳輸速率的參數。指的是信號被調製之後在單位時間內的變化,即單位時間內載波參數變化的次數,如每秒鐘傳送960個字符,而每一個字符格式包含10位(1個起始位,1箇中止位,8個數據位),這時的波特率爲960Bd,比特率爲10位*960個/秒=9600bps。學習
(2)數據位:這是衡量通訊中實際數據位的參數。當計算機發送一個信息包,實際的數據每每不會是8位的,標準的值是六、7和8位。標準的ASCII碼是0~127(7位),擴展的ASCII碼是0~255(8位)。測試
(3)中止位:用於表示單個包的最後幾位。典型的值爲1,1.5和2位。因爲數據是在傳輸線上定時的,而且每個設備有其本身的時鐘,極可能在通訊中兩臺設備間出現了小小的不一樣步。所以中止位不只僅是表示傳輸的結束,而且提供計算機校訂時鐘同步的機會。ui
(4)校驗位:在串口通訊中一種簡單的檢錯方式。有四種檢錯方式:偶、奇、高和低。固然沒有校驗位也是能夠的。編碼
三、串口通訊原理:spa
串行接口在嵌入式系統中是一種重要的數據通訊接口,其本質功能是做爲CPU和串行設備間的編碼轉換器。在發送數據時,數據從CPU經串行端口,字節數據轉換爲串行的位;在接收數據時,串行的位轉換爲字節數據。設計
四、經常使用的協議:
RS-232: 標準串口,最經常使用的一種串行通信接口採起不平衡傳輸方式,即所謂單端通信, 是爲點對點通信而設計的。
RS-422: 支持點對多的雙向通訊。採用單獨的發送和接收通道,所以沒必要控制數據方向,各裝置之間任何須須的信號交換都可以按軟件方式(XON/XOFF握手)或硬件方式(一對單獨的雙絞線)實現。
RS-485: 從RS-422基礎上發展而來的, RS-485能夠採用二線與四線方式,二線制可實現真正的多點雙向通訊,而採用四線鏈接時,與RS-422同樣只能實現點對多的通訊,但它比RS-422有改進,不管四線仍是二線鏈接方式總線上可多接到32個設備。
串口的接口標準規範9針串口:
針腳功能:
一、數據載波檢測(DCD)
二、串口接收數據(RXD)
三、串口發出數據(TXD)
四、數據終端就緒(DTR)
五、信號地線(GND)
六、數據發送就緒(DSR)
七、發送數據請求(RTS)
八、清除發送(CTS)
九、鈴聲指示(RI)
2、使用C#和Unity進行串口編程
在對串口進行編程時候,咱們要向串口發送指令,而後咱們解析串口返回的指令。從.NET Framework 2.0開始,C#提供了SerialPort類用於實現串口控制。命名空間:System.IO.Ports。詳細信息能夠參看(MSDN技術文檔)
一、 經常使用的字段:
PortName:獲取或設置通訊端口
BaudRate:獲取或設置串行波特率
DataBits:獲取或設置每一個字節的標準數據位長度
Parity:獲取或設置奇偶效驗檢查協議
StopBits:獲取或設置每一個字節的標準中止位數
二、 經常使用方法:
Close:關閉端口鏈接,將IsOpen屬性設置false,並釋放內部Stream對象
GetPortNames:獲取當前計算機的串行端口名稱數組
Open:打開一個新的串行端口鏈接
Read:從SerialPort輸入緩衝區中讀取
Write:將數據寫入串行端口輸出緩衝區
三、經常使用事件:
DataReceived:表示將處理SerialPort對象的數據接收事件的方法
DisPosed:經過調用釋放組件時發生Dispose方法(繼承自Component)
四、SerialPort 控件使用流程
流程是設置通訊端口號及波特率、數據位、中止位和校驗位,再打開端口鏈接、發送數據、接收數據,最後關閉端口鏈接步驟。
3、編程遇到的問題
一、沒有將Unity3D的API平臺切換成.NET2.0,這時Unity編寫SerialPort類會報錯。
解決方法:將Unity3D的API平臺切換成.NET2.0,切換方法: 「Edit–>project Setting–>Player–>Other Setting –>Api Compatibility level」。在這裏將「.NET2.0 Subset」切換爲「.NET2.0」
二、Unity的目標平臺沒有切換爲Windows平臺,會提示該命名空間不支持SystemIO,提示你切換工具。
解決方法:把目標平臺切換爲Windows平臺,不然是其餘平臺會報錯誤。
三、串口發送的信息不能正常解析
解決方法:把串口發送的消息使用字節流進行轉換。(字符流轉換)
四、串口接收信息的缺失問題
(1)接收字符串(string):port.ReadLine()
數據接收可能錯誤,數據丟失,數據接收不到
(2)接收字節數組(byte[]):port.Read()
接收數據斷層,會分兩次接收完整數據
(3)接收單個字節(byte):port.ReadByte()
將接收到的數據進行組合
1 using UnityEngine; 2 using System.Collections; 3 using System.IO.Ports; 4 using System; 5 using System.Collections.Generic; 6 using System.Threading; 7 using System.Text; 8 9 public class PortControl : MonoBehaviour 10 { 11 #region 定義串口屬性 12 public GUIText gui; 13 //public GUIText Test; 14 //定義基本信息 15 public string portName = "COM3";//串口名 16 public int baudRate = 9600;//波特率 17 public Parity parity = Parity.None;//效驗位 18 public int dataBits = 8;//數據位 19 public StopBits stopBits = StopBits.One;//中止位 20 SerialPort sp = null; 21 Thread dataReceiveThread; 22 //發送的消息 23 string message = ""; 24 public List<byte> listReceive = new List<byte>(); 25 char[] strchar = new char[100];//接收的字符信息轉換爲字符數組信息 26 string str; 27 #endregion 28 void Start() 29 { 30 OpenPort(); 31 dataReceiveThread = new Thread(new ThreadStart(DataReceiveFunction)); 32 dataReceiveThread.Start(); 33 } 34 void Update() 35 { 36 37 } 38 39 #region 建立串口,並打開串口 40 public void OpenPort() 41 { 42 //建立串口 43 sp = new SerialPort(portName, baudRate, parity, dataBits, stopBits); 44 sp.ReadTimeout = 400; 45 try 46 { 47 sp.Open(); 48 } 49 catch (Exception ex) 50 { 51 Debug.Log(ex.Message); 52 } 53 } 54 #endregion 55 56 57 58 #region 程序退出時關閉串口 59 void OnApplicationQuit() 60 { 61 ClosePort(); 62 } 63 public void ClosePort() 64 { 65 try 66 { 67 sp.Close(); 68 dataReceiveThread.Abort(); 69 } 70 catch (Exception ex) 71 { 72 Debug.Log(ex.Message); 73 } 74 } 75 #endregion 76 77 78 /// <summary> 79 /// 打印接收的信息 80 /// </summary> 81 void PrintData() 82 { 83 for (int i = 0; i < listReceive.Count; i++) 84 { 85 strchar[i] = (char)(listReceive[i]); 86 str = new string(strchar); 87 } 88 Debug.Log(str); 89 } 90 91 #region 接收數據 92 void DataReceiveFunction() 93 { 94 #region 按單個字節發送處理信息,不能接收中文 95 //while (sp != null && sp.IsOpen) 96 //{ 97 // Thread.Sleep(1); 98 // try 99 // { 100 // byte addr = Convert.ToByte(sp.ReadByte()); 101 // sp.DiscardInBuffer(); 102 // listReceive.Add(addr); 103 // PrintData(); 104 // } 105 // catch 106 // { 107 // //listReceive.Clear(); 108 // } 109 //} 110 #endregion 111 112 113 #region 按字節數組發送處理信息,信息缺失 114 byte[] buffer = new byte[1024]; 115 int bytes = 0; 116 while (true) 117 { 118 if (sp != null && sp.IsOpen) 119 { 120 try 121 { 122 bytes = sp.Read(buffer, 0, buffer.Length);//接收字節 123 if (bytes == 0) 124 { 125 continue; 126 } 127 else 128 { 129 string strbytes = Encoding.Default.GetString(buffer); 130 Debug.Log(strbytes); 131 } 132 } 133 catch (Exception ex) 134 { 135 if (ex.GetType() != typeof(ThreadAbortException)) 136 { 137 } 138 } 139 } 140 Thread.Sleep(10); 141 } 142 #endregion 143 } 144 #endregion 145 146 147 148 #region 發送數據 149 public void WriteData(string dataStr) 150 { 151 if (sp.IsOpen) 152 { 153 sp.Write(dataStr); 154 } 155 } 156 void OnGUI() 157 { 158 message = GUILayout.TextField(message); 159 if (GUILayout.Button("Send Input")) 160 { 161 WriteData(message); 162 } 163 string test = "AA BB 01 12345 01AB 0@ab 發送";//測試字符串 164 if (GUILayout.Button("Send Test")) 165 { 166 WriteData(test); 167 } 168 } 169 #endregion 170 }
最後爲我微信公衆號引個流,歡迎你們關注個人微信公衆號,你們一塊兒學習一塊兒進步