在做些简单的通讯,数据量小的情况下,使用串口是比较理想的。但是如果一旦机器上需要使用串口非常多的话,这时你也许需要一个工具来管理这些串口了。
串口设置参数,如COM口,波特率,奇偶校验等。
下面是一个简单的COM串口管理类 SerialPortCollectionManager,继承System.Collections.CollectionBase基类。
方法非常常见,代码过长,直接看方法更直观。
SerialPortParameter 是串口参数配置类。
代码放在后头,有兴趣朋友瞧瞧,不足支持请多多指教。
下面测试
假设工业生产,一台工控机上连有5个COM口,两个连中继器,三个连固扫。
从串口读数据,感觉挺简单的吧。那么怎么在高速的生产环境使用串口来适应生产呢?
一般情况下使用event触发,可以参考http://blog.csdn.net/wuyazhe/article/details/5598945
告诉你,起一个线程专门从串口读数据更适合工业高速生产环境;
//声明俩COM口的配置
SerialPortParameter[] paras = {new SerialPortParameter("COM1"),new SerialPortParameter("COM2")};
SerialPortCollectionManager instance = new SerialPortCollectionManager();
//添加俩个串口com1,com2到集合
instance.Add(paras);
//打开所有串口或某个串口,使用open方法重载
instance.open();
//从串口1读数据
string temp= instance.ReadBuffer("COM1")
//往串口1写数据
instance.Write("COM1","1234567890")
//关闭串口1
instance.Close("COM1");
//访问某个串口
SerialPort SerialPortOne=instance["COM1"];
//现在起一个线程读COM1数据
//声明一个委托处理读到COM1的数据
// public delegate T testDelegate<T>(string curContent);
Thread ThreadCOM1= new Thread(new ThreadStart(PrinterCOM));
ThreadCOM1.start();
public void PrinterCOM()
{
int IntevalFlag = 0;
bool flag=true;
string curRecCode = "";
while (flag)
{
try
{
//转换时间间隔界限
int IntervalLimit = 3;
while (instance[0].BytesToRead == 0)
{
//如果界限内就休眠50毫秒
if (IntevalFlag < IntervalLimit)
{
Thread.Sleep(50);
}
//如果超过界限就休眠100毫秒
else
{
Thread.Sleep(100);
if (IntevalFlag > 10000)
{
IntevalFlag = IntervalLimit;
}
}
IntevalFlag++;
}
//重新设置标识
IntevalFlag = 0;
curRecCode = Instance.ReadBuffer("COM1");
//独到COM口的数据,接下来进行数据解析和业务逻辑分析等处理。
}
catch (ThreadAbortException)
{
//
}
catch (Exception ex)
{
//MessageBox.Show(ex.Message);
}
}
}
好了,到这里基本上介绍完毕。
附件为原代码
namespace BarcodePrinter.Bussiness
{
/// <summary>
/// 串口操作管理类
/// </summary>
public sealed class SerialPortCollectionManager:System.Collections.CollectionBase
{
#region 方法
public SerialPort this[int index]
{
get
{
//如果元素不存在集合,则抛异常
lock (this.List.SyncRoot)
{
return ((SerialPort)List[index]);
}
}
set
{
//如果元素不存在集合,则抛异常
lock (this.List.SyncRoot)
{
List[index] = value;
}
}
}
public SerialPort this[string name]
{
get
{
SerialPort temp = null;
lock (this.List.SyncRoot)
{
foreach (SerialPort item in this.List)
{
if (item.PortName.Trim() == name)
{
temp = item;
break;
}
}
if (temp == null)
throw new System.ArgumentException("未找到串口:" + name + ",不存在集合中");
return temp;
}
}
set
{
bool result = true;
lock (this.List.SyncRoot)
{
for (int i = 0; i < this.List.Count; i++)
{
if (((SerialPort)this.List[i]).PortName == name)
{
List[i] = value;
result = false;
break;
}
}
if (result)
throw new System.ArgumentException("未找到串口:" + name + " ,不存在集合中");
}
}
}
public int Add(SerialPort value)
{
lock (this.List.SyncRoot)
{
return (List.Add(value));
}
}
/// <summary>
/// 初始化一个串口并加入集合中
/// </summary>
/// <param name="para"></param>
/// <returns></returns>
public SerialPort Add(SerialPortParameter para)
{
SerialPort serial = CreateSerialPortInstance(para);
lock (this.List.SyncRoot)
{
this.List.Add(serial);
}
return serial;
}
public SerialPort[] Add(SerialPortParameter[] paras)
{
List<SerialPort> list = new List<SerialPort>();
foreach (SerialPortParameter item in paras)
{
SerialPort serial = CreateSerialPortInstance(item);
list.Add(serial);
}
this.AddRange(list.ToArray());
return list.ToArray();
}
public void AddRange(SerialPort[] SerialPorts)
{
lock (this.List.SyncRoot)
{
foreach (SerialPort item in SerialPorts)
{
this.List.Add(item);
}
}
}
//public void Clear()
//{
// lock (this.List.SyncRoot)
// {
// this.List.Clear();
// }
//}
public bool Contains(string name)
{
lock (this.List.SyncRoot)
{
bool result = false;
foreach (SerialPort item in this.List)
{
if (item.PortName == name)
{
result = true;
break;
}
}
return result;
}
}
public bool Contains(SerialPort value)
{
// If value is not of type SerialPort, this will return false.
return (List.Contains(value));
}
public void CopyTo(SerialPort[] array, int index)
{
lock (this.List.SyncRoot)
{
this.List.CopyTo(array, index);
}
}
/// <summary>
///找到串口在集合的位置,不存在则为-1
/// </summary>
/// <param name="portName"></param>
/// <returns></returns>
public int IndexOf(string portName)
{
lock (this.List.SyncRoot)
{
int result = -1;
for (int i = 0; i < this.List.Count; i++)
{
if (((SerialPort)this.List[i]).PortName == portName)
{
result = i;
break;
}
}
return result;
}
}
public int IndexOf(SerialPort value)
{
lock (this.List.SyncRoot)
{
return (List.IndexOf(value));
}
}
public void Insert(int index, SerialPort value)
{
lock (this.List.SyncRoot)
{
List.Insert(index, value);
}
}
public void Remove(string portName)
{
lock (this.List.SyncRoot)
{
bool result = true;
for (int i = 0; i < this.List.Count; i++)
{
if (((SerialPort)List[i]).PortName == portName)
{
result = false;
this.List.RemoveAt(i);
break;
}
}
if (result)
throw new Exception("未在指定的集合中找到指定的项 "+portName+",因此无法移除该项。");
}
}
public void Remove(SerialPort value)
{
lock (this.List.SyncRoot)
{
List.Remove(value);
}
}
/// <summary>
/// 调用ADD时,插入集合时发生.
/// </summary>
/// <param name="index"></param>
/// <param name="value"></param>
protected override void OnInsert(int index, Object value)
{
// Insert additional code to be run only when inserting values.
base.OnInsert(index,value);
}
/// <summary>
/// 调用ADD时,插入集合后发生.
/// </summary>
/// <param name="index"></param>
/// <param name="value"></param>
protected override void OnInsertComplete(int index, object value)
{
base.OnInsertComplete(index, value);
}
protected override void OnSetComplete(int index, object oldValue, object newValue)
{
base.OnSetComplete(index, oldValue, newValue);
}
protected override void OnRemove(int index, Object value)
{
// Insert additional code to be run only when removing values.
}
protected override void OnRemoveComplete(int index, object value)
{
base.OnRemoveComplete(index, value);
}
protected override void OnSet(int index, Object oldValue, Object newValue)
{
base.OnSet(index, oldValue, newValue);
}
protected override void OnClear()
{
base.OnClear();
}
protected override void OnClearComplete()
{
base.OnClearComplete();
}
/// <summary>
/// 调用ADD时,插入集合之前对类型的校验
/// </summary>
/// <param name="value"></param>
protected override void OnValidate(Object value)
{
if (value.GetType() != typeof(System.IO.Ports.SerialPort))
throw new ArgumentException("value must be of type SerialPort.", "value");
}
#endregion
#region 拓展方法
/// <summary>
/// 获取本机所有的COM口
/// </summary>
/// <returns></returns>
public static string[] GetMachinePort()
{
return SerialPort.GetPortNames();
}
/// <summary>
/// 创建新串口实例,请检查COM是否占用,否则创建失败。
/// </summary>
/// <param name="para"></param>
/// <returns></returns>
public static SerialPort CreateSerialPortInstance(SerialPortParameter para)
{
SerialPort serial = new SerialPort();
serial.PortName = para.PortName;
serial.BaudRate = para.BaudRate;
serial.Parity = (Parity)para.Parity;
serial.DataBits=para.DataBits;
serial.ReceivedBytesThreshold = para.ReceivedBytesThreshold;
if (para.StopBits == 0)
{
//serial.StopBits =StopBits.None;
}
else
{
serial.StopBits = (StopBits)para.StopBits;
}
serial.Handshake=(Handshake)para.Handshake;
serial.ReadTimeout = para.ReadTimeout;
serial.WriteTimeout = para.WriteTimeout;
serial.Encoding = para.Encoding;
return serial;
}
public void Open()
{
lock (this.List.SyncRoot)
{
foreach (SerialPort item in this.List)
{
if (!item.IsOpen)
{
item.Open();
}
}
}
}
public void Open(string portName)
{
try
{
if (!this[portName].IsOpen)
{
this[portName].Open();
}
}
catch (Exception e)
{
//抛出
throw e;
}
}
public void Open(string[] portNameArray)
{
foreach (string item in portNameArray)
{
this.Open(item);
}
}
public void Close()
{
lock (this.List.SyncRoot)
{
foreach (SerialPort item in this.List)
{
if (item.IsOpen)
{
item.Close();
}
}
}
}
public void Close(string portName)
{
try
{
if (this[portName].IsOpen)
{
this[portName].Close();
}
}
catch (Exception e)
{
throw e;
}
}
public void Close(string[] portNameArray)
{
foreach (string item in portNameArray)
{
this.Close(item);
}
}
/// <summary>
/// 从串口读数据
/// </summary>
/// <returns></returns>
public string Read(string portName)
{
lock (this[portName])
{
try
{
string strRet = "";
while ((this[portName].IsOpen) && (this[portName].BytesToRead > 0))
{
byte[] buffer = new byte[this[portName].BytesToRead];
int iRead = this[portName].Read(buffer, 0, buffer.Length);
strRet += this[portName].Encoding.GetString(buffer);
}
return strRet;
}
catch
{
return "";
}
}
}
/// <summary>
/// 往串口写数据
/// </summary>
/// <param name="portName">COM口</param>
/// <param name="strWriteInfo">写入内容</param>
public void Write(string portName, string strWriteInfo)
{
lock (this[portName])
{
try
{
this[portName].Write(strWriteInfo);
}
catch (Exception er)
{
throw er;
}
}
}
/// <summary>
/// 往串口写数据
/// </summary>
/// <param name="portName">COM口</param>
/// <param name="byteWriteInfo">写入内容</param>
public void Write(string portName,byte[] byteWriteInfo)
{
lock (this[portName])
{
try
{
this[portName].Write(byteWriteInfo, 0, byteWriteInfo.Length);
}
catch (Exception er)
{
throw er;
}
}
}
#endregion
}
}