一、串口通信簡介
串行介面(串口)是一種可以將接受來自CPU的并行資料字符轉換為連續的串行資料流發送出去,同時可將接受的串行資料流轉換為并行的資料字符供給CPU的器件,一般完成這種功能的電路,我們稱為串行介面電路,
串口通信(Serial Communications)的概念非常簡單,串口按位(bit)發送和接收位元組,盡管比按位元組(byte)的并行通信慢,但是串口可以在使用一根線發送資料的同時用另一根線接收資料,串口通信最重要的引數是波特率、資料位、停止位和奇偶校驗,對于兩個進行通信的埠,這些引數必須匹配,
1. 波特率:這是一個衡量符號傳輸速率的引數,指的是信號被調制以后在單位時間內的變化,即單位時間內載波引數變化的次數,如每秒鐘傳送960個字符,而每個字符格式包含10位(1個起始位,1個停止位,8個資料位),這時的波特率為960Bd,位元率為10位*960個/秒=9600bps,
2. 資料位:這是衡量通信中實際資料位的引數,當計算機發送一個資訊包,實際的資料往往不會是8位的,標準的值是6、7和8位,標準的ASCII碼是0~127(7位),擴展的ASCII碼是0~255(8位),
3. 停止位:用于表示單個包的最后幾位,典型的值為1,1.5和2位,由于資料是在傳輸線上定時的,并且每一個設備有其自己的時鐘,很可能在通信中兩臺設備間出現了小小的不同步,因此停止位不僅僅是表示傳輸的結束,并且提供計算機校正時鐘同步的機會,
4. 校驗位:在串口通信中一種簡單的檢錯方式,有四種檢錯方式:偶、奇、高和低,當然沒有校驗位也是可以的,
二、C#串口編程類
從.NET Framework 2.0開始,C#提供了SerialPort類用于實作串口控制,命名空間:System.IO.Ports,其中詳細成員介紹參看MSDN檔案,下面介紹其常用的欄位、方法和事件,
1. 常用欄位:
| 名稱 | 說明 |
| PortName | 獲取或設定通信埠 |
| BaudRate | 獲取或設定串行波特率 |
| DataBits | 獲取或設定每個位元組的標準資料位長度 |
| Parity | 獲取或設定奇偶校驗檢查協議 |
| StopBits | 獲取或設定每個位元組的標準停止位數 |
2. 常用方法:
| 名稱 | 說明 |
| Close | 關閉埠連接,將 IsOpen 屬性設定為 false,并釋放內部 Stream 物件 |
| GetPortNames | 獲取當前計算機的串行埠名稱陣列 |
| Open | 打開一個新的串行埠連接 |
| Read | 從 SerialPort 輸入緩沖區中讀取 |
| Write | 將資料寫入串行埠輸出緩沖區 |
3. 常用事件:
| 名稱 | 說明 |
| DataReceived | 表示將處理 SerialPort 物件的資料接收事件的方法 |
三、C#開發串口實體
前臺頁面:

后臺代碼:
using System; using System.IO.Ports; using System.Text; using System.Windows.Forms; namespace SerialPort { public partial class SerialPort : Form { String serialPortName; public SerialPort() { InitializeComponent(); } private void Form1_Load(object sender, EventArgs e) { string[] ports = System.IO.Ports.SerialPort.GetPortNames();//獲取電腦上可用串口號 comboBox1.Items.AddRange(ports);//給comboBox1添加資料 comboBox1.SelectedIndex = comboBox1.Items.Count > 0 ? 0 : -1;//如果里面有資料,顯示第0個 comboBox2.Text = "115200";/*默認波特率:115200*/ comboBox3.Text = "1";/*默認停止位:1*/ comboBox4.Text = "8";/*默認資料位:8*/ comboBox5.Text = "無";/*默認奇偶校驗位:無*/ } private void button1_Click(object sender, EventArgs e) { if (button1.Text == "打開串口"){//如果按鈕顯示的是打開 try{//防止意外錯誤 serialPort1.PortName = comboBox1.Text;//獲取comboBox1要打開的串口號 serialPortName = comboBox1.Text; serialPort1.BaudRate = int.Parse(comboBox2.Text);//獲取comboBox2選擇的波特率 serialPort1.DataBits = int.Parse(comboBox4.Text);//設定資料位 /*設定停止位*/ if (comboBox3.Text == "1") { serialPort1.StopBits = StopBits.One; } else if (comboBox3.Text == "1.5") { serialPort1.StopBits = StopBits.OnePointFive; } else if (comboBox3.Text == "2") { serialPort1.StopBits = StopBits.Two; } /*設定奇偶校驗*/ if (comboBox5.Text == "無") { serialPort1.Parity = Parity.None; } else if (comboBox5.Text == "奇校驗") { serialPort1.Parity = Parity.Odd; } else if (comboBox5.Text == "偶校驗") { serialPort1.Parity = Parity.Even; } serialPort1.Open();//打開串口 button1.Text = "關閉串口";//按鈕顯示關閉串口 } catch (Exception err) { MessageBox.Show("打開失敗"+ err.ToString(), "提示!");//對話框顯示打開失敗 } } else{//要關閉串口 try{//防止意外錯誤 serialPort1.Close();//關閉串口 } catch (Exception){} button1.Text = "打開串口";//按鈕顯示打開 } } protected override void WndProc(ref Message m) { if (m.Msg == 0x0219){//設備改變 if (m.WParam.ToInt32() == 0x8004){//usb串口拔出 string[] ports = System.IO.Ports.SerialPort.GetPortNames();//重新獲取串口 comboBox1.Items.Clear();//清除comboBox里面的資料 comboBox1.Items.AddRange(ports);//給comboBox1添加資料 if (button1.Text == "關閉串口"){//用戶打開過串口 if (!serialPort1.IsOpen){//用戶打開的串口被關閉:說明熱插拔是用戶打開的串口 button1.Text = "打開串口"; serialPort1.Dispose();//釋放掉原先的串口資源 comboBox1.SelectedIndex = comboBox1.Items.Count > 0 ? 0 : -1;//顯示獲取的第一個串口號 } else{ comboBox1.Text = serialPortName;//顯示用戶打開的那個串口號 } } else{//用戶沒有打開過串口 comboBox1.SelectedIndex = comboBox1.Items.Count > 0 ? 0 : -1;//顯示獲取的第一個串口號 } } else if (m.WParam.ToInt32() == 0x8000){//usb串口連接上 string[] ports = System.IO.Ports.SerialPort.GetPortNames();//重新獲取串口 comboBox1.Items.Clear(); comboBox1.Items.AddRange(ports); if (button1.Text == "關閉串口"){//用戶打開過一個串口 comboBox1.Text = serialPortName;//顯示用戶打開的那個串口號 } else{ comboBox1.SelectedIndex = comboBox1.Items.Count > 0 ? 0 : -1;//顯示獲取的第一個串口號 } } } base.WndProc(ref m); } private void serialPort1_DataReceived(object sender, SerialDataReceivedEventArgs e) { int len = serialPort1.BytesToRead;//獲取可以讀取的位元組數 byte[] buff = new byte[len];//創建快取資料陣列 serialPort1.Read(buff, 0, len);//把資料讀取到buff陣列 Invoke((new Action(() =>{//C# 3.0以后代替委托的新方法 textBox1.AppendText(Encoding.Default.GetString(buff));//對話框追加顯示資料 }))); } private void button2_Click(object sender, EventArgs e) { textBox1.Clear();//清除接收對話框顯示的資料 } private void button3_Click(object sender, EventArgs e) { String Str = textBox2.Text.ToString();//獲取發送文本框里面的資料 try { if (Str.Length > 0) { serialPort1.Write(Str);//串口發送資料 } } catch (Exception){ } } private void button4_Click(object sender, EventArgs e) { textBox2.Clear();//清除發送文本框里面的內容 } } }
轉載請註明出處,本文鏈接:https://www.uj5u.com/net/68268.html
標籤:C#
上一篇:C#Entity Framework創建mysql資料庫中報錯: System.ArgumentException:“不支持關鍵字: “port”
