技术文章

    逻辑分析仪,简易逻辑分析仪,虚拟逻辑分析仪,自制逻辑分析仪,PC逻辑分析仪,USB逻辑分析仪,数字逻辑分析仪

    摘要:MATLAB®是一个强有力的工具,可逻辑分析仪,用来快速分析从模数转换器(ADC)输出所捕获的数据。本应用笔记演示了如何使用MATLAB来突破逻辑分析仪存储深度的局限。描述并比较了三种数码拼接方式(基本,超前和反转)。并给出了三种方法所得的结果。

    介绍

    要评估一个高速模数转换器(ADC)的性能,就需要捕获其数字输出码,然后进行分析。逻辑分析仪的存储深度常常成为一个重要局限,妨碍系统捕获足够的数据点,以生成高分辨率FFT,或者精确的INL/DNL图。解决该问题的一个简单办法是使用某种数学工具,例如MATLAB® (图1),将多组数据连接起来。连接数据的一个缺点是,通常会在两组数据之间的连接点出现很大的不连续性。尽管不连续性对INL/DNL图的影响极小,但对高分辨率FFT而言,几乎是毁灭性的(图2)。

    图1. 连接后的数据在两组数据之间出现不连续。
    图1. 连接后的数据在两组数据之间出现不连续。

    图2. a) 捕获单组16384点数据并分析;b) 捕获两组8192点数据,连接,然后分析“拼接”技术。
    图2. a) 捕获单组16384点数据并分析;b) 捕获两组8192点数据,连接,然后分析“拼接”技术。

    有一种办法可以消除不连续性,就是在各组数据中寻找相同的点簇(一般为3到4个点),然后在这些点将两组数据“拼接”在一起(图3)。最简单的“拼接”方法是,记录下第一组数据中的最后四个点,然后在第二组数据里寻找相同的点簇。相同点簇出现在第二组数据中的位置称为“拼接点”。第二组数据中在拼接点之前的所有数据均被舍弃;第二组数据中的剩余部分与第一组数据合并。这种技术即所谓的基本数码拼接,实现起来非常简单,可以在MATLAB中非常快地运行。

    图3. 基本数码拼接后得到的最终“拼接”数组
    图3. 基本数码拼接后得到的最终“拼接”数组。

    采用基本拼接方法拼接数据时,有时必须丢掉第二组数据中的近一半,才能找到与第一组数据最后四个点相匹配的一簇点。作为另一种选择,丢掉第一组数据尾部的几个点,常常有助于找到更靠近第二组数据起点的拼接点(图4)。然而,通过丢掉第一组数据尾部、第二组数据头部的部分采样点来寻找匹配点的方法实现起来比较困难。这种处理被称为超前数码拼接。理想拼接点应该能够保留尽可能多的数据点,寻找这样的拼接点需要认真的考虑和一定的编程技巧。正确地实现之后,超前拼接技术通常能够得到两组小数组所含数据点总数的至少90%。

    图4. 采用超前拼接技术寻找理想拼接点,最终得到“拼接”后的数组。
    图4. 采用超前拼接技术寻找理想拼接点,最终得到“拼接”后的数组。

    将第二组数据(数组B)拼接到第一组数据(数组A)之前被称为反转拼接,这种方式有可能得到更大的拼接数组(图5)。但是,这种技术会使处理时间翻倍,因为必须在A领先于B和B领先于A两种情况下寻找拼接点。此外,当与其他拼接技术一起使用时,反转拼接方式所带来的好处通常很少。因此,对于较慢的PC,反转拼接技术大幅度增加的处理时间开销较之它所带来的好处而言并不太值。表1详细比较了这三种代码拼接方法。

    图5. 反转拼接的处理时间加倍,但常常收效甚微。
    图5. 反转拼接的处理时间加倍,但常常收效甚微。

    表1. 三种拼接技术对比*

    Stitch Technique Size of Final Data Set Description
    Data Set Numbers # of codes
    (averaged)
    % of two data sets
    (averaged)
    1 + 2 3 + 4 1 + 4
    Concatenate† N/A 16384 100% Will produce erroneous FFT; however, INL/DNL can be extracted from this data.
    Basic 11060 8192‡ 14384 11212 68.4% FFT is useable for calculating figures of merit.
    Reverse 11060 8192‡ 14384 11212 68.4%
    Advanced 13790 16046 16022 15286 93.3%
    Advanced
    +
    Reverse
    15427 16176 16022 15875 96.9%

    *采用上述拼接技术对两组8K (8192个)数据进行拼接。为确保准确性,采用四组8192点数据(分别编号为1至4)重复本测试。每组测试所合成的数据取平均后列于测试数据的右侧。
    † 直接连接总能得到100%的数据。
    ‡ 无法拼接数据。

    MATLAB函数说明

    本文后附的MATLAB代码(附录A和B中的StitchMatrices和FindStitchPoint)将上述论点结合到一个易于使用的函数中。这些函数可接受两组数据(MATLAB中的单列矩阵)和几个输入变量(用来选择超前/反转拼接功能)。FindStitchPoint例程用来确定拼接点在数组A和B中的偏移量。StitchMatrices例程则根据FindStitchPoint例程给出的偏移量对两组数据A和B进行舍弃和组合。同时,最终数据的拼接点被记录在PrevStitchBins数组中,以便于后续处理。当拼接多组数据时,PrevStitchBins可保存老的拼接点。

    结论

    拼接两组数据可以得到一组理想的结果。图6给出了三组8192点数据使用上述拼接技术拼接起来(使用5个拼接点)后的FFT图。所得的FFT几乎与前面图2a所示,基于16384个连续点所得结果相同。

    图6. 数码拼接后得到精确的FFT图。
    图6. 数码拼接后得到精确的FFT图。

    附录A:StitchMatrices例程(StitchMatrices.m)

    function [StitchedMatrix, StitchBins] = StitchMatrices(MatrixA, ...
       				MatrixB, StitchNumber, PrevStitchBins, ...
    				AdvCodeStitchEnabled, ReverseStitchEnabled);
    %Stitch Matrices Function
    %Revision 1.0
    %
    %By Donald Schelle, May 2005
    %Maxim Integrated Products
    %120 San Gabriel Drive
    %Sunnyvale, CA, 94086
    %
    %This function will take two matrices (MatrixA and MatrixB), find a 
    %given number (StitchNumber) of identical points in each and 
    %concatenate the two matrices into one.
    %
    %Inputs = MatrixA, MatrixB (Data Matrices)
    %		    StitchNumber (Number of points to match)
    %			 PrevStitchBins (Bins of Previous Stitches in MatrixA)
    %			 AdvStitchEnabled (0 = NO, 1 = YES)
    %			 ReverseStitchEnabled (0 = NO, 1 = YES)
    %Output = StitchedMatrix (MatrixA + MatrixB)
    %			 StitchBins (bins of StitchedMatrix where the two 
    %						    matrices were joined.)
    %
    %If the matrices can not be joined the function will output a NaN
    %for both the StitchedMatrix variable and the StitchBins variable
    %--------------------------------------------------------------------------
    
    %Check to see that there are at least TWO StitchNumber Points
    if StitchNumber < 2,
       %Requested less than 2 stitch points
       StitchedMatrix = NaN;
       StitchBins = NaN;
       return;
    end;
    
    %Calculate Size of MatrixA and MatrixB
    [SizeA, Junk] = size(MatrixA);
    [SizeB, Junk] = size(MatrixB);
    
    %Find the Stitch Points in MatrixB
    [NormalA, NormalB] = FindStitchPoint(MatrixA, MatrixB, ...
       					StitchNumber, AdvCodeStitchEnabled);
    %Calculate the size of the NormalStitched Matrix
    NormalStitchedSize = NormalA + SizeB - NormalB + 1;
                                
    %Check to see if the reverse function is enabled
    if ReverseStitchEnabled == 1,
       %Find Stitch Points for Reverse Matrices
       [ReverseB, ReverseA] = FindStitchPoint(MatrixB, MatrixA, ...
          					StitchNumber, AdvCodeStitchEnabled);
       %Calculate the size of the Revered Stitched Matrix
       ReverseStitchedSize = ReverseB + SizeA - ReverseA + 1;
    else
       %Set Values to defaults
       ReverseStitchedSize = NaN;		%MatrixB/A Stitch Size
       ReverseA = NaN;
       ReverseB = NaN;
    end;
    
    %Check to if it's possible to stitch two matrices
    if isnan(NormalStitchedSize) & isnan(ReverseStitchedSize) == 1,
       %The two matrices could not be stitched
       StitchedMatrix = NaN;
       StitchBins = NaN;
       return;
    end;
    
    %--------------------- Normal Matrix Stitching Routine ---------------
    if (NormalStitchedSize >= ReverseStitchedSize)| ...
       			isnan(ReverseStitchedSize) == 1,
       %Stitch MatrixB to the end of MatrixA
       StitchedMatrix = cat(1, MatrixA(1:NormalA), MatrixB(NormalB:SizeB));
       
       %Update Stitch Bins
       if isnan(PrevStitchBins) == 1,
          %There are no previous stitch bins
          StitchBins = [NormalA, NormalA + StitchNumber - 1];
       else
          %There are previous stitch bins
          %Check for Snipped Stitches
          [SizeStitchBins, Junk] = size(PrevStitchBins);
          
          while (PrevStitchBins(SizeStitchBins, 2) > (NormalA - 1)),
             %Second Bin is snipped from matrix. Check if first bin is snipped.
             if (PrevStitchBins(SizeStitchBins, 1) > (NormalA - 1)),
                %First Bin is snipped too. Delete Bin Pair
                PrevStitchBins = PrevStitchBins(1:(SizeStitchBins-1),:);
             else
                %First Bin is not snipped but second bin is snipped
                %Shrink Stitch Size
                PrevStitchBins(SizeStitchBins, 2) = NormalA - 1;
             end;
             
             %Calculate size of new PrevStitchBin Matrix
             [SizeStitchBins, Junk] = size(PrevStitchBins);
          end;
                   
          %Insert New StitchBins      
          [SizeStitchBins, Junk] = size(PrevStitchBins);
          StitchBins = PrevStitchBins;
          StitchBins(SizeStitchBins + 1, :) = ...
          [NormalA, NormalA + StitchNumber - 1];
          
          %Check to see if the last two stitches need to be combined
          [SizeStitchBins, Junk] = size(StitchBins);
          if StitchBins(SizeStitchBins,1) == ...
                (StitchBins((SizeStitchBins - 1),2) + 1),
             %Combine Stitches
             StitchBins((SizeStitchBins - 1),2) = StitchBins((SizeStitchBins),2);
             %Shorten StitchBin Matrix
             StitchBins = StitchBins(1:(SizeStitchBins - 1),:);
          end;
          
       end;   
    end;
    
    
    %--------------------- Reverse Matrix Stitching Routine ---------------
    if (ReverseStitchedSize >= NormalStitchedSize)| ...
       			isnan(NormalStitchedSize) == 1,
       %Stitch MatrixA to the end of MatrixB
       StitchedMatrix = cat(1,MatrixB(1:ReverseB), MatrixA(ReverseA:SizeA));
       
       %Update Stitch Bins
       if isnan(PrevStitchBins) == 1,
          %There are no previous stitch bins
          StitchBins = [ReverseB, ReverseB + StitchNumber - 1];
       else
          %There are previous stitch bins
          %Check for Snipped Stitches            
          while (PrevStitchBins(1,1) < (ReverseA + StitchNumber - 1)),
             %First Bin is snipped from matrix. Check if second is snipped
             if (PrevStitchBins(1,2) < (ReverseA + StitchNumber - 1)),
                %Second Bin is snipped too. Delete Bad Pair
                [SizeStitchBins, Junk] = size(PrevStitchBins);
          	     PrevStitchBins = PrevStitchBins(2:SizeStitchBins, :);
             else
                %Second Bin is not snipped, but first bin is snipped
                %Shrink Old Stitch Size
                PrevStitchBins(1,1) = ReverseA + StitchNumber - 1;
             end;
          end;
          
          %Offset Stitch Bins by inserted amount
          StitchBins = PrevStitchBins + ReverseB - ReverseA + 1; 
          %Make Room for new StitchBins
          [SizeStitchBins, Junk] = size(PrevStitchBins);
          StitchBins(2:SizeStitchBins+1, :) = StitchBins;
          %Insert New Stitch Bins
          StitchBins(1,:) = [ReverseB, ReverseB + StitchNumber - 1];
                      
          %Combine close stitches
          if StitchBins(1,2) == StitchBins(2,1) - 1,
             %Combine Stitches
             StitchBins(2,1) = StitchBins(1,1);
             %Shrink Stitch Bins Matrix
    	 [SizeStitchBins, Junk] = size(StitchBins);
             StitchBins = StitchBins(2:SizeStitchBins,:);   
          end;
          
       end;
    end;
    

    附录B:FindStitchPoint例程(FindStitchPoint.m)

    function [OutputBinA, OutputBinB]=FindStitchPoint(MatrixA, MatrixB, ...
       				MatchNumber, AdvancedStitchFindEnabled)
    %Find Stitch Points Function
    %Revision 1.0
    %
    %By Donald Schelle, May 2005
    %Maxim Integrated Products
    %120 San Gabriel Drive
    %Sunnyvale, CA, 94086
    %
    %This function will find the IDEAL stitch point in Matrix B given
    %the number of data points to match
    %
    %Inputs = MatrixA
    %			 MatrixB
    %			 Number of Records to Match
    %			 Advanced Stitch Find Enabled (0 = NO, 1 = YES)
    %Output = (OutputBinA) End Bin of MatrixA to stitch data
    %			 (OutputBinB) Start Bin of Matrix B to stitch data
    %
    %If no bins are found, the function will output a NaN
    %--------------------------------------------------------------------------
    
    %Do argument error checking to see if there is enough arguments
    if nargin < 2,
       %The user has not supplied enough arguments
       disp('Function requires TWO Matrices');
       OutputBinA = NaN;
       OutputBinB = NaN;
       return;
    elseif nargin < 3,
       disp('Select a number of points to match');
       OutputBinA = NaN;
       OutputBinB = NaN;
       return;
    elseif nargin == 3,
       %Advanced code stitching is NOT enabled
       OutputBinA = NaN;
       AdvancedStitchFindEnabled=0;
    end;
    
    %Ensure that Matrix A and B are single ROW matrices
    [row col] = size(MatrixA);
    if row > col, MatrixA = MatrixA'; end;
    [row col] = size(MatrixB);
    if row > col, MatrixB = MatrixB'; end;
    
    %Determine Size of Matrices
    [Junk, SizeA] = size(MatrixA);
    [Junk, SizeB] = size(MatrixB);
    
    %Initialize OutputBinB to NaN (which means that NO stitch points are found)
    OutputBinB = NaN;
    %Set initial size of BinA
    BinA = SizeA - MatchNumber + 1;
    %Initialize BinStop Variable
    BinStop = SizeA-100;
    
    %Loop to search through Matrix B numerous times.  This loop is only
    %excuted once if Advanced Stitch Find is disabled.  The loop will stop when
    %the 'ideal' stitch point is found
    while BinA > BinStop, 
       %Stuff the Match Numbers into a separate Matrix
    	MatchMatrix = MatrixA(BinA:BinA+MatchNumber - 1);
       
       %Find all bins in MatrixB that match the first number of the Match Matrix
    	MatchedBins = find(MatrixB == MatchMatrix(1));
       
       %Compare the 2nd through nth number of the Match Matrix with the
       %prospective series of numbers in MatrixB
       
       %Calculate the size of the Matched Bins Matrix
       [Junk, SizeMatchedBins] = size(MatchedBins);
       
       %The advanced stitch mode optimizes search time by eliminating
       %bad stitch points that would result in the final concatenated
       %matrix being smaller than the last set of stitch points
       if isnan(OutputBinB) == 0,
          %A Stitch Point exists from a previous run.  Elimiate bad stitch points
          %Calculate critical Stitch Point
          MatrixSize = OutputBinA + (SizeB-OutputBinB) + 1;
          CriticalBin = BinA + SizeB - MatrixSize - 1;
          %Find maximum number in the MatchMatrix
          BadBin = find(MatchedBins > CriticalBin);
          %Eliminate Bad Bins (if there are any)
          if isempty(BadBin) == 0,
             MatchedBins = MatchedBins(1:BadBin(1) - 1);
          end;
          %Calculate size of new Matched Bins Matrix
          [Junk, SizeMatchedBins] = size(MatchedBins);       
       end;
       
       %loop to cycle through initial matched bins
       for i=1:SizeMatchedBins,
          %Check to make sure that there isn't a MatrixB overrun
          if (MatchedBins(i) + MatchNumber - 1) > SizeB,
             break;
          end;
          
          %Assume that next few codes will match and set StitchBinGood = true
          StitchBinGood = 1;	   
          %Initialize MatchMatrixCounter
          Count = 1;
          %Cycle through MatrixB and compare Numbers with the MatchMatrix
          for j=MatchedBins(i):(MatchedBins(i) + MatchNumber - 1),
             if MatchMatrix(Count)==MatrixB(j),
                %Number is good, continue and check next number
    	     Count = Count + 1;
    	 else
                %Number is bad, break loop and try next sequence
                StitchBinGood = 0;
    	     break;
    	 end;
          end;
    	   
          if StitchBinGood == 1,
             %The optimal (first) stitch has been found
             %Record the End bin of MatrixA
             %Record the Start bin of MatrixB
             OutputBinA = BinA;
             OutputBinB = MatchedBins(i) + 1;
             %Calculate the size of the joined Matrix and a new BinStop#
             BinStop = OutputBinA-OutputBinB+1;
             break;
          end;  
       end;
       
       if AdvancedStitchFindEnabled == 1,
          %Advanced Stitch Find is enabled and we should make a new match
          %matrix and search for these numbers
          BinA = BinA - 1;
       else
          %Advanced Stitch Find is disabled and we should end the loop
          break;
       end;
    end;
    
    %Check to see if NO Bins Matched
    if isnan(OutputBinB) == 1,
       %NO Bins matched
       OutputBinA = NaN;
    end;
    

北京迪阳世纪科技有限责任公司 版权所有 2008-2018 著作权声明

电话:010-62156134 62169728 86761538 13301007825  节假日:13901042484

地址:北京市海淀区北三环西路甲30号双天大厦 319  邮编:100086

Email:sales@pc17.com.cn 20131988   传真:010-68400238

流量统计  京ICP备05038211号