读取出来的量的具体含义可以查阅力科官方有关 trace 的定义文件 LeCroyWaveformTemplate_2_3.pdf
使用方法:
1、用下面的类定义,声明一个 Trace 对象
2、用 Read 方法读取即可
3、用 ADCSamples2Voltage 方法提取波形数据(原始数据为 ADC 采样数值)
4、如需回写,需要先用 Voltage2ADCSamples 方法将已有的波形数据转换为 ADC 采样值,再用 Write 方法写入到新文件
Trace 类定义(文件头+数据段):
classdef Trace < handle
properties
HeadOffset = 11
HEADER = '#9020000350' %文件头,主要用于指示文件大小,数值为9e10+文件字节长度(不包括此文件头的11个字节)
DESCRIPTOR_NAME = 'WAVEDESC' %解释器, 16B, s, 0-15
TEMPLATE_NAME = 'LECROY_2_3' %模板名, 16B, s, 16-31
COMM_TYPE = 1 %2B, enum, 32-33
COMM_ORDER = 1 %2B, enum, 34-35 小端
%各块长度(字节)
WAVE_DESCRIPTOR = 346 %文件头WAVEDSEC块的长度,4B, long, 36-39
USER_TEXT = 0 %用户文本块的长度,4B, long, 40-43
RES_DESC1 = 0 %保留,4B, long, 44-47
%各序列长度(字节)
TRIGTIME_ARRAY = 0 %4B,long,48-51
RIS_TIME_ARRAY = 0 %4B,long,52-55
RES_ARRAY_1 = 0 %保留,4B,long,56-59
WAVE_ARRAY_1 = 20000004 %4B,long,60-63,数据列1
WAVE_ARRAY_2 = 0 %4B,long,64-67,数据列2
RES_ARRAY_2 = 0 %4B,long,68-71,保留2
RES_ARRAY_3 = 0 %4B,long,72-75,保留3
%仪器信息
INSTRUMENT_NAME = 'LECROYWaveRunner'%16B,s,76-91
INSTRUMENT_NUMBER %4B, long, 92-95 仪器编号
TRACE_LABEL = repmat(char(0),1,16) %16B, s, 96-111
RESERVED1 = 10000002 %4B, 保留, 112-115,数值等于WAVE_ARRAY_COUNT,原因我也不知道
%波形信息
WAVE_ARRAY_COUNT= 10000002 %数据长度,4B, long, 116-119
PNTS_PER_SCREEN = 10000000 %屏幕上的数据长度,等于上面的值-2, 4B, long, 120-123
FIRST_VALID_PNT = 0 %需要跳过的数据点数,置0即可,4B, long, 124-127
LAST_VALID_PNT = 10000001 %WAVE_ARRAY_COUNT-1,4B, long, 128-131
FIRST_POINT = 0 %第一个数据点,填0即可,4B,132-135
SPARSING_FACTOR = 1 %填1即可,4B ,136-139
SEGMENT_INDEX = 0 %数据段索引,填0即可,4B, 140-143
SUBARRAY_COUNT = 1 %获取到的数据段数,4B, 144-147
SWEEPS_PER_ACQ = 1 %Average或Extrema专用,否则填1, 4B, 148-151
POINTS_PER_PAIR = 0 %2B, 152-153,峰值检测专用,这两个不用改
PAIR_OFFSET = 0 %2B, 154-155
VERTICAL_GAIN = 1.373120030621067e-04 %4B f 156-159 垂直轴增益 原数据=数据*增益+偏移
VERTICAL_OFFSET = 0 %4B f 160-163 垂直轴偏移
MAX_VALUE = 28875 %波形图网格的最大最小值, 4B f 164-167
MIN_VALUE = -29131 %4B f 168-171
NOMINAL_BITS = 8 %2B 172-173 不用改
NOM_SUBARRAY_COUNT = 1 %2B 174-175
HORIZ_INTERVAL = 1e-10 %4B f 176-179 采样点间隔
HORIZ_OFFSET = -5e-4 %8B double 180-187
PIXEL_OFFSET = -5e-4 %8B d 188-195
VERTUNIT = ['V', repmat(char(0),1,47)] %196-243 单位定义, 48B
HORUNIT = ['S', repmat(char(0),1,47)] %244-291 单位定义, 48B
HORIZ_UNCERTAINTY = 1e-12 %4B f 292-295 不确定性 单位为秒
TRIGGER_TIME %24B f 296-311触发时间戳
ACQ_DURATION = 0 %4B f 312-315
RECORD_TYPE = 0 %2B 316-317 波形类型,一般填0即可
PROCESSING_DONE = 0 %2B 318-319
RESERVED5 = 0 %2B 320-321
RIS_SWEEPS = 1 %2B 322-323
TIMEBASE = 24 %2B 324-325 水平轴栅格时长
VERT_COUPLING = 0 %2B 326-327 耦合方式
PROBE_ATT = 1 %4B f 328-331 探针衰减
FIXED_VERT_GAIN = 18 %2B 332-333 垂直轴固定增益
BANDWIDTH_LIMIT = 0 %2B 334-335 带宽显示,填0即可
VERTICAL_VERNIER= 1 %4B f 336-339
ACQ_VERT_OFFSET = 0 %4B f 340-343
WAVE_SOURCE = -1 %2B 344-345 波形通道
%用户文本块
TEXT %视上面定义的长度而定
%TRIGTIME
TRIGGER_T %8B f 原名结尾是TIME,但与前面定义重复,故改为T
TRIGGER_OFFSET %8B f
%RISTIME
RIS_OFFSET %8B f
%DATA_ARRAY_1
DATA_ARRAY_1
%DATA_ARRAT_2
DATA_ARRAY_2
%SIMPLE
SIMPLE
%DUAL
DUAL
end
methods
function self = Trace()
return;
end
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function Read(self,fn)
fid=fopen(fn,'r');
if fid==-1
fprintf('ERROR: file not found: %s\n', fn);
return;
end
data = fread(fid,50);
self.HeadOffset = strfind(char(data(1:50)'), self.DESCRIPTOR_NAME) - 1; %找到文件头并返回偏移量
fseek(fid, self.HeadOffset+34, 'bof'); %指针定位到指定项
self.COMM_ORDER = fread(fid,1,'int16');
fclose(fid);
if self.COMM_ORDER %根据文件数据格式重新读入
fid = fopen(fn,'r','ieee-le'); % LOFIRST ,小端数据
else
fid = fopen(fn,'r','ieee-be'); % HIFIRST ,大端数据
end
fseek(fid, 0 ,'bof');
self.HEADER = ReadStringN(fid, 0, 11);
templateName = ReadString(fid, self.HeadOffset+16);
if ~strcmp( deblank(templateName), self.TEMPLATE_NAME)
error('Unsupported Template');
end
%开始读入文件信息
self.COMM_TYPE = ReadWord(fid, self.HeadOffset+32);
self.WAVE_DESCRIPTOR = ReadLong(fid, self.HeadOffset+36);
self.USER_TEXT = ReadLong(fid, self.HeadOffset+40);
self.RES_DESC1 = ReadLong(fid, self.HeadOffset+44);
self.TRIGTIME_ARRAY = ReadLong(fid, self.HeadOffset+48);
self.RIS_TIME_ARRAY = ReadLong(fid, self.HeadOffset+52);
self.RES_ARRAY_1 = ReadLong(fid, self.HeadOffset+56);
self.WAVE_ARRAY_1 = ReadLong(fid, self.HeadOffset+60);
self.WAVE_ARRAY_2 = ReadLong(fid, self.HeadOffset+64);
self.RES_ARRAY_2 = ReadLong(fid, self.HeadOffset+68);
self.RES_ARRAY_3 = ReadLong(fid, self.HeadOffset+72);
%开始读入仪器信息
self.INSTRUMENT_NAME = ReadString(fid, self.HeadOffset+76);
self.INSTRUMENT_NUMBER = ReadLong(fid, self.HeadOffset+92);
self.TRACE_LABEL = ReadString(fid, self.HeadOffset+96);
self.RESERVED1 = ReadLong(fid, self.HeadOffset+112);
%开始读入波形信息
self.WAVE_ARRAY_COUNT = ReadLong(fid, self.HeadOffset+116);
self.PNTS_PER_SCREEN = ReadLong(fid, self.HeadOffset+120);
self.FIRST_VALID_PNT = ReadLong(fid, self.HeadOffset+124);
self.LAST_VALID_PNT = ReadLong(fid, self.HeadOffset+128);
self.FIRST_POINT = ReadLong(fid, self.HeadOffset+132);
self.SPARSING_FACTOR = ReadLong(fid, self.HeadOffset+136);
self.SEGMENT_INDEX = ReadLong(fid, self.HeadOffset+140);
self.SUBARRAY_COUNT = ReadLong(fid, self.HeadOffset+144);
self.SWEEPS_PER_ACQ = ReadLong(fid, self.HeadOffset+148);
self.POINTS_PER_PAIR = ReadWord(fid, self.HeadOffset+152);
self.PAIR_OFFSET = ReadWord(fid, self.HeadOffset+154);
self.VERTICAL_GAIN = ReadFloat(fid, self.HeadOffset+156);
self.VERTICAL_OFFSET = ReadFloat(fid, self.HeadOffset+160);
self.MAX_VALUE = ReadFloat(fid, self.HeadOffset+164);
self.MIN_VALUE = ReadFloat(fid, self.HeadOffset+168);
self.NOMINAL_BITS = ReadWord(fid, self.HeadOffset+172);
self.NOM_SUBARRAY_COUNT = ReadWord(fid, self.HeadOffset+174);
self.HORIZ_INTERVAL = ReadFloat(fid, self.HeadOffset+176);
self.HORIZ_OFFSET = ReadDouble(fid, self.HeadOffset+180);
self.PIXEL_OFFSET = ReadDouble(fid, self.HeadOffset+188);
self.VERTUNIT = ReadStringN(fid, self.HeadOffset+196, 48);
self.HORUNIT = ReadStringN(fid, self.HeadOffset+244, 48);
self.HORIZ_UNCERTAINTY = ReadFloat(fid, self.HeadOffset+292);
self.TRIGGER_TIME = ReadTimestamp(fid,self.HeadOffset+296);
self.ACQ_DURATION = ReadLong(fid, self.HeadOffset+312);
self.RECORD_TYPE = ReadWord(fid, self.HeadOffset+316);
self.PROCESSING_DONE = ReadWord(fid, self.HeadOffset+318);
self.RESERVED5 = ReadWord(fid, self.HeadOffset+320);
self.RIS_SWEEPS = ReadWord(fid, self.HeadOffset+322);
self.TIMEBASE = ReadWord(fid, self.HeadOffset+324);
self.VERT_COUPLING = ReadWord(fid, self.HeadOffset+326);
self.PROBE_ATT = ReadFloat(fid, self.HeadOffset+328);
self.FIXED_VERT_GAIN = ReadWord(fid, self.HeadOffset+332);
self.BANDWIDTH_LIMIT = ReadWord(fid, self.HeadOffset+334);
self.VERTICAL_VERNIER = ReadFloat(fid, self.HeadOffset+336);
self.ACQ_VERT_OFFSET = ReadFloat(fid, self.HeadOffset+340);
self.WAVE_SOURCE = ReadWord(fid, self.HeadOffset+344);
%开始读入数据
self.TEXT = ReadStringN(fid, self.HeadOffset+346, self.USER_TEXT);
if self.RECORD_TYPE == 0 %single sweep
fseek(fid, self.HeadOffset + self.WAVE_DESCRIPTOR + self.USER_TEXT, 'bof');
if self.COMM_TYPE %2B
self.DATA_ARRAY_1 = fread(fid, self.WAVE_ARRAY_1, 'int16');
else %1B
self.DATA_ARRAY_1 = fread(fid, self.WAVE_ARRAY_1, 'int8');
end
else
error('Unsupported Record Type');
end
fclose(fid);
end
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function Write(self,fn,wvfm)
self.Voltage2ADCSamples(wvfm); %转换数据
if self.COMM_ORDER
fid = fopen(fn,'w','ieee-le');
else
fid = fopen(fn,'w','ieee-be');
end
fseek(fid,0,'bof');
self.HEADER = strcat('#', num2str( 9000000000 + self.WAVE_DESCRIPTOR + self.WAVE_ARRAY_1 ));
fwrite(fid, self.HEADER, 'char*1');
fwrite(fid, self.DESCRIPTOR_NAME,'char*1');
fwrite(fid, repmat(char(0),1,8),'char*1'); %补\0
fwrite(fid, self.TEMPLATE_NAME,'char*1');
fwrite(fid, repmat(char(0),1,6),'char*1');
fwrite(fid, self.COMM_TYPE, 'int16');
fwrite(fid, self.COMM_ORDER, 'int16');
fwrite(fid, self.WAVE_DESCRIPTOR, 'int32');
fwrite(fid, self.USER_TEXT, 'int32');
fwrite(fid, self.RES_DESC1, 'int32');
fwrite(fid, self.TRIGTIME_ARRAY, 'int32');
fwrite(fid, self.RIS_TIME_ARRAY, 'int32');
fwrite(fid, self.RES_ARRAY_1, 'int32');
fwrite(fid, self.WAVE_ARRAY_1, 'int32');
fwrite(fid, self.WAVE_ARRAY_2, 'int32');
fwrite(fid, self.RES_ARRAY_2, 'int32');
fwrite(fid, self.RES_ARRAY_3, 'int32');
fwrite(fid, self.INSTRUMENT_NAME, 'char*1');
fwrite(fid, self.INSTRUMENT_NUMBER, 'int32');
fwrite(fid, self.TRACE_LABEL, 'char*1');
fwrite(fid, self.RESERVED1, 'int32');
fwrite(fid, self.WAVE_ARRAY_COUNT, 'int32');
fwrite(fid, self.PNTS_PER_SCREEN, 'int32');
fwrite(fid, self.FIRST_VALID_PNT, 'int32');
fwrite(fid, self.LAST_VALID_PNT, 'int32');
fwrite(fid, self.FIRST_POINT, 'int32');
fwrite(fid, self.SPARSING_FACTOR, 'int32');
fwrite(fid, self.SEGMENT_INDEX, 'int32');
fwrite(fid, self.SUBARRAY_COUNT, 'int32');
fwrite(fid, self.SWEEPS_PER_ACQ, 'int32');
fwrite(fid, self.POINTS_PER_PAIR, 'int16');
fwrite(fid, self.PAIR_OFFSET, 'int16');
fwrite(fid, self.VERTICAL_GAIN, 'float');
fwrite(fid, self.VERTICAL_OFFSET, 'float');
fwrite(fid, self.MAX_VALUE, 'float');
fwrite(fid, self.MIN_VALUE, 'float');
fwrite(fid, self.NOMINAL_BITS, 'int16');
fwrite(fid, self.NOM_SUBARRAY_COUNT, 'int16');
fwrite(fid, self.HORIZ_INTERVAL, 'float');
fwrite(fid, self.HORIZ_OFFSET, 'double');
fwrite(fid, self.PIXEL_OFFSET, 'double');
fwrite(fid, self.VERTUNIT, 'char*1');
fwrite(fid, self.HORUNIT, 'char*1');
fwrite(fid, self.HORIZ_UNCERTAINTY, 'float');
timestamp = datetime('now');
fwrite(fid, second(timestamp), 'float64'); %时间戳
fwrite(fid, minute(timestamp), 'int8');
fwrite(fid, hour(timestamp), 'int8');
fwrite(fid, day(timestamp), 'int8');
fwrite(fid, month(timestamp), 'int8');
fwrite(fid, year(timestamp), 'int32');
fwrite(fid, self.ACQ_DURATION, 'int32');
fwrite(fid, self.RECORD_TYPE, 'int16');
fwrite(fid, self.PROCESSING_DONE, 'int16');
fwrite(fid, self.RESERVED5, 'int16');
fwrite(fid, self.RIS_SWEEPS, 'int16');
fwrite(fid, self.TIMEBASE, 'int16');
fwrite(fid, self.VERT_COUPLING, 'int16');
fwrite(fid, self.PROBE_ATT, 'float');
fwrite(fid, self.FIXED_VERT_GAIN, 'int16');
fwrite(fid, self.BANDWIDTH_LIMIT, 'int16');
fwrite(fid, self.VERTICAL_VERNIER, 'float');
fwrite(fid, self.ACQ_VERT_OFFSET, 'float');
fwrite(fid, self.WAVE_SOURCE, 'int16');
if self.USER_TEXT ~= 0
fwrite(fid, self.TEXT, 'char*1');
end
if self.COMM_ORDER
fwrite(fid, self.DATA_ARRAY_1, 'int16');
else
fwrite(fid, self.DATA_ARRAY_1, 'int8');
end
fclose(fid);
end
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% 恢复波形数据
function [x,y] = ADCSamples2Voltage(self)
y = self.VERTICAL_GAIN * self.DATA_ARRAY_1 - self.VERTICAL_OFFSET;
x = (0:self.WAVE_ARRAY_COUNT-1)'*self.HORIZ_INTERVAL + self.HORIZ_OFFSET;
end
% 将浮点数波形数据转换为ADC采样值,会覆盖对象中的数值
function Voltage2ADCSamples(self,wvfm)
self.DATA_ARRAY_1 = int16( (wvfm + self.VERTICAL_OFFSET) / self.VERTICAL_GAIN );
end
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
end
end
下面是一些辅助函数(为每个函数定义一个文件,并将所有文件放至同一目录即可正常运行):
% Read 8Bit signed Byte (not used)
function b=ReadByte(fid, Addr)
fseek(fid,Addr,'bof');
b=fread(fid,1,'int8');
end
% Read 16Bit signed Word
function w=ReadWord(fid, Addr)
fseek(fid,Addr,'bof');
w=fread(fid,1,'int16');
end
% Read 32Bit signed Long
function l=ReadLong(fid, Addr)
fseek(fid,Addr,'bof');
l=fread(fid,1,'int32');
end
% Read 32Bit IEEE Float
function f=ReadFloat(fid, Addr)
fseek(fid,Addr,'bof');
f=fread(fid,1,'float32');
end
% Read 64Bit IEEE Double
function d=ReadDouble(fid, Addr)
fseek(fid,Addr,'bof');
d=fread(fid,1,'float64');
end
% Read timestamp
function t=ReadTimestamp(fid, Addr)
fseek(fid,Addr,'bof');
t.Seconds = fread(fid,1,'float64');
t.Minutes = fread(fid,1,'int8');
t.Hours = fread(fid,1,'int8');
t.Days = fread(fid,1,'int8');
t.Months = fread(fid,1,'int8');
t.Year = fread(fid,1,'int16');
end
% Read string (up to 16 characters)
function s=ReadString(fid, Addr)
fseek(fid,Addr,'bof');
s=fgets(fid,16);
end
% Read string (N characters)
function s=ReadStringN(fid, Addr, n)
fseek(fid,Addr,'bof');
s=fgets(fid,n);
end
回写后的文件在力科的 WaveStudio 中的显示效果: