C#串口调试助手
2020年春节,因新冠病毒疫情,难得的空闲时间,自学了一下C#。之前一直在做单片机,所以就用C#写了个串口调试助手来练习一下。
先看一下效果图:
SerialAssistant.exe
链接:https://pan.baidu.com/s/1_Lti0i0nlYbSBYJ9Fe4AwQ
提取码:msvg
下面附上主要代码:
窗体加载事件
private void frmMainForm_Load(object sender, EventArgs e)
{
btnSend.Enabled = false;
this.MinimumSize = this.Size;
//搜索计算机串口号
cmbPort.Items.AddRange(SerialPort.GetPortNames());
if (cmbPort.Items.Count > 0)
{
cmbPort.SelectedIndex = 0;
}
//波特率
cmbBaudRate.Items.Add("300");
cmbBaudRate.Items.Add("600");
cmbBaudRate.Items.Add("1200");
cmbBaudRate.Items.Add("2400");
cmbBaudRate.Items.Add("4800");
cmbBaudRate.Items.Add("9600");
cmbBaudRate.Items.Add("19200");
cmbBaudRate.Items.Add("38400");
cmbBaudRate.Items.Add("57600");
cmbBaudRate.Items.Add("115200");
cmbBaudRate.SelectedIndex = 5;
//数据位
cmbDataBits.Items.Add("5");
cmbDataBits.Items.Add("6");
cmbDataBits.Items.Add("7");
cmbDataBits.Items.Add("8");
cmbDataBits.SelectedIndex = 3;
//停止位
cmbStopBit.Items.Add("1");
cmbStopBit.Items.Add("1.5");
cmbStopBit.Items.Add("2");
cmbStopBit.SelectedIndex = 0;
//校验位
cmbParity.Items.Add("None");
cmbParity.Items.Add("Even");
cmbParity.Items.Add("Odd");
cmbParity.SelectedIndex = 0;
lblMark.Text = ""; //显示串口状态Mark
chkDTR.Enabled = false;
chkDSR.Enabled = false;
chkRTS.Enabled = false;
chkCTS.Enabled = false;
timer2.Interval = 1; //下位机响应时间计时,时间间隔1ms
timer3.Interval = 100; //DSR/CTS线状态检测时间
//创建ProgramLogs.txt文本文件,记录发送过的数据
FileStream F = new FileStream("ProgramLogs.txt", FileMode.OpenOrCreate, FileAccess.ReadWrite, FileShare.Read);
F.Close();
StreamReader sR = new StreamReader("ProgramLogs.txt"); //实例化StreamReader,读取ProgramLogs.txt
string nextLine;
while ((nextLine = sR.ReadLine()) != null)
{
cmbDataLogs.Items.Add(nextLine); //Add读取的数据
cmbDataLogs.SelectedIndex = 0;
}
sR.Close();
txtSendData.Text = "";
CheckForIllegalCrossThreadCalls = false;
ComDevice.DataReceived += new SerialDataReceivedEventHandler(Com_DataReceived); //绑定串口接收事件
}
打开串口
/// <summary>
/// 打开串口
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void btnOpen_Click(object sender, EventArgs e)
{
if (cmbPort.Items.Count <= 0) //判断计算机是否存在串口
{
MessageBox.Show("计算机没有发现串口,请检查!", "提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
return;
}
if (ComDevice.IsOpen == false) //如果串口未打开
{
//根据选择设置串口参数
ComDevice.PortName = cmbPort.SelectedItem.ToString();
ComDevice.BaudRate = Convert.ToInt32(cmbBaudRate.SelectedItem.ToString());
ComDevice.Parity = (Parity)Convert.ToInt32(cmbParity.SelectedIndex.ToString());
ComDevice.DataBits = Convert.ToInt32(cmbDataBits.SelectedItem.ToString());
ComDevice.StopBits = (StopBits)Convert.ToInt32(cmbStopBit.SelectedItem.ToString());
try
{
ComDevice.Open(); //打开串口
btnSend.Enabled = true;
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
lblMark.Text = "ERR";
lblMark.ForeColor = Color.Red;
return;
}
btnOpen.Text = "关闭串口";
lblMark.Text = "OK";
lblMark.ForeColor = Color.Green;
//在状态栏显示串口状态
toolStripStatusLabel1.Text = cmbPort.SelectedItem.ToString() + " OPENED , " + cmbBaudRate.SelectedItem.ToString() + " , " + cmbDataBits.SelectedItem.ToString() + " , " + (Parity)Convert.ToInt32(cmbParity.SelectedIndex.ToString()) + " , " + cmbStopBit.SelectedItem.ToString();
toolStripStatusLabel1.ForeColor = Color.Green;
chkDTR.Enabled = true;
chkDSR.Enabled = true;
chkRTS.Enabled = true;
chkCTS.Enabled = true;
}
else
{
try
{
ComDevice.Close(); //关闭串口
btnSend.Enabled = false;
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
btnOpen.Text = "打开串口";
lblMark.Text = "";
//在状态栏显示串口状态
toolStripStatusLabel1.Text = cmbPort.SelectedItem.ToString() + " CLOSED";
toolStripStatusLabel1.ForeColor = Color.Red;
chkDTR.Enabled = false;
chkDSR.Enabled = false;
chkRTS.Enabled = false;
chkCTS.Enabled = false;
}
cmbPort.Enabled = !ComDevice.IsOpen;
cmbBaudRate.Enabled = !ComDevice.IsOpen;
cmbParity.Enabled = !ComDevice.IsOpen;
cmbDataBits.Enabled = !ComDevice.IsOpen;
cmbStopBit.Enabled = !ComDevice.IsOpen;
}
发送button事件
/// <summary>
/// 发送button事件
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void btnSend_Click(object sender, EventArgs e)
{
byte[] sendData = null;
if (radSendHEX.Checked)
{
sendData = strToHexByte(txtSendData.Text.Trim());
}
else if (radSendASCII.Checked)
{
sendData = Encoding.ASCII.GetBytes(txtSendData.Text.Trim());
}
else if (radSendUTF.Checked)
{
sendData = Encoding.UTF8.GetBytes(txtSendData.Text.Trim());
}
else if (radSendUNI.Checked)
{
sendData = Encoding.Unicode.GetBytes(txtSendData.Text.Trim());
}
else
{
sendData = Encoding.ASCII.GetBytes(txtSendData.Text.Trim());
}
if (SendData(sendData))
{
timer2.Enabled = true; //开启定时器2,计时下位机响应时间
timer2.Start();
toolStripStatusLabel6.Text = (int.Parse(toolStripStatusLabel6.Text) + sendData.Length).ToString(); //状态栏提示发送的字节数
}
else
{
//MessageBox.Show("数据发送失败", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
if (cmbDataLogs.Items.Count != 0)
{
bool f = false;
foreach (string data in cmbDataLogs.Items) //如果发送的数据没有记录,记录
{
if (data == txtSendData.Text)
{
f = true;
}
}
if (!f)
{
cmbDataLogs.Items.Add(txtSendData.Text);
StreamWriter sW = new StreamWriter(Application.StartupPath + "\\ProgramLogs.txt", true);
sW.WriteLine(txtSendData.Text);
sW.Close();
}
}
else
{
cmbDataLogs.Items.Add(txtSendData.Text);
cmbDataLogs.SelectedIndex = 0;
StreamWriter sW = new StreamWriter(Application.StartupPath + "\\ProgramLogs.txt", true);
sW.WriteLine(txtSendData.Text);
sW.Close();
}
}
串口发送数据
/// <summary>
/// 发送数据
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
public bool SendData(byte[] data)
{
if (ComDevice.IsOpen)
{
try
{
if (radSendHEX.Checked)
{
ComDevice.Write(data, 0, data.Length); //HEX发送数据
}
else
{
ComDevice.Write(txtSendData.Text); //string发送数据
}
return true;
}
catch (Exception e)
{
MessageBox.Show(e.Message, "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
else
{
MessageBox.Show("串口未打开", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
return false;
}
/// <summary>
/// 字符串转换16进制字节数组
/// </summary>
/// <param name="hexString"></param>
/// <returns></returns>
private byte[] strToHexByte(string hexString)
{
hexString = hexString.Replace(" ", "");
if ((hexString.Length % 2) != 0)
hexString += " ";
byte[] returnBytes = new byte[hexString.Length / 2];
for (int i = 0; i < returnBytes.Length; i++)
returnBytes[i] = Convert.ToByte(hexString.Substring(i * 2, 2).Replace(" ", ""), 16);
return returnBytes;
}
串口接收数据
/// <summary>
/// 接收数据
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void Com_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
toolStripStatusLabel9.Text = Convert.ToString(responseTime); //状态提示下位机响应时间
timer2.Stop();
timer2.Enabled = false;
responseTime = 0;
if (ComDevice.IsOpen)
{
byte[] ReDatas = new byte[ComDevice.BytesToRead];
ComDevice.Read(ReDatas, 0, ReDatas.Length); //读取数据
AddData(ReDatas); //输出数据
}
else
{
MessageBox.Show("请先打开串口");
}
}
将接收的数据显示到接收区
/// <summary>
/// 添加数据
/// </summary>
/// <param name="data"></param>
public void AddData(byte[] data)
{
if (radReceiveHEX.Checked)
{
StringBuilder sb = new StringBuilder(); //实例化StringBuilder
for (int i = 0; i < data.Length; i++)
{
sb.AppendFormat("{0:x2}" + " ", data[i]); //十六进制显示,不足补0
}
AddContent(sb.ToString().ToUpper());
}
else if (radReceiveASCII.Checked)
{
AddContent(new ASCIIEncoding().GetString(data));
}
else if (radReceiveUTF.Checked)
{
AddContent(new UTF8Encoding().GetString(data));
}
else if (radReceiveUNI.Checked)
{
AddContent(new UnicodeEncoding().GetString(data));
}
else
{
AddContent(new ASCIIEncoding().GetString(data));
}
toolStripStatusLabel3.Text = (int.Parse(toolStripStatusLabel3.Text) + data.Length).ToString(); //状态栏提示接收的字节数
}
/// <summary>
/// 输入到显示区域
/// </summary>
/// <param name="content"></param>
private void AddContent(string content)
{
if (!pauseDisplay)
{
BeginInvoke(new MethodInvoker(delegate
{
if (chkAutoLine.Checked && txtReceivedData.Text.Length > 0)
{
txtReceivedData.AppendText("\r\n");
}
txtReceivedData.AppendText(content);
})); //这里是使用委托刷新控件的显示,初学的话这里可能有些难以理解
}
}
初学C#,分享一下我的第一个C#程序,有不足之处还望各位大侠不吝指教!
changsons: 连到系统上的设备没有发挥作用 是什么原因?同样的设备用友善串口调试工具可以