目录
一、基于SunnyUI的C#简易串口调试软件界面
上篇文章已经学会怎么在线导入SunnyUI并用于Winform程序中,本文利用前面所学的知识编写一个简易串口调试程序,UI界面如下:
该界面简洁美观,只有基本的可编辑发送和接收区域。
二、源代码
源代码如下,如果需要压缩包文件直接点击绑定的资源进行下载。
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 Sunny.UI;
using System.IO.Ports;
using System.Threading;
using System.Reflection.Emit;
using static System.Windows.Forms.VisualStyles.VisualStyleElement;
using static System.Net.Mime.MediaTypeNames;
namespace SerialPortCommunications
{
public partial class Form1 : UIForm
{
public Form1()
{
InitializeComponent();
uiCheckBoxStringSend.Checked = true;
uiCheckBoxStringDisplay.Checked = true;
}
SerialPort serialPort = new SerialPort();
bool autoSendFlag = false;
private void uiComboBoxCOMports_DropDown(object sender, EventArgs e) //扫描并选择本机串口
{
uiComboBoxCOMports.Items.Clear();
string[] Ports = SerialPort.GetPortNames(); //获取当前计算机的所有COM口
foreach (string Port in Ports)
{
if (Ports.Contains(Port))
{
uiComboBoxCOMports.Items.Add(Port); //把所有COM口添加到组合框控件选项中
}
}
uiComboBoxCOMports.Text = Ports[Ports.Count() - 1]; //选中最新获取的COM口
}
private void SerialSet() //串口配置设置
{
serialPort.PortName = uiComboBoxCOMports.Text; //选择串口号
serialPort.BaudRate = uiComboBoxbaudRate.Text.ToInt(); //设置波特率
switch (uiComboBoxParityBits.Text) //设置校验位
{
case "无None": serialPort.Parity = Parity.None; break;
case "偶Even": serialPort.Parity = Parity.Even; break;
case "奇Odd": serialPort.Parity = Parity.Odd; break;
case "标志Mark": serialPort.Parity = Parity.Mark; break;
case "空格Space": serialPort.Parity = Parity.Space; break;
default: serialPort.Parity = Parity.None; break;
}
serialPort.DataBits = uiComboBoxDataBits.Text.ToInt(); //设置数据位
switch (uiComboBoxStopBits.Text) //设置停止位
{
case "1": serialPort.StopBits = StopBits.One; break;
case "2": serialPort.StopBits = StopBits.Two; break;
default: serialPort.StopBits = StopBits.One; break;
}
}
private async void uiButtonOpenOrCloseSerialPort_Click(object sender, EventArgs e) //打开或关闭串口
{
try
{
if (serialPort.IsOpen) //关闭串口
{
serialPort.Close();
uiLedBulb1.On = false;
uiButtonOpenOrCloseSerialPort.FillColor = Color.Lime;
uiButtonOpenOrCloseSerialPort.Text = "打开串口";
}
else //打开串口
{
SerialSet();
serialPort.Open();
uiLedBulb1.On = true;
uiButtonOpenOrCloseSerialPort.FillColor = Color.Red;
uiButtonOpenOrCloseSerialPort.Text = "关闭串口";
}
}
catch (Exception ex)
{
UIMessageBox.Show("串口打开失败,该串口可能已被其他程序占用!!!");
}
}
private void uiButtonManulSend_Click(object sender, EventArgs e) //手动发送
{
string stringData = uiRichTextBoxSendArea.Text;
SendData(stringData);
}
private void SendData(string stringData) //发送数据方法
{
if (serialPort.IsOpen)
{
if (uiCheckBoxStringSend.Checked) //以字符串格式发送
{
if (stringData.Length != 0)
{
serialPort.Write(stringData);
}
else
{
UIMessageBox.Show("请输入要发送的数据!!!");
}
}
else //以十六进制格式发送
{
// 要发送的十六进制字节数组
if (stringData.Length != 0)
{
byte[] sendData = null;
string send = stringData.Trim();
//按照指定编码将string编程字节数组
byte[] b = Encoding.GetEncoding("GBK").GetBytes(send);
string result = string.Empty;
//逐字节变为16进制字符
for (int i = 0; i < b.Length; i++)
{
result += Convert.ToString(b[i], 16).ToUpper() + " ";
}
sendData = Encoding.GetEncoding("GBK").GetBytes(result);
serialPort.Write(sendData, 0, sendData.Length);
}
else
{
UIMessageBox.Show("请输入要发送的数据!!!");
}
}
}
else
{
UIMessageBox.Show("串口未打开,请先打开串口!!!");
}
}
private void uiCheckBoxHexSend_Click(object sender, EventArgs e) //选择16进制发送
{
uiCheckBoxStringSend.Checked = false;
uiCheckBoxHexSend.Checked = true;
return;
}
private void uiCheckBoxStringSend_Click(object sender, EventArgs e) //选择字符串发送
{
uiCheckBoxHexSend.Checked = false;
uiCheckBoxStringSend.Checked = true;
return;
}
private void uiButtonClearSendArea_Click(object sender, EventArgs e) //清空发送区
{
uiRichTextBoxSendArea.Text = string.Empty;
}
private void uiButtonUpDateTime_Click(object sender, EventArgs e) //更新时间
{
uiRichTextBoxSendArea.Text = DateTime.Now.ToString();
}
private void uiButtonClearRecieveArea_Click(object sender, EventArgs e) //清空接收区
{
uiRichTextBoxRecieveArea.Text = string.Empty;
}
private async void uiButtonAutoSend_Click(object sender, EventArgs e) //自动发送数据
{
string stringData = uiRichTextBoxSendArea.Text;
int AutoSendCycleMs = 0;
if (uiTextBoxAutoSendCycleMs.Text != string.Empty)
{
AutoSendCycleMs = uiTextBoxAutoSendCycleMs.Text.ToInt();
}
else
{
AutoSendCycleMs = 0;
}
autoSendFlag = !autoSendFlag;
await Task.Run(() => //更新UI界面
{
if (serialPort.IsOpen)
{
while (true)
{
SendData(stringData);
uibuttonTextUpdate(uiButtonAutoSend, "停止发送");
Task.Delay(AutoSendCycleMs).Wait();
if (!autoSendFlag)
{
uibuttonTextUpdate(uiButtonAutoSend, "自动发送");
break;
}
}
}
else
{
UIMessageBox.Show("串口未打开,请先打开串口!!!");
}
});
}
private void uibuttonTextUpdate(UIControl uIControl, string text) //委托的方式更新按键文本
{
//采用委托的方式更新UI界面label1显示的字符串
if (uIControl.InvokeRequired) //label1委托请求
{
while (!uIControl.IsHandleCreated)
{
//解决窗体关闭时出现“访问已释放句柄“的异常
if (uIControl.Disposing || uIControl.IsDisposed)
return;
}
Invoke(new Action(() => { uIControl.Text = text; }));
}
else
{
uIControl.Text = text;
}
}
private void serialPort_DataReceived(object sender, SerialDataReceivedEventArgs e) //串口数据接收处理
{
//异步委托一个线程,不然接收数据时会出现数据线程错误
this.Invoke((EventHandler)delegate
{
if (serialPort.IsOpen)
{
try
{
byte[] receivedData = new byte[serialPort.BytesToRead];//创建接收数据数组
serialPort.Read(receivedData, 0, receivedData.Length);//读取数据
var content = string.Empty;
//显示形式
if (uiCheckBoxHexDisplay.Checked && !uiCheckBoxStringDisplay.Checked)
{
for (int i = 0; i < receivedData.Length; i++)
{
//ToString("X2") 为C#中的字符串格式控制符
//X为 十六进制
//2为 每次都是两位数
content += (receivedData[i].ToString("X2") + " ");
}
}
else if (!uiCheckBoxHexDisplay.Checked && uiCheckBoxStringDisplay.Checked)
{
content = Encoding.GetEncoding("GB2312").GetString(receivedData);//防止乱码
}
//接收文本框
uiRichTextBoxRecieveArea.AppendText(content); //接收区域追加数据
uiRichTextBoxRecieveArea.SelectionStart = uiRichTextBoxRecieveArea.Text.Length; //将光标设置到末尾位置
uiRichTextBoxRecieveArea.ScrollToCaret(); //接收区域更新显示最后一行
serialPort.DiscardInBuffer();//丢弃缓存区数据
}
catch (Exception ex)
{
UIMessageBox.Show(ex.Message, "Error");
}
}
else
{
UIMessageBox.Show("请打开串口", "Error");
}
});
}
private void uiCheckBoxStringDisplay_Click(object sender, EventArgs e) //选择字符串显示
{
uiCheckBoxStringDisplay.Checked = true;
uiCheckBoxHexDisplay.Checked = false;
}
private void uiCheckBoxHexDisplay_Click(object sender, EventArgs e) //选择16进制显示
{
uiCheckBoxStringDisplay.Checked = false;
uiCheckBoxHexDisplay.Checked = true;
}
private void Form1_Load(object sender, EventArgs e) //采用委托的方式实时接收数据并显示
{
serialPort.DataReceived += new SerialDataReceivedEventHandler(serialPort_DataReceived);
}
}
}
三、视频演示
C#简易串口调试软件