C#編寫一個簡易的序列槽調試助手
序列槽調試助手簡介:
序列槽調試助手是序列槽調試相關工具,有多個版本。如:友善序列槽調試助手,支援9600,19200等常用各種波特率及自定義波特率,可以自動識别序列槽,能設定校驗、資料位和停止位,能以ASCII碼或十六進制接收或發送任何資料或字元,可以任意設定自動發送周期,并能将接收資料儲存成文本檔案,能發送任意大小的文本檔案。
硬體連接配接方面,傳統台式PC機支援标準RS232接口,但是帶有序列槽的筆記本很少見,是以需要USB/232轉換接口,并且安裝相應驅動程式。
主要實作的功能:
- 自動搜尋序列槽,并打開序列槽;
- 支援多序列槽;
- 支援自定義波特率,支援非标準波特率;
- 支援發送曆史記錄;
- 接收資料可以進行十六進制和ASCII切換;
- 接收資料時,光标可定位在指定行或在最後一行;
- 可以以十六進制或ASCII格式,向指定序列槽發送資料;
- 定時發送資料;
- 接收資料可以儲存為檔案,也可打開已儲存資料檔案;
- 序列槽打開過程中,可修改通訊參數,如波特率;
- 自動記錄上次操作參數,如序列槽号、波特率等。
主界面:
主要代碼
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; //傳回字元串臨時變量。
}
}
}
相關項目檔案可在上傳的資源裡找到