12,162
社区成员
发帖
与我相关
我的任务
分享
/// <summary>
/// 收发串口数据
/// </summary>
/// <param name="sendData">发送数据</param>
/// <param name="portName">串口号</param>
/// <param name="bandRate">波特率</param>
/// <param name="dataBit">数据位</param>
/// <param name="stopBit">停止位</param>
/// <param name="checkBit">校验位</param>
/// <param name="timeOut">超时时间</param>
/// <returns></returns>
[WebMethod]
public string GetSeriesPortData(string sendData, string portName, int bandRate, int dataBit, int stopBit, int checkBit, int timeOut,int receiveOn)
{
#region 变量
int n = 0;
PortControlHelper pchSend;
//PortControlHelper pchReceive;
pchSend = new PortControlHelper();
//pchReceive = new PortControlHelper();
////虚拟串口自我接收
//string CO = "COM2";
#endregion
#region 执行步骤
try
{
//if (pchSend.PortState)
//{
// pchSend.ClosePort();
// pchReceive.ClosePort();
//}
//pchReceive.OnComReceiveDataHandler += new PortControlHelper.ComReceiveDataHandler(ComReceiveData);
pchSend.OnComReceiveDataHandler += new PortControlHelper.ComReceiveDataHandler(ComReceiveData);
pchSend.OpenPort(portName, bandRate, dataBit, stopBit, checkBit, timeOut,receiveOn);
//pchReceive.OpenPort(CO, bandRate, dataBit, stopBit, checkBit, timeOut);
pchSend.SendData(sendData);
while (true)
{
//n = n + 1;
//if (n > 50000) break;
if (seriesData != null)
{
break;
}
}
}
catch
{
throw;
}
finally
{
//pchReceive.ClosePort();
pchSend.ClosePort();
}
return seriesData;
#endregion
}
/// <summary>
/// 接收到的数据,写入文本框内
/// </summary>
/// <param name="data"></param>
private void ComReceiveData(string data)
{
seriesData = data;
}
using System;
using System.Collections.Generic;
using System.IO.Ports;
using System.Linq;
using System.Text;
using System.Web;
namespace AcquisitonWebService
{
public class PortControlHelper
{
#region 字段/属性/委托
/// <summary>
/// 串行端口对象
/// </summary>
private SerialPort sp;
/// <summary>
/// 串口接收数据委托
/// </summary>
public delegate void ComReceiveDataHandler(string data);
public ComReceiveDataHandler OnComReceiveDataHandler = null;
/// <summary>
/// 端口名称数组
/// </summary>
//public string[] PortNameArr { get; set; }
/// <summary>
/// 串口通信开启状态
/// </summary>
public bool PortState { get; set; } = false;
/// <summary>
/// 编码类型
/// </summary>
public Encoding EncodingType { get; set; } = Encoding.UTF8;
#endregion
#region 方法
public PortControlHelper()
{
//PortNameArr = SerialPort.GetPortNames();
sp = new SerialPort();
//默认接收一个数据帧就会触发,DataReceived事件,实际上由于其他原因并不会。
sp.DataReceived += new SerialDataReceivedEventHandler(DataReceived);
}
/// <summary>
/// 打开端口
/// </summary>
/// <param name="portName">端口名称</param>
/// <param name="boudRate">波特率</param>
/// <param name="dataBit">数据位</param>
/// <param name="stopBit">停止位</param>
/// <param name="timeout">超时时间</param>
public void OpenPort(string portName, int boudRate, int dataBit, int stopBit, int checkBit, int timeout,int receiveOn)
{
try
{
sp.PortName = portName;
sp.BaudRate = boudRate;
sp.DataBits = dataBit;
sp.StopBits = (StopBits)stopBit;
//判断是什么校验
switch (checkBit)
{
case 0:
sp.Parity = Parity.None;
break;
case 1:
sp.Parity = Parity.Odd;
break;
case 2:
sp.Parity = Parity.Even;
break;
}
sp.ReadTimeout = timeout;
sp.ReceivedBytesThreshold = receiveOn;
sp.Open();
PortState = true;
}
catch (Exception e)
{
throw e;
}
}
/// <summary>
/// 关闭端口
/// </summary>
public void ClosePort()
{
try
{
sp.Close();
PortState = false;
}
catch (Exception e)
{
throw e;
}
}
/// <summary>
/// 发送数据
/// </summary>
/// <param name="sendData"></param>
public void SendData(string sendData)
{
try
{
sp.Encoding = EncodingType;
sp.Write(sendData+"\r\n");
}
catch (Exception e)
{
throw e;
}
}
/// <summary>
/// 接收数据回调用
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void DataReceived(object sender, SerialDataReceivedEventArgs e)
{
byte[] buffer = new byte[sp.BytesToRead];
sp.Read(buffer, 0, buffer.Length);
string str = EncodingType.GetString(buffer);
if (OnComReceiveDataHandler != null)
{
OnComReceiveDataHandler(str);
}
}
#endregion
}
}
Thread.Sleep(100);
这类代码。实际上交互通讯程序应该是事件驱动的,有了接收数据的事件才应该继续委托执行后续动做。但是假设是初学者、不会从头开始改变设计思路,那么这个地方也应该使用信号量来 WaitOne,然后接收数据事件发生的时候使用 Set 来让 Wait 结束。而不是使用什么 Thread.Sleep。使用 Sleep 的话,这个 100 就是胡乱写的,数值高了就造成通讯一卡一卡地效率降低百倍,数值低了就把机器搞死了。实际上 Sleep 本身在这里就是一些博客上才会出现的坑人语句了,因为这种东西最符合什么技术都不想费脑子理解的那些人的习惯。 while (true)
{
//n = n + 1;
//if (n > 50000) break;
if (seriesData != null)
{
break;
}
}