之前的文章中对示波器波形文件进行了解析,见参考链接示波器波形数据文件(trc,dat文件)解析。其实,我们对trc或者dat文件的解析主要是通过上位机,对数据进行我们想要的处理,因此,本文我们将一下用C#实现文件的解析。
之前的文章中,我们知道,trc文件可以用十六进制的格式打开,然后进行每个Byte的解析。dat文件可以通过文件流的形式打开,即ASCII的形式打开。因此,对于trc文件我们主要使用BinaryReader来实现解析,dat文件通过StreamReader打开即可。
//打开trc文件
FileStream bin_stream = newFileStream(file_name,FileMode.Open);
BinaryReader bin_reader =new BinaryReader(bin_stream);
//打开dat文件StreamReader read_file =new StreamReader(file_name);
对于十六进制文件格式的操作,可以具体参考我之前的文章。C#学习随笔—操作BIN文件(读,写,替代),注意:BIN文件的操作实质上也是十六进制码的操作。我这里大概列一下简单的读操作:
bin_reader.ReadBytes(346)//读取346个bytes
对于文本文件格式的操作,基本如下:
read_file.ReadLine();//读取一行String字符串
上面是比较基本的文件操作方法,我们本文不做过多叙述,只说我们会用到的。
然后在解析文件过程中,会用到byte[]转换为float型,byte[]转换为word(int16),byte[]转换为ASCII string,byte转换为ASCII。
BitConverter.ToUInt32(数组名,数组的开始的index);//byte[]转换为Uint32
BitConverter.ToInt16(数组名,数组的开始的index);//byte[]转换为Int16
BitConverter.ToSingle(数组名,数组开始的index);//byte[]转换为Float
Encoding.ASCII.GetString(数组名,数组开始的index,长度);//Byte[]转换为ASCII String字符
(char);//Byte转换为ASCII码,直接强制数据类型转换
然后我们要将数据类型显示到Winform的Chart图表中。
Chart图标的操作,我在这儿不做详细叙述,我这里也只是对数据的初步显示,不做炫酷的操作。效果图如下所示:
直接上源码:
usingSystem;using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.IO;
namespace Cellwise_Debug_Tool
{
public partial class SoftwareToolWindows : Form
{
//TRC 文件各个数据类型占用字节数
public const int LONG_LENGTH = 4;
public const int WORD_LENGTH = 2;
public const int FLOAT_LENGTH = 4;
public const intDOUBLE_LENGTH =8;
public const int BYTE_LENGTH = 1;
//Chart控件中显示的最大数据点数
public const int MAX_SHOW_LENGTH = 100000;
//trc文件的数据解析,具体可以参考上一篇文章
public enum trc_file_offset
{
KEY_WORD_OFFSET = 0x000B,
TEMPLETE_VERSION_OFFSET =0x001B,
DATA_TYPE_OFFSET= 0x002B,
DATA_HIGH_LOW_OFFSET = 0x002D,
WAVEDESC_LENGTH_OFFSET =0x002F,
USERTEXT_LENGTH_OFFSET = 0x0033,
TRIGTIME_LENGTH_OFFSET = 0x003B,
RISTIME_LENGTH_OFFSET =0x003F,
DATA_ARRAY_1_OFFSET = 0x0047,
DATA_ARRAY_2_OFFSET = 0x004B,
INSTRUMENT_NAME_OFFSET =0x0057,
INSTRUMENT_NUM_OFFSET = 0x0067,
CHANNEL_LABEL_OFFSET = 0x006B,
DATA_ARRAY_1_POINT_LENGTH_OFFSET =0x007F,
OSC_DISPLAY_POINT_LENGTH_OFFSET = 0x0083,
FIRST_VALID_INDEX_OFFSET =0x0087,
LAST_VALID_INDEX_OFFSET = 0x008B,
VERTICAL_GAIN_OFFSET = 0x00A7,
VERTICAL_OFFSET_OFFSET =0x00AB,
HORIZ_INTERVAL_OFFSET = 0x00BB,
VERTICAL_UNIT_OFFSET = 0x00CF,
HORIZ_UNIT_OFFSET =0x00FF,
TIMEBASE_OFFSET = 0x014F,
PROBE_RES_SETTING_OFFSET = 0x0151,
VERTICAL_DIV_OFFSET =0x0157,
BANDLIMIT_ENABLE_OFFSET = 0x0159,
CHANNEL_NUM_OFFSET = 0x0163,
MAX_WAVEDESC_OFFSET =0x164,
};
public enummessage_info
{
FORMAT_ERROR,
STRING_OUT,
}public struct software_status_t
{
public byte[] header_byte;
public byte point_type;//00-->Byte,01-->Word
public UInt32 user_text_length;
public UInt32 trig_time_length;
public UInt32 ris_time_length;
public UInt32 point_length;
public float horiz_interval;
public byte horiz_unit;
public byte vertical_unit;
public float vertical_gain;
public float vertical_offset;
publicDataTable data_value;
}
software_status_t software_status;public SoftwareToolWindows()
{
InitializeComponent();
app_init();
}
//用户配置初始化
private void app_init()
{
software_status.header_byte = new byte[512];
ChartInit();
}
//Chart控件初始化
private void ChartInit()
{
#region SetChartPropertyWaveform.BackColor = Color.White;
Waveform.BackGradientStyle = System.Windows.Forms.DataVisualization.Charting.GradientStyle.None;
Waveform.BorderlineColor = Color.Black;
Waveform.BorderlineDashStyle = System.Windows.Forms.DataVisualization.Charting.ChartDashStyle.Solid;
Waveform.BorderlineWidth =1;
Waveform.BorderSkin.SkinStyle = System.Windows.Forms.DataVisualization.Charting.BorderSkinStyle.None;#endregion
#regionSetTitleProperty
System.Windows.Forms.DataVisualization.Charting.Title title = newSystem.Windows.Forms.DataVisualization.Charting.Title();
title.Text ="Waveform";
title.Font = new Font("Times New Roman",10, FontStyle.Regular);
title.Alignment = ContentAlignment.TopCenter;
title.TextStyle = System.Windows.Forms.DataVisualization.Charting.TextStyle.Default;
Waveform.Titles.Add(title);#endregion
#region SetChartAreaProperty
//handle in the Form
#endregion
#region SetLegandProperty
//handle in the Form
#endregion
}
//Trc Dat File 对话框处理函数
private void FileBrowse_Click(object sender, EventArgs e){
OpenFileDialog open_file =new OpenFileDialog();
open_file.Filter = "波形文件|*.trc|数据文件|*.dat";//只需要trc文件或者dat文件
if (open_file.ShowDialog() == DialogResult.OK)
{
FilePath.Text = open_file.FileName;
if (open_file.FilterIndex == 1)//波形数据文件 .trc文件{
trc_file_convert_to_data(open_file.FileName,Waveform);
}else if(open_file.FilterIndex == 2)//波形数据文件 .dat{
dat_file_convert_to_data(open_file.FileName, Waveform);
}
}
}//trc文件解析函数
//file_name trc文件路径
//Chart Chart控件,trc文件数据输出至Chart控件
private void trc_file_convert_to_data(stringfile_name,System.Windows.Forms.DataVisualization.Charting.Chart dataChart)
{
FileStream bin_stream = newFileStream(file_name,FileMode.Open);
BinaryReader bin_reader =new BinaryReader(bin_stream);
try{
software_status.header_byte = bin_reader.ReadBytes((int)trc_file_offset.MAX_WAVEDESC_OFFSET+1);
stringtrc_file_log = System.Text.Encoding.ASCII.GetString(software_status.header_byte,(int)trc_file_offset.KEY_WORD_OFFSET,8);
if (trc_file_log == "WAVEDESC")
{
message_info_output(false, message_info.STRING_OUT, "FILE LOG: WAVEDESC");
stringtrc_file_version = System.Text.Encoding.ASCII.GetString(software_status.header_byte, (int)trc_file_offset.TEMPLETE_VERSION_OFFSET,10);
if (trc_file_version == "LECROY_2_3")
{
message_info_output(false, message_info.STRING_OUT,"FILE Version: Lecroy_2_3");
message_info_output(false, message_info.STRING_OUT,"INSTRUMENT NAME: "+Encoding.ASCII.GetString(software_status.header_byte, (int)trc_file_offset.INSTRUMENT_NAME_OFFSET,14));
message_info_output(false, message_info.STRING_OUT, "INSTRUMENT NUMBER: " + (BitConverter.ToUInt32(software_status.header_byte,(int)trc_file_offset.INSTRUMENT_NUM_OFFSET)).ToString());
software_status.point_length = BitConverter.ToUInt32(software_status.header_byte, (int)trc_file_offset.DATA_ARRAY_1_POINT_LENGTH_OFFSET);
software_status.horiz_interval = BitConverter.ToSingle(software_status.header_byte, (int)trc_file_offset.HORIZ_INTERVAL_OFFSET);
software_status.horiz_unit = software_status.header_byte[(int)trc_file_offset.HORIZ_UNIT_OFFSET];
software_status.vertical_unit = software_status.header_byte[(int)trc_file_offset.VERTICAL_OFFSET_OFFSET];
software_status.vertical_gain = BitConverter.ToSingle(software_status.header_byte, (int)trc_file_offset.VERTICAL_GAIN_OFFSET);
software_status.vertical_offset = BitConverter.ToSingle(software_status.header_byte, (int)trc_file_offset.VERTICAL_OFFSET_OFFSET);
message_info_output(false, message_info.STRING_OUT,"DATA POINT LENGTH: "+ software_status.point_length.ToString());
message_info_output(false, message_info.STRING_OUT, "HORIZ INTERVAL: "+ software_status.horiz_interval.ToString("F15")+((char)software_status.horiz_unit).ToString());
software_status.user_text_length = BitConverter.ToUInt32(software_status.header_byte, (int)trc_file_offset.USERTEXT_LENGTH_OFFSET);
software_status.trig_time_length = BitConverter.ToUInt32(software_status.header_byte, (int)trc_file_offset.TRIGTIME_LENGTH_OFFSET);
software_status.ris_time_length = BitConverter.ToUInt32(software_status.header_byte, (int)trc_file_offset.RISTIME_LENGTH_OFFSET);
if(software_status.user_text_length >0)
{
bin_reader.ReadBytes((int)software_status.user_text_length);
}
else{
message_info_output(false, message_info.STRING_OUT, "USER_TEXT AREA is Empty!");
}
if(software_status.trig_time_length >0)
{
bin_reader.ReadBytes((int)software_status.trig_time_length);
}
else{
message_info_output(false, message_info.STRING_OUT, "TRIG_TIME AREA is Empty!");
}
if(software_status.ris_time_length >0)
{
bin_reader.ReadBytes((int)software_status.ris_time_length);
}else
{
message_info_output(false, message_info.STRING_OUT, "RIS_TIME AREA is Empty!");
}
software_status.point_type = software_status.header_byte[(int)trc_file_offset.DATA_TYPE_OFFSET];
software_status.data_value =new DataTable();
software_status.data_value.Columns.Add("Times", typeof(float));
software_status.data_value.Columns.Add("Value", typeof(float));
DataRow row_value;int y_value=0;
byte[] y_value_byte = new byte[2];
float finial_value;
for (int temp = 0; (temp < MAX_SHOW_LENGTH)&&(temp