天天看點

C#序列槽調試助手C#編寫一個簡易的序列槽調試助手

C#編寫一個簡易的序列槽調試助手

序列槽調試助手簡介:

序列槽調試助手是序列槽調試相關工具,有多個版本。如:友善序列槽調試助手,支援9600,19200等常用各種波特率及自定義波特率,可以自動識别序列槽,能設定校驗、資料位和停止位,能以ASCII碼或十六進制接收或發送任何資料或字元,可以任意設定自動發送周期,并能将接收資料儲存成文本檔案,能發送任意大小的文本檔案。

硬體連接配接方面,傳統台式PC機支援标準RS232接口,但是帶有序列槽的筆記本很少見,是以需要USB/232轉換接口,并且安裝相應驅動程式。

主要實作的功能:

  1. 自動搜尋序列槽,并打開序列槽;
  2. 支援多序列槽;
  3. 支援自定義波特率,支援非标準波特率;
  4. 支援發送曆史記錄;
  5. 接收資料可以進行十六進制和ASCII切換;
  6. 接收資料時,光标可定位在指定行或在最後一行;
  7. 可以以十六進制或ASCII格式,向指定序列槽發送資料;
  8. 定時發送資料;
  9. 接收資料可以儲存為檔案,也可打開已儲存資料檔案;
  10. 序列槽打開過程中,可修改通訊參數,如波特率;
  11. 自動記錄上次操作參數,如序列槽号、波特率等。

主界面:

C#序列槽調試助手C#編寫一個簡易的序列槽調試助手

主要代碼

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 _01_SerialPort
{
    public partial class Form1 : Form
    {
        public delegate void showReceiveDelegate(string text); //當采用響應模式,應申明一個委托,實作不同線程的控件實驗

        SerialPort com = new SerialPort("COM2", 9600, Parity.None, 8, StopBits.One);//初始化構造函數
        public Form1()
        {
            InitializeComponent();
        }
        /// <summary>
        /// 窗體加載
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void Form1_Load(object sender, EventArgs e)
        {
          
            cmbPort.SelectedIndex = 0;            
            cmbBaudRate.SelectedIndex = 0;          
            cmbDataBits.SelectedIndex = 0;           
            cmbStopBits.SelectedIndex = 0;
            cmbParity.SelectedIndex = 0;           
        }
        /// <summary>
        /// 序列槽打開與關閉
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnOpen_Click(object sender, EventArgs e)
        {
            if (btnOpen.Text == "打開序列槽")
            {
                try
                {
                    if (!com.IsOpen)
                    {
                        com.PortName = cmbPort.Text;
                        com.BaudRate = int.Parse(cmbBaudRate.Text);
                        com.DataBits = int.Parse(cmbDataBits.Text);
                        switch (cmbStopBits.SelectedIndex)                        {
                            case 0:
                                com.StopBits = StopBits.One; break;
                            case 1:
                                com.StopBits = StopBits.Two; break;
                            case 2:
                                com.StopBits = StopBits.OnePointFive; break;
                            case 3:                             
                                com.StopBits = StopBits.None; break;
                        }
                        switch (cmbParity.SelectedIndex)
                        {
                            case 0: com.Parity = Parity.None; break;
                            case 1: com.Parity = Parity.Odd; break;
                            case 2: com.Parity = Parity.Even; break;
                        }

                        com.Open();//打開序列槽
                    }
                    btnOpen.Text = "關閉序列槽";
                    txtStatus.Text = "序列槽已打開!";
                    btnSend.Enabled = true;
                    if (rbAck.Checked)
                        btnReceive.Enabled = true; //應答模式,接收按鈕有效
                }
                catch
                { txtStatus.Text = "序列槽打開錯誤或序列槽不存在!"; }
            }
            else //關閉序列槽

                try
                {
                    if (com.IsOpen)
                       com.Close(); //關閉序列槽
                    btnOpen.Text = "打開序列槽";
                    txtStatus.Text = "序列槽已關閉!";
                    btnSend.Enabled = false ;
                    if (rbAck.Checked)
                        btnReceive.Enabled = false; //應答模式,接收按鈕有效
                }
                catch
                { txtStatus.Text = "序列槽關閉錯誤或序列槽不存在!"; }
        }

        /// <summary>
        /// 序列槽發送資料
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnSend_Click(object sender, EventArgs e)
        {
            try
             {
                 byte[] data = null;
                if(chkSendHex.Checked)
                    data = getBytesFromString(txtSend.Text);
                else
                    data = Encoding.Default.GetBytes(txtSend.Text);
                com.Write(data, 0, data.Length);  
            }
            catch (Exception err)
            { txtStatus.Text = err.ToString(); }
        }

        /// <summary>
        /// 序列槽接收資料,應答模式時
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnReceive_Click(object sender, EventArgs e)
        {
            try
             {
                 //應答模式
                int count = com.BytesToRead;
                byte[] readBuffer = new byte[count];
                com.Read(readBuffer, 0, count);
                if (chkRecHex.Checked)
                   txtReceive.Text = getStringFromBytes(readBuffer);  //轉十六進制
                else
                   txtReceive.Text = Encoding.Default.GetString(readBuffer);  //字母、數字、漢字轉換為字元串 
               
            }
            catch (Exception err)
            { txtStatus.Text = err.ToString(); }
        }

        /// <summary>
        /// 資料接收模式變化時,設定序列槽的資料接收偵聽事件
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void rbResponse_CheckedChanged(object sender, EventArgs e)
        {
            try
            {  btnReceive.Enabled = rbAck.Checked;
               if(rbResponse.Checked)
                  com.DataReceived += new SerialDataReceivedEventHandler(com_DataReceived);  //加載接收事件
               else
                com.DataReceived -= new SerialDataReceivedEventHandler(com_DataReceived);  //移除接收事件
            }
            catch (Exception err)
            { txtStatus.Text = err.ToString(); }

        }

        /// <summary>
        /// 響應模式時,序列槽接收資料事件
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void com_DataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e)
        {  try
           {
               int count = com.BytesToRead;
               byte[] readBuffer = new byte[count];
               com.Read(readBuffer, 0, count);
               string strReceive="";
               if(chkRecHex.Checked)
                  strReceive = getStringFromBytes(readBuffer);  //轉十六進制
               else
                 strReceive = Encoding.Default.GetString(readBuffer);  //字母、數字、漢字轉換為字元串          
               this.Invoke(new showReceiveDelegate(doShowReceive), strReceive);

             }
           catch (Exception err)
             { txtStatus.Text = err.ToString(); }

        }

        /// <summary>
        /// //異步線程處理接受的字元,顯示在接收的文本框中
        /// </summary>
        /// <param name="str"></param>
        public void doShowReceive(string str)
        {
            txtReceive.Text += str;
        }

        /// <summary>
        /// 以十六進制資料發送轉換時,顯示轉換對應資料
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void chkSendHex_CheckedChanged(object sender, EventArgs e)
        { try 
          {
              if (chkSendHex.Checked)
                  txtSend.Text = getStringFromBytes( Encoding.Default.GetBytes(txtSend.Text));
            else
                txtSend.Text =Encoding.Default.GetString(getBytesFromString(txtSend.Text));
          }
          catch
            { txtStatus.Text = "資料轉換出錯,請輸入正确的資料格式"; }
        }
        /// <summary>
        /// 以十六進制資料顯示接收資料時,顯示對應資料
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void chkRecHex_CheckedChanged(object sender, EventArgs e)
        {
           try 
           {  if (chkRecHex.Checked)
                txtReceive.Text = getStringFromBytes(Encoding.Default.GetBytes(txtReceive.Text));
             else
                txtReceive.Text = Encoding.Default.GetString(getBytesFromString(txtReceive.Text));
             }
           catch
             { txtStatus.Text ="資料轉換出錯,請輸入正确的資料格式"; }
        }

        /// <summary>
        /// 把十六進制格式的字元串轉換成位元組數組。
        /// </summary>
        /// <param name="pString">要轉換的十六進制格式的字元串</param>
        /// <returns>傳回位元組數組。</returns>
        public static byte[] getBytesFromString(string pString)
        {
            string[] str = pString.Split(' ');     //把十六進制格式的字元串按空格轉換為字元串數組。
            byte[] bytes = new byte[str.Length];     //定義位元組數組并初始化,長度為字元串數組的長度。
            for (int i = 0; i < str.Length; i++)     //周遊字元串數組,把每個字元串轉換成位元組類型指派給每個位元組變量。
                bytes[i] = Convert.ToByte(Convert.ToInt32(str[i], 16));
            return bytes;     //傳回位元組數組。
        }

        /// <summary>
        /// 把位元組數組轉換為十六進制格式的字元串。
        /// </summary>
        /// <param name="pByte">要轉換的位元組數組。</param>
        /// <returns>傳回十六進制格式的字元串。</returns>
        public static string getStringFromBytes(byte[] pByte)
        {
            string str = "";     //定義字元串類型臨時變量。
            //周遊位元組數組,把每個位元組轉換成十六進制字元串,不足兩位前面添“0”,以空格分隔累加到字元串變量裡。
            for (int i = 0; i < pByte.Length; i++)
                str += (pByte[i].ToString("X").PadLeft(2, '0') + " ");
            str = str.TrimEnd(' ');     //去掉字元串末尾的空格。
            return str;     //傳回字元串臨時變量。
        }
    }   
}

           

相關項目檔案可在上傳的資源裡找到