1. 程式人生 > >【C#學習筆記】Lesson5-串列埠除錯助手開發

【C#學習筆記】Lesson5-串列埠除錯助手開發

學習有幾天時間了,跟著大神的指導和手冊以及萬能的度娘。下面記錄下串列埠除錯助手的開發,還並不是很完善,但是基本功能還是有的。一下就不一步步記錄開發過程了,貼上程式碼,以及重點和需要注意的地方。

最終程式碼如下:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

using System.IO.Ports;
namespace Lesson5
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
            System.Windows.Forms.Control.CheckForIllegalCrossThreadCalls = false;
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            SearchAndAddSerialToComboBox(serialPort1, comboBox1);
            /*****************非常重要************************/
            serialPort1.DataReceived += new SerialDataReceivedEventHandler(port_DataReceived);//必須手動新增事件處理程式
        }

        //串列埠接收函式封裝
        private void port_DataReceived(object sender, SerialDataReceivedEventArgs e)//串列埠資料接收事件
        {
            if (!checkBox1.Checked)//如果沒有勾選,字元模式
            {
                string str = serialPort1.ReadExisting();//字串方式讀
                textBox1.AppendText(str);//新增內容
            }
            else//接收模式為數值接收
            { 
                byte data;
                data = (byte)serialPort1.ReadByte();//此處需要強制型別轉換,將(int)型別資料轉換為(byte型別資料,不必考慮是否會丟失資料
                string str = Convert.ToString(data, 16).ToUpper();//轉換為大寫十六進位制字串
                textBox1.AppendText("0x" + (str.Length == 1 ? "0" + str : str) + " ");//空位補“0”   
            }
        }

        //掃描串列埠函式封裝
        private void SearchAndAddSerialToComboBox(SerialPort MyPort, ComboBox MyBox)
        {                                                               //將可用埠號新增到ComboBox  
            string Buffer;                                              //快取  
            MyBox.Items.Clear();                                        //清空ComboBox內容  
            for (int i = 1; i < 20; i++)                                //迴圈這裡只掃描1-19  
            {
                try                                                     //核心原理是依靠try和catch完成遍歷  
                {
                    Buffer = "COM" + i.ToString();
                    MyPort.PortName = Buffer;
                    MyPort.Open();                                      //如果失敗,後面的程式碼不會執行  
                                                                        // MyString[count] = Buffer;  
                    MyBox.Items.Add(Buffer);                            //開啟成功,新增至下倆列表  
                    MyPort.Close();                                     //關閉  
                }
                catch//出錯了什麼也不做繼續迴圈  
                {
                }
            }
        }

        //掃描串列埠按鈕
        private void button3_Click(object sender, EventArgs e)
        {
            SearchAndAddSerialToComboBox(serialPort1, comboBox1);
            //設計上根據使用到的串列埠和下拉框決定傳入引數 
        }

        //清空接收按鈕
        private void button5_Click(object sender, EventArgs e)
        {
            textBox1.Text = "";
        }

        //清空傳送按鈕
        private void button4_Click(object sender, EventArgs e)
        {
            textBox2.Text = "";
        }

        //開啟關閉串列埠按鈕
        private void button1_Click(object sender, EventArgs e)
        {
            if (serialPort1.IsOpen)                                     //串列埠開啟就關閉
            {
                try
                {
                    serialPort1.Close();
                }
                catch { }                                               //確保萬無一失
                button1.ForeColor = Color.Black;
                //button1.BackColor = Color.Black;
                button1.Text = "開啟串列埠";
            }
            else
            {
                try
                {
                    serialPort1.PortName = comboBox1.Text;              //埠號
                    serialPort1.BaudRate = Convert.ToInt32(comboBox2.Text, 10);//十進位制資料轉換
                    serialPort1.Open();                                 //開啟埠
                    button1.ForeColor = Color.Red;
                    //button1.BackColor = Color.Red;
                    button1.Text = "關閉串列埠";
                }
                catch
                {
                    MessageBox.Show("串列埠開啟失敗", "錯誤");
                }
            }
        }

        //傳送按鈕
        private void button2_Click(object sender, EventArgs e)
        {
            byte[] Data = new byte[1];//定義一個變數

            //判斷串列埠是否開啟,如果開啟執行下一步操作
            //如果傳送的資料不是空的
            if (serialPort1.IsOpen && textBox2.Text != "")        
            {
                if (!checkBox1.Checked)//如果傳送模式是字元模式
                {
                    try
                    {
                        serialPort1.WriteLine(textBox2.Text);//寫資料
                    }
                    catch (Exception err)
                    {
                        MessageBox.Show("串列埠資料寫入錯誤", "錯誤");//出錯提示
                        serialPort1.Close();
                    }
                }
                else
                {
                    //總長度除以2得到有多少對字元
                    for (int i = 0; i < textBox2.Text.Length / 2; i++)
                    {
                        //每次取兩位字元組成一個16進位制
                        Data[0] = Convert.ToByte(textBox2.Text.Substring(i * 2, 2), 16);
                        serialPort1.Write(Data, 0, 1);//迴圈傳送(如果輸入字元為0A0BB,則只發送0A,0B)
                    }
                    if (textBox2.Text.Length % 2 != 0)//剩下一位單獨處理
                    {
                        Data[0] = Convert.ToByte(textBox2.Text.Substring(textBox2.Text.Length - 1, 1), 16);//單獨傳送B(0B)
                        serialPort1.Write(Data, 0, 1);//傳送
                    }
                }
            }
        }
    }
}

程式碼基本上都有註釋,僅供參考。

最終介面功能除錯如下圖:


介面比較簡單,實現功能如下:

1、串列埠掃描。

2、開啟、關閉串列埠。

3、16進位制及字元型資料的傳送和接收。

4、傳送區域和接受區域清空按鈕。

5、波特率是在textbox中集合中加的幾個常用的波特率,這個新增起來也很簡單。

6、在開啟軟體自行掃描到串列埠後暫時沒辦法讓其直接顯示有效的串列埠號,需要手動選擇。

7、波特率在開啟軟體裡面沒有自動加上一個波特率,這個比較好修改。

不足之處:

1、字元型資料預設是開啟了回車換行,不添加回車換行還需要在程式碼上稍作修改。

2、串列埠掃描功能在開啟軟體的時候會自動執行,不過熱插拔掃描的話還是需要一個按鍵,暫時還沒能力整合到下拉框中。

注意的問題及新知識點:

1、開啟和關閉串列埠有顏色變化,在串列埠關閉的狀態文字顯示黑色的“開啟串列埠”,開啟後顯示紅色的“關閉串列埠”,這是比較使用及人性化的設計。

2、添加了checkbox選擇顯示16進位制或者字元,傳送也是一樣可以選擇傳送字元或者16進位制資料。

3、接收文字框和傳送文字框都有滾動條,這個在文字框的屬性裡面選擇滾動條的垂直模式即可。

4、在開始除錯的時候報了一個錯誤,找這個問題找了很久,最終在度娘上找到答案,同時感謝解決我這個問題的貼子。我這裡再記上一筆,希望能幫到更多的人。


上圖是在除錯之前遇到的一個問題。產生這個錯誤的原因是少了一行程式碼:

 System.Windows.Forms.Control.CheckForIllegalCrossThreadCalls = false;

這個是視窗初始化緊接著需要新增的。新增之後就沒有問題了。程式碼懂得不多,C#是門簡單強大的語言,但是最終的目的還是編寫一個合適的上位機軟體,所以目前就不深究C#本身,先以最快最有效的方式達到目的再說,以後再慢慢深究。

以上是及上一貼後學習到並開發的內容。

By Urien 2018年2月15日 10:55:06