Csharp 多串口通信
顾名思义,多串口通信,普通的PC机一般只有一个串口,现在很多家用的PC都没有串口,那么问题来了,如何保证多串口呢?
有一种神器,MOXA CP-168U Series PCI bus
需要PCI插槽支持,现在市面上要找大主板才会有PCI。
OK,硬件准备妥当。当然我这个项目中还需要另外一件神器,红外感应器,暂且不表。
插入设备,装好驱动,你会在设备管理器中发现 serial board拓展出的8个port。Csharp有针对串口的控件:serialPort,每添加一个物理串口,就需要添加一个控件,操作如下:
1>.实例化串口并打开
serialPort.PortName = item; //串口名称
serialPort.BaudRate = 2400; //波特率
serialPort.DataBits = 8; //数据位
serialPort.Parity = Parity.Even; //校验位
serialPort.StopBits = StopBits.One; //停止位
serialPort.ReadTimeout = 3000; //读写超时控制在3秒内
serialPort.WriteTimeout = 3000;
//设置数据流控制;数据传输的握手协议
serialPort.Handshake = Handshake.None;
serialPort.ReceivedBytesThreshold = 1;
serialPort.RtsEnable = true;
if (!serialPort.IsOpen)
{
serialPort.Open();
}
2>.发送数据(byte)
byte[] ReadData = (byte)Function you need did serialPort.Write(ReadData, 0, ReadData.Length); serialPort.DataReceived += new SerialDataReceivedEventHandler(serialPort1_DataReceived);
//此处需要特别说明的是,很多人在debug的时候,串口接受回应的事件(serialPort1_DataReceived)没有被触发
//此时可使用串口调试工具,检查发送的值是否正确,一般情况都是因为命令错误,没有回应,导致DataReceived没有被触发
3>.接受回应并处理
public void serialPort1_DataReceived(object sender, SerialDataReceivedEventArgs e) { //结束符后,接收返回值 int by = serialPort.BytesToRead; byte[] rece = new byte[by]; serialPort.Read(rece, 0, by); //解析返回值 //dosomething }
如上所述,你只有一个串口需要操作是这样做可以,但是如果你有5个 8头的serial board需要处理时,你就不得不考虑这样做的效率了。那应该怎样呢??
针对多个串口,可以通过读取注册表获取PC的所有被激活的串口,然后遍历实例化,由于没有使用多线程,不用考虑线程之间的冲突,即使资源被释放,也会在3秒后触发下一个周期
/// <summary> /// 打开并设置所有的串口 /// </summary> private void OpenSettingAllSerialPort() { try { Microsoft.Win32.RegistryKey reg = Microsoft.Win32.Registry.LocalMachine; Microsoft.Win32.RegistryKey hardware = reg.OpenSubKey("HARDWARE"); Microsoft.Win32.RegistryKey dev = reg.OpenSubKey("DEVICEMAP"); Microsoft.Win32.RegistryKey siteKey = reg.OpenSubKey("SERIALCOMM"); //获取所有串口 string[] strPort = System.IO.Ports.SerialPort.GetPortNames(); //siteKey.GetValueNames(); if (ExcuteNum < 1) { foreach (string item in strPort) { serialPort.PortName = item; //串口名称 serialPort.BaudRate = 2400; //波特率 serialPort.DataBits = 8; //数据位 serialPort.Parity = Parity.Even; //校验位 serialPort.StopBits = StopBits.One; //停止位 serialPort.ReadTimeout = 3000; //读写超时控制在3秒内 serialPort.WriteTimeout = 3000; //设置数据流控制;数据传输的握手协议 serialPort.Handshake = Handshake.None; serialPort.ReceivedBytesThreshold = 1; serialPort.RtsEnable = true; if (!serialPort.IsOpen) { serialPort.Open(); } byte[] ReadData = devOpreation.Broadst_Addr(); serialPort.Write(ReadData, 0, ReadData.Length); serialPort.DataReceived += new SerialDataReceivedEventHandler(serialPort1_DataReceived); ExcuteNum++; } } else { byte[] ReadData = devOpreation.Broadst_Addr(); serialPort.Write(ReadData, 0, ReadData.Length); serialPort.DataReceived += new SerialDataReceivedEventHandler(serialPort1_DataReceived); } } catch (Exception ex) { MessageBox.Show( "串口未找到或被占用. " + ex.Message); } }
至此,你用很少的代码实现了多串口的实例化并打开,然后发送和接受处理利用同样的场景,问题得到解决。
到最后这样就是你看到的真实样子。
2015/03/17 TymonYang