学习C#做简单上位机界面,简单熟悉C#控件使用方法后尝试实现串口通信,控件拖拽很方便,双击工具箱里的,双击SerialPort控件后就向窗体中添加了一个串口对象,在Form1_Load里添加如下代码
private void Form1_Load(object sender, EventArgs e)
{
try
{
button1.Text = "打开串口";
textBox2.Text = "test";
label2.Text = "Ok";
button1.BackColor = Color.Gray;
string[] PortsName = SerialPort.GetPortNames(); //获取计算机串口
Array.Sort(PortsName); //有多个串口时排序
comboBox1.Items.AddRange(PortsName);
comboBox1.SelectedIndex = 0; //默认选择列表第一个串口
}
catch(Exception ex)
{
MessageBox.Show("没有发现串口","错误提示");
}
}
在窗体上放置一个button用作打开和关闭串口,双击窗体上的button后跳到button点击事件里,添加代码如下:
private void button1_Click(object sender, EventArgs e)
{
try
{
if (MyCom.IsOpen)
{
button1.BackColor = Color.Gray;
button1.Text = "打开串口";
MyCom.Close();
}
else
{
button1.BackColor = Color.Red;
button1.Text = "关闭串口";
MyCom.Open();
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
在串口属性值都为默认情况下,SerialPortd的最简单的主要方法就是ReadLine和WriteLine,窗体中添加一个发送按钮,click事件代码如下:
private void button2_Click(object sender, EventArgs e)
{
try
{
MyCom.WriteLine(textBox2.Text);
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
return;
}
}
接收事件,SerialPort提供了相应的Receive事件,只需要在控件的事件栏(闪电图标)里双击DataReceived即可跳到接收事件代码处,这个操作同时也在Form1.Designer.cs里完成了串口接收事件的注册(MyCom为串口对象名称):
// MyCom
//
this.MyCom.DataReceived += new System.IO.Ports.SerialDataReceivedEventHandler(this.MyCom_DataReceived_1);
//
接收代码如下:
<pre class="csharp" name="code"> private void MyCom_DataReceived(object sender, SerialDataReceivedEventArgs e)//接收数据
{
try
{
System.Threading.Thread.Sleep(100);
int DataLength = MyCom.BytesToRead;
byte[] buf = new byte[DataLength];
MyCom.Read(buf, 0, DataLength);
RCount++;
string str = Encoding.ASCII.GetString(buf);
this.Invoke(new EventHandler(delegate
{
richTextBox1.Text = richTextBox1.Text + str + '\n';
ReceiveCount.Text = Convert.ToString(RCount);
}
));
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "错误提示");
}
}
}
读数据的ReadLine()只有当接收的数据里有换行符时才停止接收,不然程序将一直等待,而Read()方法是自己定义byte长度,不过程序里要加上让线程挂起,即代码中的sleep方法,只有sleep足够长,才能保证发送很长的内容是能完整接收,应该有其它解决办法的吧!
ReadLine()接收代码如下(发送内容里一定要有换行符):
string Context;
Context = MyCom.ReadLine();
程序刚开始调试时发现发送正常,但接收不到数据,在发送和接收里分别设置断点后调试,结果发现程序无法进入接收方法里,于是怀疑接收方法没注册,仔细看代码发现原来之前在类里面实例化了一个全局SerialPort对象:
SerialPort sp = new SerialPort();
但又在工具栏里双击添加了一个SerialPort对象(名称为SerialPort1),在时间栏里双击DataReceived事件后,其实是注册了SerialPort1的接收事件,自己实例化的串口对象并没有注册监听事件,手动添加注册代码:
MyCom.DataReceived += new SerialDataReceivedEventHandler(MyCom_DataReceived);
之后便可以接收数据了。现在关于对象的概念体会还不是很深,同时对C#窗体编程中控件对象与代码的关系还没理清楚,导致这个简单错误也找了很长时间,不过现在也算实现了最简单的功能,程序还有很多问题,慢慢解决……