1. 程式人生 > >基於C#實現串列埠通訊Demo

基於C#實現串列埠通訊Demo

https://www.cnblogs.com/Zed-H/p/8651882.html

1.基本概念

 

2.前端winForm佈局如下(僅僅為了實現功能,佈局略醜)

 

3.程式碼實現如下

複製程式碼
  1 namespace SerialPortTest
  2 {
  3     public partial class Form1 : Form
  4     {
  5         SerialPort sp1 = new SerialPort();
  6         public Form1()
7 { 8 InitializeComponent(); 9 } 10 11 private void Form1_Load(object sender, EventArgs e) 12 {
          //分別對應前端的波特率、數字位、校驗位、停止位
13 cbBaudRate.SelectedIndex = 0; 14 cbDataBits.SelectedIndex = 0; 15 cbCheck.SelectedIndex = 0
; 16 cbStop.SelectedIndex = 0; 17 18 string[] strCom = SerialPort.GetPortNames(); 19 if (strCom == null) 20 { 21 MessageBox.Show("本機沒有串列埠!", "Error"); 22 return; 23 } 24 //GetPortNames()方法:獲取當前計算機的串列埠名的陣列
25 foreach (string com in System.IO.Ports.SerialPort.GetPortNames()) 26 { 27 cbCom.Items.Add(com); 28 } 29 30 cbCom.SelectedIndex = 0; 31 sp1.BaudRate = 9600; 32 Control.CheckForIllegalCrossThreadCalls = false; 33 sp1.DataReceived += Sp1_DataReceived; 34 35 sp1.DtrEnable = true;//獲取或設定一個值,該值在序列通訊過程中啟用資料終端就緒 (DTR) 訊號。 36 sp1.RtsEnable = true;//獲取或設定一個值,該值指示在序列通訊中是否啟用請求傳送 (RTS) 訊號 37 //設定資料讀取超時為1秒 38 sp1.ReadTimeout = 1000; 39 40 sp1.Close(); 41 } 42 43 private void Sp1_DataReceived(object sender, SerialDataReceivedEventArgs e) 44 { 45 if (sp1.IsOpen) //判斷是否開啟串列埠 46 { 47 //輸出當前時間 48 DateTime dt = DateTime.Now; 49 txtReceived.Text += dt.GetDateTimeFormats('f')[0].ToString() + "\r\n"; 50 try 51 { 52 Byte[] receivedData = new Byte[sp1.BytesToRead]; //建立接收位元組陣列 53 sp1.Read(receivedData, 0, receivedData.Length); //讀取資料 54 AddContent(new UTF8Encoding().GetString(receivedData));//用萬能的UTF8可以傳輸中文不會亂碼 55 } 56 catch (System.Exception ex) 57 { 58 MessageBox.Show(ex.Message, "出錯提示!!!!!"); 59 txtSendStr.Text = ""; 60 } 61 } 62 else 63 { 64 MessageBox.Show("請開啟某個串列埠", "錯誤提示"); 65 } 66 } 67 68 //將接受到的內容顯示出來 69 private void AddContent(string content) 70 { 71 this.BeginInvoke(new MethodInvoker(delegate 72 { 73 txtReceived.AppendText(content); 74 txtReceived.AppendText("\r\n"); 75 //記錄收到的字元個數 76 lblRevCount.Text = (int.Parse(lblRevCount.Text) + content.Length).ToString(); 77 })); 78 } 79 80 private void btnOpen_Click(object sender, EventArgs e) 81 { 82 //serialPort1.IsOpen 83 if (!sp1.IsOpen) 84 { 85 try 86 { 87 //設定串列埠號 88 string serialName = cbCom.SelectedItem.ToString(); 89 sp1.PortName = serialName; 90 91 //設定各“串列埠設定” 92 string strBaudRate = cbBaudRate.Text; 93 string strDateBits = cbDataBits.Text; 94 string strStopBits = cbStop.Text; 95 Int32 iBaudRate = Convert.ToInt32(strBaudRate); 96 Int32 iDateBits = Convert.ToInt32(strDateBits); 97 98 sp1.BaudRate = iBaudRate; //波特率 99 sp1.DataBits = iDateBits; //資料位 100 switch (cbStop.Text) //停止位 101 { 102 case "1": 103 sp1.StopBits = StopBits.One; 104 break; 105 case "1.5": 106 sp1.StopBits = StopBits.OnePointFive; 107 break; 108 case "2": 109 sp1.StopBits = StopBits.Two; 110 break; 111 default: 112 MessageBox.Show("Error:引數不正確!", "Error"); 113 break; 114 } 115 switch (cbCheck.Text) //校驗位 116 { 117 case "": 118 sp1.Parity = Parity.None; 119 break; 120 case "奇校驗": 121 sp1.Parity = Parity.Odd; 122 break; 123 case "偶校驗": 124 sp1.Parity = Parity.Even; 125 break; 126 default: 127 MessageBox.Show("Error:引數不正確!", "Error"); 128 break; 129 } 130 131 if (sp1.IsOpen == true)//如果開啟狀態,則先關閉一下 132 { 133 sp1.Close(); 134 } 135 136 //設定必要控制元件不可用 137 cbCom.Enabled = false; 138 cbBaudRate.Enabled = false; 139 cbDataBits.Enabled = false; 140 cbStop.Enabled = false; 141 cbCheck.Enabled = false; 142 sp1.Open(); //開啟串列埠 143 btnOpen.Text = "關閉串列埠"; 144 } 145 catch (System.Exception ex) 146 { 147 MessageBox.Show("Error:" + ex.Message, "Error"); 148 return; 149 } 150 } 151 else 152 { 153 //恢復控制元件功能 154 //設定必要控制元件不可用 155 cbCom.Enabled = true; 156 cbBaudRate.Enabled = true; 157 cbDataBits.Enabled = true; 158 cbStop.Enabled = true; 159 cbCheck.Enabled = true; 160 sp1.Close(); //關閉串列埠 161 btnOpen.Text = "開啟串列埠"; 162 } 163 } 164 165 private void btnSend_Click(object sender, EventArgs e) 166 { 167 byte[] sendData = null; 168 if (!sp1.IsOpen) //如果沒開啟 169 { 170 MessageBox.Show("請先開啟串列埠!", "Error"); 171 return; 172 } 173 String strSend = txtSendStr.Text; 174 try 175 { 176 sendData = Encoding.UTF8.GetBytes(txtSendStr.Text.Trim()); 177 //sp1.WriteLine(txtSendStr.Text); //寫入資料 178 sp1.Write(sendData, 0, sendData.Length); 179 } 180 catch (Exception ex) 181 { 182 MessageBox.Show("Error:" + ex.Message, "Error"); 183 } 184 185 } 186 187 } 188 }
複製程式碼

 

4.測試執行結果如下

  在自己同一臺電腦上測試,需要先用Configure Virtual Serial Port Driver建立兩個虛擬串列埠,如下

 

  串列埠執行結果如下:

 上述兩窗體通訊時要選擇同一波特率,不然收發資料會失敗

關於C# serialport的一些說明:

SerialPort() :如果未指定,則此建構函式使用預設屬性值。 例如, DataBits 屬性預設值為 8, Parity 屬性預設為 None 列舉值,
StopBits 屬性預設值為 1,預設埠名為 COM1。

public static string[] GetPortNames() :獲取當前計算機的串列埠名的陣列

SerialPort.Read 方法 (Byte[], Int32, Int32) :從 SerialPort 輸入緩衝區讀取一些位元組並將那些位元組寫入位元組陣列中指定的偏移量處

SerialPort.ReadLine 方法 () :一直讀取到輸入緩衝區中的 NewLine 值

SerialPort.Write 方法 (Byte[], Int32, Int32) : 使用緩衝區中的資料將指定數量的位元組寫入串列埠

SerialPort.WriteLine 方法 (String) : 將指定的字串和 NewLine 值寫入輸出緩衝區。