前言
工控领域通常需要使用串口对仪器进行程控
目前主流的控制方式为:USB、串口、LAN
本篇文章主要介绍串口控制
需求分析
封装前需要分析串口类需要的方法进行分析和统计
1、通常情况下一台测试设备中可能包含多个串口仪器,所以串口类不能使用静态方法,那么就需要有构造方法。
2、串口的使用需要传递通讯参数,包括:波特率、数据位、校验位、停止位。而且串口还需要有Open的操作。所有串口类需要有串口的打开方法或这初始化方法。对应的也需要有Close方法。
3、上位机控制仪器,一般包含控制指令和询问指令。以万用表为例,控制指令:将万用表设置为电压档;询问指令:查询当的测量电压。所以串口类需要有Write方法和Query方法
代码实现
csharp
public class PortHelper
{
public Action actConnectAfterDisConnect;
public Action actDisConnectAfterConnect;
public string portName;
public int baudRate;
public int dataBits;
public StopBits stopBit;
public Parity parity;
private SerialPort port;
public PortHelper(string portName, int baudRate, int dataBits, StopBits stopBit, Parity parity)
{
this.portName = portName;
this.baudRate = baudRate;
this.dataBits = dataBits;
this.stopBit = stopBit;
this.parity = parity;
}
/// <summary>
/// 创建串口并连接
/// </summary>
/// <returns></returns>
private bool Open()
{
port = new SerialPort(portName, baudRate, parity, dataBits, stopBit)
{
//设置读取超时时间
ReadTimeout = 1500
};
try
{
port.Open();
}
catch (Exception)
{
}
return port.IsOpen;
}
/// <summary>
/// 关闭客户端
/// </summary>
public void Close()
{
port?.Close();
}
public bool Write(string order)
{
if (port == null || !port.IsOpen)
{
if (!Open())
return false;
actConnectAfterDisConnect?.Invoke();
}
try
{
port.WriteLine(order);
return true;
}
catch (Exception)
{
actDisConnectAfterConnect?.Invoke();
//需要记录下异常错误信息:e.Message
return false;
}
}
/// <summary>
/// 客户端询问
/// </summary>
/// <param name="order"></param>
/// <returns></returns>
public string Query(string order)
{
if (port == null || !port.IsOpen)
{
if (!Open())
return "ERR";
actConnectAfterDisConnect?.Invoke();
}
try
{
port.WriteLine(order);
}
catch (Exception)
{
actDisConnectAfterConnect?.Invoke();
return "ERR";
}
string rst = "";
try
{
rst = port.ReadLine();
}
catch (Exception)
{
actDisConnectAfterConnect?.Invoke();
return "ERR";
}
if (rst.Length == 0)
return "ERR";
return rst;
}
/// <summary>
/// 异步询问
/// </summary>
/// <param name="order"></param>
/// <returns></returns>
public async Task<string> QueryAsync(string order, CancellationToken? ct = null)
{
CancellationToken token = ct ?? CancellationToken.None;
if (port == null || !port.IsOpen)
{
if (!Open())
return "ERR";
actConnectAfterDisConnect?.Invoke();
}
try
{
port.WriteLine(order);
}
catch (Exception)
{
actDisConnectAfterConnect?.Invoke();
return "ERR";
}
string rst;
try
{
rst = await Task.Run(() => port.ReadLine()) ;
}
catch (Exception)
{
actDisConnectAfterConnect?.Invoke();
return "ERR";
}
if (rst.Length == 0)
return "ERR";
return rst;
}
}
其中actConnectAfterDisConnect 和 actDisConnectAfterConnect 表示断线重连和连接后异常断开的事件。