C#開發串口通訊實例及串口基礎

1、串口通訊簡介

       串行接口(串口)是一種能夠將接受來自CPU的並行數據字符轉換爲連續的串行數據流發送出去,同時可將接受的串行數據流轉換爲並行的數據字符供給CPU的器件。通常完成這種功能的電路,咱們稱爲串行接口電路。編程

       串口通訊(Serial Communications)的概念很是簡單,串口按位(bit)發送和接收字節。儘管比按字節(byte)的並行通訊慢,可是串口能夠在使用一根線發送數據的同時用另外一根線接收數據。串口通訊最重要的參數是波特率、數據位、中止位和奇偶校驗。對於兩個進行通訊的端口,這些參數必須匹配。數組

  1. 波特率:這是一個衡量符號傳輸速率的參數。指的是信號被調製之後在單位時間內的變化,即單位時間內載波參數變化的次數,如每秒鐘傳送960個字符,而每一個字符格式包含10位(1個起始位,1箇中止位,8個數據位),這時的波特率爲960Bd,比特率爲10位*960個/秒=9600bps。緩存

  2. 數據位:這是衡量通訊中實際數據位的參數。當計算機發送一個信息包,實際的數據每每不會是8位的,標準的值是六、7和8位。標準的ASCII碼是0~127(7位),擴展的ASCII碼是0~255(8位)。ide

  3. 中止位:用於表示單個包的最後幾位。典型的值爲1,1.5和2位。因爲數據是在傳輸線上定時的,而且每個設備有其本身的時鐘,極可能在通訊中兩臺設備間出現了小小的不一樣步。所以中止位不單單是表示傳輸的結束,而且提供計算機校訂時鐘同步的機會。spa

  4. 校驗位:在串口通訊中一種簡單的檢錯方式。有四種檢錯方式:偶、奇、高和低。固然沒有校驗位也是能夠的。3d

2、C#串口編程類

       從.NET Framework 2.0開始,C#提供了SerialPort類用於實現串口控制。命名空間:System.IO.Ports。其中詳細成員介紹參看MSDN文檔。下面介紹其經常使用的字段、方法和事件。code

  1. 經常使用字段:

名稱 說明
PortName 獲取或設置通訊端口
BaudRate 獲取或設置串行波特率
DataBits 獲取或設置每一個字節的標準數據位長度
Parity 獲取或設置奇偶校驗檢查協議
StopBits 獲取或設置每一個字節的標準中止位數

 

 

 

 

 

 

 

 

2. 經常使用方法:

名稱 說明
Close 關閉端口鏈接,將 IsOpen 屬性設置爲 false,並釋放內部 Stream 對象
GetPortNames 獲取當前計算機的串行端口名稱數組
Open 打開一個新的串行端口鏈接
Read 從 SerialPort 輸入緩衝區中讀取
Write  將數據寫入串行端口輸出緩衝區

 

 

 

 

 

 

 

 

3. 經常使用事件:

名稱 說明
DataReceived 表示將處理 SerialPort 對象的數據接收事件的方法

 

 

 

3、C#開發串口實例

前臺頁面:orm

 後臺代碼:對象

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();//清除發送文本框裏面的內容
        }
    }
}
相關文章
相關標籤/搜索