215 lines
6.4 KiB
C#
215 lines
6.4 KiB
C#
|
||
using System;
|
||
using System.Collections.Concurrent;
|
||
using System.Collections.Generic;
|
||
using System.IO.Ports;
|
||
using System.Linq;
|
||
using System.Text;
|
||
using System.Threading;
|
||
using System.Threading.Tasks;
|
||
|
||
namespace LeatherApp.Utils
|
||
{
|
||
public class SSerialPort
|
||
{
|
||
private SerialPort _serialPort;
|
||
private readonly ConcurrentQueue<byte[]> _messageQueue;
|
||
private readonly EventWaitHandle _messageWaitHandle;
|
||
private int _receiveCount, _sendCount;
|
||
private readonly object _lock;
|
||
private int queueSize;
|
||
public int ReceiveCount
|
||
{
|
||
get => _receiveCount;
|
||
}
|
||
public int SendCount
|
||
{
|
||
get => _sendCount;
|
||
}
|
||
/// <summary>
|
||
///
|
||
/// </summary>
|
||
/// <param name="com"></param>
|
||
/// <param name="baud"></param>
|
||
/// <param name="size">队列最大容量</param>
|
||
public SSerialPort(string com, int baud,int size=-1)
|
||
{
|
||
// initialized
|
||
_lock = new object();
|
||
_receiveCount = 0;
|
||
_sendCount = 0;
|
||
_messageQueue = new ConcurrentQueue<byte[]>();
|
||
_messageWaitHandle = new EventWaitHandle(false, EventResetMode.AutoReset);
|
||
queueSize = size;
|
||
// Open Com
|
||
openCom(com.ToUpper(), baud);
|
||
|
||
// Receive byte
|
||
pushMessage();
|
||
}
|
||
|
||
private void openCom(string com, int baud)
|
||
{
|
||
// Open Com
|
||
_serialPort = new SerialPort(com, baud);
|
||
if (_serialPort.IsOpen) _serialPort.Close();
|
||
|
||
// Set the read / write timeouts
|
||
_serialPort.ReadTimeout = 500;
|
||
_serialPort.WriteTimeout = 500;
|
||
|
||
// Set read / write buffer Size,the default of value is 1MB
|
||
_serialPort.ReadBufferSize = 1024 * 1024;
|
||
_serialPort.WriteBufferSize = 1024 * 1024;
|
||
|
||
_serialPort.Open();
|
||
|
||
// Discard Buffer
|
||
_serialPort.DiscardInBuffer();
|
||
_serialPort.DiscardOutBuffer();
|
||
}
|
||
|
||
|
||
#region Static
|
||
/// <summary>
|
||
/// 获取当前计算机的串行端口名的数组
|
||
/// </summary>
|
||
/// <returns></returns>
|
||
public static string[] getPortNames()
|
||
{
|
||
return SerialPort.GetPortNames();
|
||
}
|
||
/// <summary>
|
||
/// 波特率
|
||
/// </summary>
|
||
/// <returns></returns>
|
||
public static List<string> getBaudrateList()
|
||
{
|
||
return new List<string>()
|
||
{
|
||
"300",
|
||
"600",
|
||
"1200",
|
||
"2400",
|
||
"4800",
|
||
"9600",
|
||
"19200",
|
||
"38400",
|
||
"57600",
|
||
"115200",
|
||
"230400",
|
||
"460800",
|
||
"921600"
|
||
};
|
||
}
|
||
#endregion
|
||
|
||
#region Receive
|
||
private void pushMessage()
|
||
{
|
||
_serialPort.DataReceived += (sender, e) =>
|
||
{
|
||
lock (_lock)
|
||
{
|
||
if (_serialPort.IsOpen == false) return;
|
||
int length = _serialPort.BytesToRead;
|
||
byte[] buffer = new byte[length];
|
||
int readLen = _serialPort.Read(buffer, 0, length);
|
||
API.OutputDebugString($"serialPort 缓存中长度:{length},实际读取长度:{readLen}.");
|
||
if (readLen > 0)
|
||
{
|
||
_receiveCount += length;
|
||
_messageQueue.Enqueue(buffer);
|
||
|
||
byte[] outObj;
|
||
while (queueSize > 0 && _messageQueue.Count > queueSize)
|
||
{
|
||
API.OutputDebugString($"serialPort 删除队列1项,队列中数量:{_messageQueue.Count},队列大小:{queueSize}");
|
||
_messageQueue.TryDequeue(out outObj);
|
||
}
|
||
_messageWaitHandle.Set();
|
||
}
|
||
}
|
||
};
|
||
}
|
||
|
||
/// <summary>
|
||
/// 获取串口接受到的内容
|
||
/// </summary>
|
||
/// <param name="millisecondsToTimeout">取消息的超时时间</param>
|
||
/// <returns>返回byte数组</returns>
|
||
public byte[] getMessage(int millisecondsToTimeout = -1)
|
||
{
|
||
if (_messageQueue.TryDequeue(out var message))
|
||
{
|
||
return message;
|
||
}
|
||
|
||
if (_messageWaitHandle.WaitOne(millisecondsToTimeout))
|
||
{
|
||
if (_messageQueue.TryDequeue(out message))
|
||
{
|
||
return message;
|
||
}
|
||
}
|
||
return default;
|
||
}
|
||
#endregion
|
||
|
||
|
||
#region Send
|
||
/// <summary>
|
||
/// 发送消息(byte数组)
|
||
/// </summary>
|
||
/// <param name="buffer"></param>
|
||
/// <param name="offset"></param>
|
||
/// <param name="count"></param>
|
||
public void send(byte[] buffer, int offset, int count)
|
||
{
|
||
lock (_lock)
|
||
{
|
||
_serialPort.Write(buffer, offset, count);
|
||
//_sendCount += (count - offset);
|
||
_sendCount += count;
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// 发送消息(字符串)
|
||
/// </summary>
|
||
/// <param name="encoding">字符串编码方式,具体方式见<see cref="Encoding"/></param>
|
||
/// <param name="message"></param>
|
||
public void send(Encoding encoding, string message)
|
||
{
|
||
lock (_lock)
|
||
{
|
||
var buffer = encoding.GetBytes(message);
|
||
_serialPort.Write(buffer, 0, buffer.Length);
|
||
_sendCount += buffer.Length;
|
||
}
|
||
}
|
||
#endregion
|
||
|
||
/// <summary>
|
||
/// 清空接受/发送总数统计
|
||
/// </summary>
|
||
public void clearCount()
|
||
{
|
||
lock (_lock)
|
||
{
|
||
_sendCount = 0;
|
||
_receiveCount = 0;
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// 关闭串口
|
||
/// </summary>
|
||
public void close()
|
||
{
|
||
_serialPort.Close();
|
||
}
|
||
}
|
||
|
||
}
|