c#的串口通訊簡單實例

---本人是一名小白,最近在做學校有關通信的項目。在寫這份代碼之前,查看了許多參考代碼。如果我有說的不對的地方,還請大家指出來。

工具:串口助手、串口調試助手、編譯器(我用的vs2017)//完整代碼和調試助手 在文末有鏈接

一、效果圖

首先給大家放一張效果圖。

二、步驟

(1)首先,肯定就是先將各個部件拖入form裏,然後佈局了。

在這裏請注意:

  • 對於剛剛接觸c#的小白來說,記得發送的文本框和單選按鈕與接受的文本框和單選按鈕。是兩個不一樣的panel。
  • 波特率:因爲常用的波特率是以下幾個,所以我直接設置了下拉框。
  • 校驗位:設置的是 無、奇校驗、偶校驗。
  • 停止位設置的是:1、1.5、2
  • 數據位是:7、8
  • 串口號:串口號就任意了,主要看你需要多少。我就設置了com1~4

在選擇完參數之後,點擊檢查串口,如沒問題,則會顯示,串口檢查成功

這時,點擊打開串口,會提示打開串口成功。

讓我們再看看串口助手

打開串口調試助手,將參數調成一致之後。在form裏發送一段16進制。調試助手將接受到

最後用調試助手,發送一段16進制數。form將接受到信息。

(2)代碼及其主要函數。

 CheckPort():檢查串口是否可用。裏面的主要方法是GetPortNames(獲取當前計算機的串行端口名稱數組)

 

  private void CheckPort()//檢查串口是否可用
        {
            ckCheckBox.Items.Clear();//清除控件中的當前值
            bool havePort = false;
            string[] a = SerialPort.GetPortNames();
            if (a != null)
            {
                
                for (int i = 0; i < a.Length; i++)
                {
                    bool use = false;
                    try
                    {
                        SerialPort t = new SerialPort(a[i]);
                        sp.Open();
                        sp.Close();
                        use = true;
                    }
                    catch
                    {
                    }
                    if (use)
                    {
                        ckCheckBox.Items.Add(a[i]);
                        havePort = true;
                    }
                }
            }
            if (havePort)
            {
                ckCheckBox.SelectedIndex = 0;//??
            }
            else
            {
                MessageBox.Show("無可用串口...", "錯誤");
            }

        }

setPort()://設置串口

通過下拉框獲取此串口的PortName(串口號)、BaudRate(波特率)、Parity(校驗位)、StopBits(停止位)

DataReceived()//接受數據

通過異步委託一個線程,讀出緩衝區串口通信的字節,然後將其寫入此前定義的SerialPort中。最後寫入text中

 ASCIIToHex()//字符轉16進制

HexToASCII()//十六進制轉字符;

 

-----------------------------------------------------------------------

話不多說,直接上源代碼

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.IO.Ports;
using System.Threading;//線程申明

namespace ck3
{
    public partial class Form1 : Form
    {
        private void CheckPort()//檢查串口是否可用
        {
            ckCheckBox.Items.Clear();//清除控件中的當前值
            bool havePort = false;
            string[] a = SerialPort.GetPortNames();
            if (a != null)
            {
                
                for (int i = 0; i < a.Length; i++)
                {
                    bool use = false;
                    try
                    {
                        SerialPort t = new SerialPort(a[i]);
                        sp.Open();
                        sp.Close();
                        use = true;
                    }
                    catch
                    {
                    }
                    if (use)
                    {
                        ckCheckBox.Items.Add(a[i]);
                        havePort = true;
                    }
                }
            }
            if (havePort)
            {
                ckCheckBox.SelectedIndex = 0;//??
            }
            else
            {
                MessageBox.Show("無可用串口...", "錯誤");
            }

        }
        private void SetPort()//設置串口
        {
            try
            {
                sp.PortName = ckCheckBox.Text.Trim();//串口名給了串口類
                sp.BaudRate = Convert.ToInt32(SendBox.Text.Trim());//Trim除去前後空格,講文本轉換爲32位字符給予串口類
                if (JywCheckBox.Text.Trim() == "奇校驗")
                {
                    sp.Parity = Parity.Odd;//將奇校驗位給了sp的協議
                }
                else if (JywCheckBox.Text.Trim() == "偶校驗")
                {
                    sp.Parity = Parity.Even;
                }
                else
                {
                    sp.Parity = Parity.None;
                }
                if (StopCheckBox.Text.Trim() == "1.5")
                {
                    sp.StopBits = StopBits.OnePointFive;//設置停止位有幾位
                }
                else if (StopCheckBox.Text.Trim() == "2")
                {
                    sp.StopBits = StopBits.Two;
                }
                else
                {
                    sp.StopBits = StopBits.One;
                }
                sp.DataBits = Convert.ToInt16(DataBox.Text.ToString().Trim());//數據位
                sp.Encoding = Encoding.UTF8;//串口通信的編碼格式
                sp.Open();
            }
            catch { }

        }
        private string HexToASCII(string str)
        {
            try
            {
                string[] mystr1 = str.Trim().Split(' ');
                byte[] t = new byte[mystr1.Length];
                for (int i = 0; i < t.Length; i++)
                {
                    t[i] = Convert.ToByte(mystr1[i], 16);
                }
                return Encoding.UTF8.GetString(t);

            }
            catch (Exception ex)
            {
                rbtReceicedAscii.Select();
                MessageBox.Show("轉換失敗!" + ex.Message, "錯誤提示");
                return str;

            }
        }
        private string ASCIIToHex(string my2)
        {
            try
            {
                byte[] a = Encoding.UTF8.GetBytes(my2.Trim());
                string mystr1 = "";
                for (int i = 0; i < a.Length; i++)
                {
                    mystr1 += a[i].ToString("X2") + " ";
                }
                return mystr1;
            }
            catch (Exception ex)
            {
                rbtReceicedAscii.Select();
                MessageBox.Show("轉換失敗!" + ex.Message, "錯誤提示");
                return my2;
            }


        }
       
      

        private void Form1_Load(object sender, EventArgs e)
        {
            statusText.Text = "";//狀態條初始化
            //設置窗口大小
            this.MaximizeBox = false;//隱藏最大化按鈕
            this.MaximumSize = this.Size;//固定窗口尺寸最大爲當前尺寸
            this.MinimumSize = this.Size;//固定窗口尺寸最小爲當前尺寸
            BtlCheckBox.SelectedIndex = 5;
          //  JywCheckBox.Items.Clear();
            JywCheckBox.SelectedIndex = 1;
            StopCheckBox.SelectedIndex = 1;
           // DataBox.Items.Clear();
            DataBox.SelectedIndex = 1;
            statusText.Text = "";
            rbtSendAscii.Select();//默認選擇ASCII字符顯示
            rbtReceicedAscii.Select();//默認選擇ASCII字符顯示

        }

        private void btnChecked_Click(object sender, EventArgs e)
        {
            statusText.Text = "檢測串口開始!";
            CheckPort();
            statusText.Text = "串口檢測完成!";
        }
        private void sp_DataReceived(object sender, SerialDataReceivedEventArgs e)
        {
            Thread.Sleep(100);//等待

            this.Invoke((EventHandler)(delegate //異步委託一個線程
            {
                try
                {
                    byte[] a = new byte[sp.BytesToRead];//讀出緩衝區串口通信的字節
                    sp.Read(a, 0, a.Length);//寫入sp
                    string my2 = Encoding.UTF8.GetString(a);
                    string b = "";
                    if (rbtSendAscii.Checked)
                    {
                        b = ASCIIToHex(my2);
                    }
                    else
                    {
                        b = my2;
                    }
                    RecevieBox.Text += b + "\r\n";
                    statusText.Text = "接收成功!";
                }
                catch
                {
                    statusText.Text = "接收失敗!";
                }
            }));
        }
        public Form1()
        {
            InitializeComponent();
        }
    
   
        //發送按鈕
        private void button1_Click_1(object sender, EventArgs e)
        {
            try
            {
                string mystr1 = SendBox.Text;
                if (SixtyRe.Checked)
                {
                    mystr1 = HexToASCII(SendBox.Text);
                }
                byte[] a = Encoding.UTF8.GetBytes(mystr1);
                string mystr2 = Encoding.UTF8.GetString(a);
                sp.Write(mystr2);//將數據寫入串行端口輸出緩衝區
                // tbxReceivedData.Text += tbxSendData.Text + "\r\n";
                statusText.Text = "發送成功!";
            }
            catch
            {
                statusText.Text = "發送失敗";
            }
        }

        private void button1_Click_2(object sender, EventArgs e)
        {
            RecevieBox.Text = " ";
            SendBox.Text = " ";
        }

       

        private void BtnOpen_Click(object sender, EventArgs e)
        {
           
                if (BtnOpen.Text == "打開串口")
                {
                    SetPort();
                    if (sp.IsOpen)
                    {
                        statusText.Text = "串口" + ckCheckBox.Text + "已打開!";
                    }
                    else
                    {
                        try
                        {
                            sp.Open();
                            btnChecked.Enabled = false;
                            ckCheckBox.Enabled = false;
                            BtlCheckBox.Enabled = false;
                            JywCheckBox.Enabled = false;
                            StopCheckBox.Enabled = false;
                            DataBox.Enabled = false;
                            BtnOpen.Text = "關閉串口";
                            statusText.Text = "串口" + ckCheckBox.Text + "打開成功!";
                        }
                        catch (Exception ex)
                        {
                            MessageBox.Show("串口" + ckCheckBox.Text + "打開失敗,失敗原因:" + ex.Message, "錯誤提示");
                            statusText.Text = "串口" + ckCheckBox.Text + "打開失敗,失敗原因:" + ex.Message;
                        }
                    }
                }
                else //關閉串口
                {
                    if (sp.IsOpen) //判斷串口是否打開
                    {
                        try
                        {
                            sp.Close(); //關閉串口
                                        //啓用設置控件
                        btnChecked.Enabled = true;
                        ckCheckBox.Enabled = true;
                        BtlCheckBox.Enabled = true;
                        JywCheckBox.Enabled = true;
                        StopCheckBox.Enabled = true;
                        DataBox.Enabled = true;
                        BtnOpen.Text = "打開串口";
                        statusText.Text = "串口" + ckCheckBox.Text + "關閉成功!";
                        }
                        catch (Exception ex)
                        {
                            MessageBox.Show("串口" + ckCheckBox.Text + "關閉失敗,錯誤提示:" + ex.Message, "錯誤提示");
                        statusText.Text = "串口" + ckCheckBox.Text + "關閉失敗,錯誤提示:" + ex.Message;
                        }
                    }
                    else
                    {
                    btnChecked.Enabled = true;
                    ckCheckBox.Enabled = true;
                    BtlCheckBox.Enabled = true;
                    JywCheckBox.Enabled = true;
                    StopCheckBox.Enabled = true;
                    DataBox.Enabled = true;
                    BtnOpen.Text = "打開串口";
                    statusText.Text = "串口未打開,無法關閉!";
                        MessageBox.Show("串口未打開,無法關閉!", "錯誤提示");
                    }
                

            }

        }

       
        private void SixtySend_CheckedChanged(object sender, EventArgs e)
        {
            if (SixtyRe.Checked)
            {
                SendBox.Text = ASCIIToHex(SendBox.Text.ToString());
            }
        }

       
    }
}

 

最後附上 我的代碼資源。如果鏈接打不開請大家去我的主頁查看

完整代碼:https://download.csdn.net/download/qq_41406816/10776168

串口調試助手:https://download.csdn.net/download/qq_41406816/10776285

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章