?? 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
/// <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";
_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>
/// <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][];
{
_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 + -