最近涉及到串口编程比较多,在项目中需要通过串口给硬件设备发送控制指令,为了确认发送的控制指令被正确执行,所以过程一般是这样:
1、 向串口发送控制指令,此时设备没有数据返回
2、 向串口发送状态读取指令确认设备的状态是否已经改变,此时设备会返回当前的状态。
由于有些设备返回的状态数据较少,而有些设备返回的状态数据较多(可能分多次返回),所以需要根据情况来预估等待时间的值。但总觉得根据实际情况给定等待的时间不是很好,有没有更专业的串口编程的方法,请告知,谢谢。
下面是我上面说的办法的代码:

Code
1
using System;
2
using System.IO.Ports;
3
using System.Configuration;
4
using System.Threading;
5
6
namespace Communication
7

{
8
/**//// <summary>
9
/// 串口类
10
/// </summary>
11
public class ComPort : IDisposable
12
{
13
private string portName;
14
/**//// <summary>
15
/// 获取或设置 串口号,默认为 "COM1"
16
/// </summary>
17
public string PortName
18
{
19
get
{ return this.portName; }
20
set
{ this.portName = value; }
21
}
22
23
private int baudRate;
24
/**//// <summary>
25
/// 获取或设置 串口波特率, 默认 9600
26
/// </summary>
27
public int BaudRate
28
{
29
get
{ return this.baudRate; }
30
set
{ this.baudRate = value; }
31
}
32
33
private int dataBits;
34
/**//// <summary>
35
/// 获取或设置 一个字节的数据位,默认 8
36
/// </summary>
37
public int DataBits
38
{
39
get
{ return this.dataBits; }
40
set
{ this.dataBits = value; }
41
}
42
43
private StopBits stopBits;
44
/**//// <summary>
45
/// 获取或设置 停止位, 默认 1
46
/// </summary>
47
public StopBits StopBits
48
{
49
get
{ return this.stopBits; }
50
set
{ this.stopBits = value; }
51
}
52
53
//内置的串口对象
54
private SerialPort serialPort;
55
56
private int waitTimeInMilliseconds;
57
/**//// <summary>
58
/// 获取或设置 需要从串口接收数据时的等待时间(以毫秒为单位) , 默认50毫秒
59
/// </summary>
60
public int WaitTimeInMilliseconds
61
{
62
get
{ return this.waitTimeInMilliseconds; }
63
set
{ this.waitTimeInMilliseconds = value; }
64
}
65
66
public ComPort()
67
{
68
this.portName = "COM1";
69
this.baudRate = 9600;
70
this.dataBits = 8;
71
this.stopBits = StopBits.One;
72
this.waitTimeInMilliseconds = 50;
73
74
try
75
{
76
this.portName = ConfigurationManager.AppSettings["ComPortName"].ToString();
77
}
78
catch
79
{
80
}
81
try
82
{
83
this.baudRate = int.Parse(ConfigurationManager.AppSettings["ComBaudRate"].ToString());
84
}
85
catch
86
{
87
}
88
try
89
{
90
this.waitTimeInMilliseconds = int.Parse(ConfigurationManager.AppSettings["WaitTimeInMilliseconds"].ToString());
91
}
92
catch
93
{
94
}
95
96
this.serialPort = null;
97
}
98
99
/**//// <summary>
100
/// 串口对象初始化
101
/// </summary>
102
public void Initialize()
103
{
104
this.serialPort = new SerialPort(this.portName, this.baudRate, Parity.None, this.dataBits, this.stopBits);
105
this.serialPort.DataReceived += new SerialDataReceivedEventHandler(serialPort_DataReceived);
106
}
107
108
private void serialPort_DataReceived(object sender, SerialDataReceivedEventArgs e)
109
{
110
//当SendCommand的“Thread.Sleep(this.waitTimeInMilliseconds);”被执行时,正在干下面的事情:
111
//如果该过程经历时间较长(比如有很多的数据要读取),可以通过设置增大“this.waitTimeInMilliseconds”的值。
112
//也就是说根据实际情况预估 等待时间 的值,总感觉这样处理不是很好。
113
//有更靠谱的串口编程的方式,请告知,谢谢。
114
int bytes = this.serialPort.BytesToRead;
115
byte[] data = new byte[bytes];
116
this.serialPort.Read(data, 0, bytes);
117
118
//当接收到数据且函数委托不为空时,调用函数委托处理接收到的数据
119
if (null != data)
120
if (null != this.dgDataReceived)
121
this.dgDataReceived(data);
122
}
123
124
/**//// <summary>
125
/// 发送数据
126
/// </summary>
127
/// <param name="data">要发送的数据流</param>
128
/// <param name="bRead">发送完后是否马上读取数据</param>
129
public void SendCommand(byte[] data, bool bRead)
130
{
131
//预防被多线程调用
132
lock (this.serialPort)
133
{
134
this.serialPort.Open();
135
136
this.serialPort.Write(data, 0, data.Length);
137
138
//此时正在执行 serialPort_DataReceived 函数。
139
if (bRead)
140
Thread.Sleep(this.waitTimeInMilliseconds);
141
142
this.serialPort.Close();
143
}
144
}
145
146
public delegate void DGDataReceived(byte[] data);
147
private DGDataReceived dgDataReceived;
148
/**//// <summary>
149
/// 设置 当接收到数据时的函数委托
150
/// </summary>
151
public DGDataReceived DataReceived
152
{
153
set
{ this.dgDataReceived = value; }
154
}
155
156
IDisposable 成员#region IDisposable 成员
157
public void Dispose()
158
{
159
if (this.serialPort.IsOpen)
160
this.serialPort.Close();
161
}
162
#endregion
163
}
164
}
165