一、 Form窗体设计
![](https://img-blog.csdnimg.cn/direct/2cb1eb2ae8fe42d29df76f9a6b09ead8.png)
所用控件:
按钮控件Button
编辑框控件TextBox
组合框控件ComboBox
复选框控件CheckBox
单选框控件RadioButton
标签控件Label
定时器组件Timer
分组框控件GroupBox
二、代码
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO.Ports;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Timers;
namespace WinFChuanKou
{
public partial class Form1 : Form
{
// private System.Timers.Timer clickTimer;
private Thread trd;
private bool isSending = false;
private bool isChecked = true;
private Thread sendingThread;
public Form1()
{
InitializeComponent();
//clickTimer = new System.Timers.Timer();
//clickTimer.Interval = 1000; // 设置定时器的周期为1秒
//clickTimer.AutoReset = true; // 设置定时器为可重复触发
//clickTimer.Elapsed += OnTimedEvent; // 绑定定时器触发事件处理方法
}
//private void ThreadTask()
//{
// byte[] sendData = null;
// string strData = null;
// while (continueThread)
// {
// strData = tbxSend.Text.Trim();
// if (rbnSendHEX.Checked)
// {
// sendData = strToHexByte(strData);
// }
// else if (rbnSendASCII.Checked)
// {
// sendData = Encoding.ASCII.GetBytes(strData);
// }
// if (sendData != null)
// {
// serialPort1.Write(sendData, 0, sendData.Length); // 将读取到的全部数据写入串口
// }
// Thread.Sleep(1000);
// }
//}
private void SendDataThread()
{
while (isChecked)
{ if (isSending)
{
byte[] sendData = null;
string strData = tbxSend.Text.Trim();
if (rbnSendHEX.Checked)
{
sendData = strToHexByte(strData);
}
else if (rbnSendASCII.Checked)
{
sendData = Encoding.ASCII.GetBytes(strData);
}
if (sendData != null)
{
serialPort1.Write(sendData, 0, sendData.Length); // 发送数据到串口
}
Thread.Sleep(Convert.ToInt32(tbxAuto.Text));
}
}
}
//private void OnTimedEvent(object source, ElapsedEventArgs e)
//{
// // 模拟点击btnSend按钮
// // 确保在UI线程上执行按钮点击操作
// if (btnSend.InvokeRequired)
// {
// btnSend.Invoke(new MethodInvoker(delegate
// {
// btnSend.PerformClick();
// }));
// }
// else
// {
// btnSend.PerformClick();
// }
//}
private void Form1_Load(object sender, EventArgs e)
{
// 串口
string[] str = SerialPort.GetPortNames();
foreach (string p in str)
{
cbxSerial.Items.Add(p);
}
cbxSerial.SelectedIndex = 0;
// 波特率
cbxBuadRate.Items.Add("300");
cbxBuadRate.Items.Add("1200");
cbxBuadRate.Items.Add("2400");
cbxBuadRate.Items.Add("4800");
cbxBuadRate.Items.Add("9600");
cbxBuadRate.Items.Add("19200");
cbxBuadRate.Items.Add("38400");
cbxBuadRate.Items.Add("43000");
cbxBuadRate.Items.Add("56000");
cbxBuadRate.Items.Add("115200");
cbxBuadRate.SelectedIndex = 4;
// 数据位
cbxDataBits.Items.Add("5");
cbxDataBits.Items.Add("6");
cbxDataBits.Items.Add("7");
cbxDataBits.Items.Add("8");
cbxDataBits.SelectedIndex = 3;
// 停止位
cbxStop.Items.Add("0");
cbxStop.Items.Add("1");
cbxStop.Items.Add("1.5");
cbxStop.Items.Add("2");
cbxStop.SelectedIndex = 1;
// 校验位
cbxParity.Items.Add("无");
cbxParity.Items.Add("奇校验");
cbxParity.Items.Add("偶校验");
cbxParity.SelectedIndex = 0;
// ACSII单选框格式
rbnSendASCII.Checked = true;
rbnRecASCII.Checked = true;
//发送按钮
btnSend.Enabled = false;
//
sendingThread = new Thread(new ThreadStart(SendDataThread));
sendingThread.IsBackground = true;
sendingThread.Start();
}
SerialPort serialPort1 = new SerialPort();
// 在开始button点击时,设置串口信息,串口打开时发送button的enabled打开
private void btnOpen_Click(object sender, EventArgs e)
{
try
{
if (!serialPort1.IsOpen)
{
serialPort1.PortName = cbxSerial.SelectedItem.ToString();
serialPort1.BaudRate = Convert.ToInt32(cbxBuadRate.SelectedItem.ToString());
serialPort1.DataBits = Convert.ToInt32(cbxDataBits.SelectedItem.ToString());
serialPort1.StopBits = (StopBits)Convert.ToInt32(cbxStop.SelectedItem.ToString());
serialPort1.Parity = (Parity)Convert.ToInt32(cbxStop.SelectedItem.ToString());
serialPort1.WriteTimeout = 1000;
serialPort1.ReadTimeout = 1000;
serialPort1.DataReceived += new SerialDataReceivedEventHandler(serialPort1_DataReceived);
serialPort1.Open();
if (serialPort1.IsOpen)
{
btnSend.Enabled = true;
}
btnOpen.Text = "关闭";
}
else
{
serialPort1.DataReceived -= new SerialDataReceivedEventHandler(serialPort1_DataReceived);
serialPort1.Close();
btnSend.Enabled = false;
btnOpen.Text = "打开";
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "操作串口错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
return;
}
}
// 点击输出文本框可以清除文字
private void 清除ToolStripMenuItem_Click(object sender, EventArgs e)
{
tbxRec.Clear();
}
// 发送button的click事件时,将从sendtxtbox读取到的信息发送出去
private void btnSend_Click(object sender, EventArgs e)
{
//clickTimer.Start();
byte[] sendData = null;
string strData = null;
strData = tbxSend.Text.Trim();
if (rbnSendHEX.Checked)
{
sendData = strToHexByte(strData);
}
else if (rbnSendASCII.Checked)
{
sendData = Encoding.ASCII.GetBytes(strData);
}
serialPort1.Write(sendData, 0, sendData.Length); // 将读取到的全部数据写入串口
}
// 复选框SendASCII触发CheckedChanged事件,如果输入框不为空,则读取输入框的内容并转码
private void rbnSendASCII_CheckedChanged(object sender, EventArgs e)
{
if (rbnSendASCII.Checked)
{
byte[] data = null;
if (tbxSend.Text == "")
{
return;
}
data = HexStringToByte(tbxSend.Text.Trim());
tbxSend.Text = new ASCIIEncoding().GetString(data);
}
}
// SendHEX复选框被选中时,将发送文本框的文本转换为字节数组,转换为十六进制大写再赋值给发送框
private void rbnSendHEX_CheckedChanged(object sender, EventArgs e)
{
if (rbnSendHEX.Checked)
{
byte[] data = null;
data = System.Text.Encoding.Default.GetBytes(tbxSend.Text.Trim());
StringBuilder s = new StringBuilder();
for (int i = 0; i < data.Length; i++)
{
s.AppendFormat("{0:x2}" + " ", data[i]);
}
tbxSend.Text = s.ToString().ToUpper();
}
}
private void rbnRecASCII_CheckedChanged(object sender, EventArgs e)
{
if (rbnRecASCII.Checked)
{
byte[] data = null;
if (string.IsNullOrEmpty(tbxRec.Text))
{
return;
}
data = HexStringToByte(tbxRec.Text.Trim());
tbxRec.Text = new ASCIIEncoding().GetString(data);
}
}
private void rbnRecHEX_CheckedChanged(object sender, EventArgs e)
{
if (rbRecHEX.Checked)
{
byte[] data = null;
data = System.Text.Encoding.Default.GetBytes(tbxRec.Text.Trim());
StringBuilder sb = new StringBuilder();
for (int i = 0; i < data.Length; i++)
{
sb.AppendFormat("{0:x2}" + " ", data[i]);
}
tbxRec.Text = sb.ToString().ToUpper();
}
}
// 16进制转字节数组
private byte[] HexStringToByte(string hexstring)
{
string[] tmpary = hexstring.Trim().Split(' ');
byte[] buff = new byte[tmpary.Length];
for (int i = 0; i < buff.Length; i++)
{
buff[i] = Convert.ToByte(tmpary[i], 16);
}
return buff;
}
// 字符串转换16进制字节数组
private byte[] strToHexByte(string hexString)
{
hexString = hexString.Replace(" ", "");
if ((hexString.Length % 2) != 0)
hexString += " ";
byte[] returnBytes = new byte[hexString.Length / 2];
try
{
for (int i = 0; i < returnBytes.Length; i++)
returnBytes[i] = Convert.ToByte(hexString.Substring(i * 2, 2), 16);
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "转换成HEX错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
return returnBytes;
}
private bool Send(byte[] data)
{
if (serialPort1.IsOpen)
{
try
{
serialPort1.Write(data, 0, data.Length);
Thread.Sleep(10);
serialPort1.WriteLine("\r\n");
return true;
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "发送数据错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
else
{
MessageBox.Show("未打开串口", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
return false;
}
// 串口接收
private void serialPort1_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
byte[] ReDatas = new byte[serialPort1.BytesToRead];
serialPort1.Read(ReDatas, 0, ReDatas.Length);
this.AddData(ReDatas);
}
public void AddData(byte[] data)
{
if (rbRecHEX.Checked)
{
StringBuilder s = new StringBuilder();
for (int i = 0; i < data.Length; i++)
{
s.AppendFormat("{0:x2}" + " ", data[i]);
}
AddContent(s.ToString().ToUpper());
}
else if (rbnRecASCII.Checked)
{
AddContent(new ASCIIEncoding().GetString(data));
}
}
private void AddContent(string content)
{
this.BeginInvoke(new MethodInvoker(delegate
{
tbxRec.AppendText(content);
}));
}
private void chaeckbox_CheckedChanged(object sender, EventArgs e)
{
if (chaeckbox.Checked)
{
isSending = true;
}
else
{
isSending = false;
}
}
}
}
三、测试工具(虚拟串口工具)
![](https://img-blog.csdnimg.cn/direct/17a6368ea3bb4a9e82acc9a586d72518.png)
四、实际演示
![](https://img-blog.csdnimg.cn/direct/503bd0246c464f4f879568266c3fa2bd.png)