📄 ddata.cs
字号:
using System;
using System.Collections;
using System.Xml;
using System.IO;
using System.IO.Ports;
using System.Text;
namespace DAS
{
#region "多道数据类"
/// <summary>
/// 多道数据类
/// </summary>
public class DData
{
#region "属性"
#region "受保护的属性"
/// <summary>
/// 暂存串口数据
/// </summary>
private byte[] _tmpdata;
/// <summary>
/// 暂存转换后的数据
/// </summary>
private int[] _tmpvalue;
/// <summary>
/// 已接收的字节数
/// </summary>
private int _receivedbyte;
/// <summary>
/// 计数溢出查找表,一维数组,下标表示道址,元素是所在道址的最大计数
/// </summary>
private int[] _overflowtable;
/// <summary>
/// 数据坐标
/// </summary>
private bool _islinecoordinate;
/// <summary>
/// 存储多道数据,二维数组
/// </summary>
private int[][] _data;
/// <summary>
/// 全谱区最大计数
/// </summary>
private double _maxcount;
/// <summary>
/// 放大区最大计数
/// </summary>
private double _zmaxcount;
/// <summary>
/// 串口对象
/// </summary>
private SerialPort _serialport;
/// <summary>
/// 串口号
/// </summary>
private string _serialportname;
/// <summary>
/// 波特率
/// </summary>
private int _serialportbandrate;
/// <summary>
/// 是否停机
/// </summary>
private bool _stop;
/// <summary>
/// 数据读取索引
/// </summary>
private int _dataindex;
#endregion
#region "公共属性"
#region "串口号"
/// <summary>
/// 获取或设置串口号
/// </summary>
public string SerialPortName
{
get
{
return _serialportname;
}
set
{
if (_serialportname != value)
{
_serialportname = value;
//如果串口已经打开,先把其关闭再重新打开
if (_serialport.IsOpen)
{
_serialport.Close();
_serialport.PortName = _serialportname;
_serialport.Open();
}
else
{
_serialport.PortName = _serialportname;
}
}
}
}
#endregion
#region "波特率"
/// <summary>
/// 获取或设置波特率
/// </summary>
public int SerialPortBandRate
{
get
{
return _serialportbandrate;
}
set
{
if (_serialportbandrate != value)
{
_serialportbandrate = value;
//如果串口已经打开,先把其关闭再重新打开
if (_serialport.IsOpen)
{
_serialport.Close();
_serialport.BaudRate = _serialportbandrate;
_serialport.Open();
}
else
{
_serialport.BaudRate = _serialportbandrate;
}
}
}
}
#endregion
#region "全谱区最大计数"
/// <summary>
/// 获取或者设置全谱区最大计数
/// </summary>
public double MaxCount
{
get
{
return _maxcount;
}
set
{
_maxcount = value;
}
}
#endregion
#region "放大区最大计数"
/// <summary>
/// 获取或者设置放大区最大计数
/// </summary>
public double ZMaxCount
{
get
{
return _zmaxcount;
}
set
{
_zmaxcount = value;
}
}
#endregion
#region "时间点数"
/// <summary>
/// 获取时间点总数
/// </summary>
public int TimePoints
{
get
{
return _data.GetLength(0);
}
}
#endregion
#region "道数"
/// <summary>
/// 获取道数
/// </summary>
public int Channels
{
get
{
return _data[0].Length;
}
}
#endregion
#region "数据坐标"
/// <summary>
/// 获取或设置数据坐标
/// </summary>
public bool IsLineCoordinate
{
set
{
_islinecoordinate = value;
}
get
{
return _islinecoordinate;
}
}
#endregion
#endregion
#endregion
#region "构造函数"
/// <summary>
/// 构造函数
/// </summary>
/// <param name="timepoints">时间点数</param>
/// <param name="channels">道数</param>
/// <param name="maxcount">全谱区最大计数</param>
/// <param name="zmaxcount">放大区最大计数</param>
public DData(int timepoints, int channels, int maxcount, int zmaxcount)
{
//初始化数据结构
_data = new int[timepoints][];
for(int i = 0;i < timepoints;i++)
{
_data[i] = new int[channels];
}
//初始化溢出表
_overflowtable = new int[timepoints];
//初始化坐标
_islinecoordinate = true;
//初始化最大计数
_maxcount = maxcount;
_zmaxcount = zmaxcount;
//初始化串口
_serialportname = "COM1";
_serialportbandrate = 115200;
_serialport = new SerialPort(_serialportname, _serialportbandrate, Parity.None, 8, StopBits.One);
_serialport.ReadBufferSize = 8192;
_serialport.ReceivedBytesThreshold = 1;
_serialport.DataReceived += new SerialDataReceivedEventHandler(serialport_DataReceived);
_serialport.Open();
_tmpdata = new byte[channels * 4];
_tmpvalue = new int[channels];
_receivedbyte = 0;
_stop = true;
_dataindex = timepoints - 1;
}
#endregion
#region "方法"
#region "受保护的方法"
#region "释放资源"
/// <summary>
/// 释放资源
/// </summary>
~DData()
{
_serialport.Close();
_serialport.Dispose();
}
#endregion
#region "串口数据到达"
/// <summary>
/// 串口数据到达
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
protected void serialport_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
//读入数据
int n = _serialport.BytesToRead;
if (n <= 0)//如果没有数据要读取则返回
{
return;
}
try
{
//读取数据并增加已接收到的字节数
if (_receivedbyte + n < _tmpdata.Length)
{
_serialport.Read(_tmpdata, _receivedbyte, n);
}
else
{
_serialport.Read(_tmpdata, _receivedbyte, _tmpdata.Length - _receivedbyte);
}
_receivedbyte += n;
}
catch (TimeoutException)
{
return;
}
//如果已接收的字节数达到道数的8倍则保存数据(每8字节代表一道数据)
if (_receivedbyte >= _tmpdata.Length)
{
int tmpcount;
int max = 0;
for (int i = 0; i < _tmpvalue.Length; i++)
{
tmpcount = _tmpdata[4 * i] + 256 * _tmpdata[1 + 4 * i] + 65536 * _tmpdata[2 + 4 * i];
_tmpvalue[i] = tmpcount;
if (tmpcount > max)
{
max = tmpcount;
}
}
_serialport.DiscardInBuffer();
_receivedbyte = 0;
AddData(ref _tmpvalue, max);
if (_datareceived != null)//检查数据到达事件是否有预定
{
//产生数据到达事件
_datareceived(sender, new EventArgs());
}
if (_stop)
{
_serialport.Write("0");
}
else
{
_serialport.Write("1");
}
}
}
#endregion
#region "在指定的时间点下写入一个道数据"
/// <summary>
/// 在指定的时间点下写入一个道数据
/// </summary>
/// <param name="time">时间点</param>
/// <param name="channel">道址</param>
/// <param name="count">计数</param>
protected void SetData(int timePoint, int channel, int count)
{
if (timePoint < 0 || timePoint > _data.Length)
{
throw new Exception("timepoint overflow!");
}
_data[timePoint - 1][channel - 1] = count;
//根据写入的数据更新溢出表
if (count > _overflowtable[timePoint - 1])
{
_overflowtable[timePoint - 1] = count;
}
}
#endregion
#region "在最后使用的时间点增加一个道数据"
/// <summary>
/// 在最后使用的时间点增加一个道数据
/// </summary>
/// <param name="data">数据</param>
/// <param name="count">计数</param>
protected void AddData(ref int[] data, int count)
{
//时间点数据前移
for (int i = 0; i < _data.GetUpperBound(0); i++)
{
Array.Copy(_data[i + 1], _data[i], _data[0].Length);
_overflowtable[i] = _overflowtable[i + 1];
}
Array.Copy(data, _data[_data.GetUpperBound(0)], _data[0].Length);
//更新溢出表
_overflowtable[_overflowtable.GetUpperBound(0)] = count;
//更新数据读取索引
if (_dataindex > 0)
{
_dataindex--;
}
}
#endregion
#endregion
#region "公有方法"
#region "重新设置数据结构"
/// <summary>
/// 重新设置数据结构
/// </summary>
/// <param name="timepoints">时间点</param>
/// <param name="channels">道数</param>
public void Reset(int timePoints, int channels)
{
Stack s = new Stack();
Stack s1 = new Stack();
//保存原先数据
foreach (int[] n in _data)
{
s.Push(n);
}
foreach (int n1 in _overflowtable)
{
s1.Push(n1);
}
//设置数据结构
int mincn = Math.Min(channels, Channels);
_data = new int[timePoints][];
for (int i = 0; i < timePoints; i++)
{
_data[i] = new int[channels];
}
_overflowtable = new int[timePoints];
//复制原先数据
for (int i = timePoints - 1; i >= 0; i--)
{
if (s.Count > 0)
{
Array.Copy((int[])s.Pop(), _data[i], mincn);
_overflowtable[i] = (int)s1.Pop();
}
else
{
break;
}
}
_tmpdata = new byte[channels * 4];
_tmpvalue = new int[channels];
_receivedbyte = 0;
_dataindex = TimePoints;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -