⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ddata.cs

📁 用C#写的USB数据采集程序
💻 CS
📖 第 1 页 / 共 2 页
字号:
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 + -