主窗体及下的代码
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;
using System.IO;
using System.Threading;
namespace WindowsFormsApplication1
{
public partial class 串口助手 : Form
{
public 串口助手()
{
InitializeComponent();
}
private Thread getRecevice; //声明线程
protected Boolean stop = false;
protected Boolean conState = false;
//private StreamReader sRead;
private StringBuilder builder = new StringBuilder();
bool bAccpet = false;
private UInt32 tx, rx = 0;
SerialPort sp = new SerialPort();//实例化串口通讯类
//以下定义4个公有变量,用于参数传递
public static string strProtName = "";
public static string strBaudRate = "";
public static string strDataBits = "";
public static string strStopBits = "";
private void Form1_Load(object sender, EventArgs e)
{
// 端口未打开时
groupBox1.Enabled = false;//发送区不可选
groupBox2.Enabled = false;//接收区不可选
this.toolStripStatusLabel1.Text = "端口号:端口未打开 | ";
this.toolStripStatusLabel2.Text = "波特率:端口未打开 | ";
this.toolStripStatusLabel3.Text = "数据位:端口未打开 | ";
this.toolStripStatusLabel4.Text = "停止位:端口未打开 | ";
this.toolStripStatusLabel5.Text = "";
}
//串口设置按钮监听事件
private void btnSetSP_Click_1(object sender, EventArgs e)
{
timer1.Enabled = false;//关闭计时器1
sp.Close();//关闭当前串口
Form2 dlg = new Form2();//打开串口设置窗口
if (dlg.ShowDialog() == DialogResult.OK)//判断是否点击了串口设置窗口的确定按钮,在设置窗口的确定按钮监听下设置了DialogResult = DialogResult.OK;
{//将串口设置窗口的参数传到串口的设置参数中
sp.PortName = strProtName;//串口号
sp.BaudRate = int.Parse(strBaudRate);//波特率
sp.DataBits = int.Parse(strDataBits);//数据位
sp.StopBits = (StopBits)int.Parse(strStopBits);//停止位
sp.ReadTimeout = 500;//读取数据的超时时间,引发ReadExisting异常
}
}
private void bntSwitchSP_Click(object sender, EventArgs e)
{
if (bntSwitchSP.Text == "打开串口")
{
if (strProtName != "" && strBaudRate != "" && strDataBits != "" && strStopBits != "")
{
try
{
if (sp.IsOpen)
{
sp.Close();
sp.Open();//打开串口
}
else
{
sp.Open();//打开串口
}
bntSwitchSP.Text = "关闭串口";
groupBox1.Enabled = true;//发送区可选
groupBox2.Enabled = true;//接收区可选
this.toolStripStatusLabel1.Text = "端口号:" + sp.PortName + " | ";
this.toolStripStatusLabel2.Text = "波特率:" + sp.BaudRate + " | ";
this.toolStripStatusLabel3.Text = "数据位:" + sp.DataBits + " | ";
this.toolStripStatusLabel4.Text = "停止位:" + sp.StopBits + " | ";
this.toolStripStatusLabel5.Text = "";
}
catch (Exception ex)
{
MessageBox.Show("错误:" + ex.Message, "C#串口通信");
}
}
else
{
MessageBox.Show("请先设置串口!", "RS232串口通信");
}
// //使用委托以及多线程进行接收数据
sp.Encoding = Encoding.GetEncoding("GB2312");
bAccpet = true;
ThreadStart th = new ThreadStart(testDelegate);
getRecevice = new Thread(th);
getRecevice.IsBackground = true;
getRecevice.Start();
}
else
{
/*****************接收的线程*****************/
try
{ //停止主监听线程
if (null != getRecevice)
{
if (getRecevice.IsAlive)
{
if (!getRecevice.Join(100))
{
//关闭线程
getRecevice.Abort();
}
}
getRecevice = null;
}
}
catch { }
/****************************************************************/
timer2.Stop();
timer1.Enabled = false;
timer2.Enabled = false;
bntSwitchSP.Text = "打开串口";
if (sp.IsOpen) sp.Close();
groupBox1.Enabled = false;
groupBox2.Enabled = false;
this.toolStripStatusLabel1.Text = "端口号:端口未打开 | ";
this.toolStripStatusLabel2.Text = "波特率:端口未打开 | ";
this.toolStripStatusLabel3.Text = "数据位:端口未打开 | ";
this.toolStripStatusLabel4.Text = "停止位:端口未打开 | ";
this.toolStripStatusLabel5.Text = "";
}
}
private void timer2_Tick(object sender, EventArgs e)
{
if (sp.IsOpen)
{
try
{
if (hex_Send.Checked == true)//以十六进制发送
{
byte[] Send_buf = HexStringToByteArray(txtSend.Text);
sp.Write(Send_buf, 0, Send_buf.Length);
}
else
{//字符串发送
sp.Encoding = System.Text.Encoding.GetEncoding("GB2312");//编码格式
sp.Write(txtSend.Text);//发送数据
}
}
catch (Exception ex)
{
MessageBox.Show("错误:" + ex.Message);
}
}
else
{
timer2.Stop();
MessageBox.Show("请先打开串口!");
}
}
////开启定时发送
private void checkBox1_timer_CheckedChanged(object sender, EventArgs e)
{
if (checkBox1_timer.Checked == true)
{
try
{
timer2.Interval = Convert.ToInt32(textBox1.Text);
timer2.Start(); // 启动计时器, 默认不启动
}
catch (Exception ec)
{
MessageBox.Show(ec.Message);
}
} ////关闭定时发送
else// if (checkBox1_timer.Checked == false)
{
timer2.Stop();
}
}
//清除发送
private void button3_Click(object sender, EventArgs e)
{
txtSend.Clear();
}
//清除接收
private void button4_Click(object sender, EventArgs e)
{
txtReceiveData.Clear();
}
//字符串转十六进制字符串
public static byte[] HexStringToByteArray(string s)
{
s = s.Replace(" ", "");
byte[] buffer = new byte[s.Length / 2];
for (int i = 0; i < s.Length; i += 2)
buffer[i / 2] = (byte)Convert.ToByte(s.Substring(i, 2), 16);
return buffer;
}
//发送数据按键
private void bntSendData_Click(object sender, EventArgs e)
{
if (sp.IsOpen)
{
try
{
if (hex_Send.Checked == true)//以十六进制发送
{
byte[] Send_buf = HexStringToByteArray(txtSend.Text);
sp.Write(Send_buf, 0, Send_buf.Length);
}
else
{//字符串发送
sp.Encoding = System.Text.Encoding.GetEncoding("GB2312");
sp.Write(txtSend.Text);//发送数据
}
}
catch (Exception ex)
{
MessageBox.Show("错误1:" + ex.Message);
}
}
else
{
MessageBox.Show("请先打开串口!");
}
}
private void testDelegate()
{
reaction r = new reaction(fun);
r();
}
//下面用到了接收信息的代理功能,此为设计的要点之一
delegate void DelegateAcceptData();//刷新接收框的委托
void fun()
{
while (bAccpet)
{
try
{
DelegateAcceptData ddd = new DelegateAcceptData(dat);
this.Invoke(ddd, new object[] { });
}
catch { }
}
}
delegate void reaction();
private void dat()
{
try
{
int n = sp.BytesToRead;
byte[] buf = new byte[n];
sp.Read(buf, 0, n);
builder.Clear();
rx += (UInt32)n;
foreach (byte i in buf)
{
builder.Append(i.ToString("x2") + " ");
}
txtReceiveData.AppendText(builder.ToString());
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
}
}
设置窗口的代码
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 WindowsFormsApplication1
{
public partial class Form2 : Form
{
public Form2()
{
InitializeComponent();
}
private void Form2_Load(object sender, EventArgs e)
{
//串口
string[] ports = SerialPort.GetPortNames();
foreach (string port in ports)
{
cmbPort.Items.Add(port);
}
cmbPort.SelectedIndex = 0;
//波特率
cmbBaudRate.Items.Add("110");
cmbBaudRate.Items.Add("300");
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.Items.Add("230400");
cmbBaudRate.Items.Add("460800");
cmbBaudRate.Items.Add("921600");
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.SelectedIndex = 0;
//佼验位
cmbParity.Items.Add("无");
cmbParity.SelectedIndex = 0;
}
private void bntOK_Click_1(object sender, EventArgs e)
{
//以下4个参数都是从窗体MainForm传入的
串口助手.strProtName = cmbPort.Text;
串口助手.strBaudRate = cmbBaudRate.Text;
串口助手.strDataBits = cmbDataBits.Text;
串口助手.strStopBits = cmbStopBit.Text;
DialogResult = DialogResult.OK;
}
private void cmbPort_SelectedIndexChanged(object sender, EventArgs e)
{
}
private void bntCancel_Click_1(object sender, EventArgs e)
{
DialogResult = DialogResult.Cancel;
}
}
}
主窗体界面
设置窗口界面