工作上需要用到上位机进行数据交互,所以就用C#编制了一个简单的串口信息收发程序。界面如下:
开发过程中遇到的一个问题是串口的接收。串口接收大体来说有两个方式,一个是同步读取,也即利用循环不断的读串口缓存,另外一个就是利用事件触发的方式。第一种方法效率低,不推荐,第二种则需要利用到跨线程的内容。本人就是卡在这里一天,其实也就10来句代码的事,无奈自己玩这个没得请教,只有求助万能的百度。经过一天多断续的摸索,终于解决了这个问题。
在贴上代码前,先解释一下代码中会用到的一些控件的名称。
1、 cmbportname:设置串口号的下拉列表
2、 cmbbaudrate:设置波特率的下来列表
3、 bttopenport:打开/关闭串口的动作按钮
4、 txSend:要发送的数据显示文本框
5、 bttSend:发送那妞
6、 txrecieve:接收到的数据显示文本框
7、 bttClear:清空接收数据的按钮
涂黄的代码关系到异步接收数据,只要照着那几个涂黄的代码改一下,应该就可以实现了功能了。需要完整代码的也可以发邮件给我,。
代码中的SP是从工具箱拖进来的一个serialport控件。
代码:
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 Form1 : Form
{
public Form1()
{
InitializeComponent();
}
public delegate void getstring(string dataRe);//定义委托
getstring getmystring;//定义委托变量
private void DoUpdate(string data)
{
tbRecieve.Text = tbRecieve.Text + data;//数据处理,将当前数据与文本框文本合并
if (label5.BackColor == Color.AliceBlue)//改变lable的颜色,提示收到数据
{
label5.BackColor = Color.Black;
}
else label5.BackColor = Color.AliceBlue;
}
void SP_DataReceived(object sender, SerialDataReceivedEventArgs e)//接收事件触发方法
{
try
{
string mystring = SP.ReadExisting();
getmystring = new getstring(DoUpdate);
Invoke(getmystring, mystring);
}
catch (Exception EX)
{
MessageBox.Show(EX.Message, "出错", MessageBoxButtons.OK, MessageBoxIcon.Error);
return;
}
}
private void bttOpenPort_Click(object sender, EventArgs e)//打开串口按钮单击事件函数
{
try
{
if (SP.IsOpen == true)//如果当前串口是处于打开状态,则单击按钮为关闭串口动作
{
cmbPortName.Enabled = true;//使能串口号获取控件
cmbBaudRate.Enabled = true;//使能波特率设置控件
bttSend.Enabled = false;//关闭发送数据按钮
SP.Close();//关闭串口
bttOpenPort.Text = "打开串口";//将打开按钮文字改为打开串口
}
else if (SP.IsOpen == false)//如果当前串口是处于关闭状态,则单击按钮为打开串口动作
{
cmbPortName.Enabled = false;//关闭串口号获取控件
cmbBaudRate.Enabled = false;//关闭波特率设置控件
bttOpenPort.Text = "关闭串口";//将打开按钮文字改为关闭串口
SP.BaudRate = Convert.ToInt16(cmbBaudRate.SelectedItem);//设置波特率为对应combox的选择项,强制转换成int型
SP.PortName = cmbPortName.SelectedItem.ToString();//串口号设置成串口号获取控件当前选择项,强制转换成string
SP.StopBits = StopBits.One;//停止位1位
SP.Parity = 0;//校验,无
SP.DataBits = 8;//数据位,8位
SP.ReceivedBytesThreshold = 10;//接收数据事件触发门限,设为10,可根据需要设置
SP.Open();//打开串口
bttSend.Enabled = true;//使能发送数据按钮
SP.DataReceived += new SerialDataReceivedEventHandler(SP_DataReceived);//添加数据接收事件
}
}
catch (Exception EX)
{
MessageBox.Show(EX.Message, "出错", MessageBoxButtons.OK, MessageBoxIcon.Error);
return;
}
}
private void bttSend_Click(object sender, EventArgs e)
{
try
{
SP.Write(tbSend.Text);
}
catch (Exception EX)
{
MessageBox.Show(EX.Message, "出错", MessageBoxButtons.OK, MessageBoxIcon.Error);
return;
}
}
//串口号选择combox鼠标点击事件,为了获取电脑当前有的串口号,并将其添加到combox列表中
//
private void bttGetPort_Click(object sender, EventArgs e)
{
string[] Ports = SerialPort.GetPortNames();
Array.Sort(Ports);
cmbPortName.Items.AddRange(Ports);
cmbPortName.SelectedIndex = cmbPortName.Items.Count > 0 ? 0 : -1;
cmbBaudRate.SelectedIndex = cmbBaudRate.Items.IndexOf("9600");
tbSend.Text = Ports[1];
}
private void bttClear_Click(object sender, EventArgs e)//清空数据按钮点击事件
{
tbRecieve.Text = string.Empty;//清空文本框文本内容
}
}
}
閱讀更多 能源工控微課堂 的文章