高速ADC测试心得

摘要:ADC作为连接模拟世界与数字世界的桥梁,是现代雷达系统中必不可少的一环,其性能的好坏直接决定雷达的好坏。激光测风雷达作为现代雷达系统大家庭中的一员,必然也会使用到ADC。为了保证其性能,除了良好的设计外,设计完成之后充分的测试也是必不可少的。

在测试之前,首先简单介绍下ADC的种类以及其主要指标。

ADC种类

 

类型

优点

缺点

逐次逼近型

速度高,功耗低,低分辨率价格低

分辨率提升困难

Σ-Δ调制型

采样精度高,无需抗混叠滤波器

应用带宽低

并行比较型/串并行型

转换速率快

分辨率低,规格大,价格高

压频变换型

分辩率高、功耗低、价格低

需要外部计数电路共同完成AD转换

不同类型的ADC由于其原理不同,各有优缺点,实际使用过程中可以根据具体使用场景选择最合适的类型。下图列举了一些典型应用及其对采样率和分辨率的要求。

ADC指标

 

不管何种原理的ADC,其评价指标是一样的,主要分为静态指标和动态指标,其定义及意义如下表所示

指标名称

定义及意义

静态指标

偏移误差(Offset Error)

输入信号为零时输出信号不为零的值

增益误差

(Gain Error)

增益误差是预估传递函数和实际斜率的差别,增益误差通常在模数转换器最末或最后一个传输代码转换点计算

积分非线性(INL)

INL表示了ADC器件在所有的数值点上对应的模拟值,和真实值之间误差最大的那一点的误差值

差分非线性(DNL)

相邻两刻度之间最大的差异

动态指标

分辨率

分辩率又称精度,通常以数字信号的位数来表示

有效位数(ENOB)

实际处理中,ADC能够达到的处理精度。根据信纳比算得。

信噪比(SNR)

输入信号和噪声(不包括任何谐波以及直流) 的有效值之比,衡量器件内部噪声大小

总谐波失真(THD)

输入信号与系统所有谐波(HD)的总功率(P)之比,提供系统对称和非对称非线性产生的总失真大小

无杂散动态范围(SFDR)

基本频率与杂波信号最大值的差值,能够对系统失真进行量化

信纳比(SINAD)

输入信号和所有输出信号失真(包括谐波成分,不包括直流)的功率之比,评估输出信号所有传递函数非线性加上系统所有噪声(量化、抖动和假频)的累积效果

一般来讲静态参数都比较好理解,而下面这张图及其中公式可以让你对各个动态指标有一个更直观的认识。

 
高速ADC测试


在测试之前,要做好充足的准备工作,本文档只对ADC单频测试进行讨论,一个比较好的测试系统框图如下图所示,测试过程中需要的仪器有信号发生器、带通滤波器、电源、电脑等。

ADC的偏移误差与增益误差可以很方便通过对采集结果进行计算得到,而积分非线性与差分非线性通常是通过对正弦波的采样数据进行幅度分布的直方图间接统计计算得到,如下图所示,理想正弦波的幅度分布应该是左面的形状,由于非线性等的影响,分布会变成右边的形状,通过对直方图分析可以得出静态参数的指标。

ADC的动态参数是对正弦波的采样数据进行FFT频谱分析间接计算得到,为了在FFT处理时不发生频谱泄露,从而得到更准确的结果,一般采用相干采样的方式,即需选择特定频率的输入信号与采样频率,从而使得采集到的采样数据能在记录长度内转换的代码尽可能多。这是通过输入信号频率与采样频率之间的一种基本关系实现的,其数学关系如下所示:

finfs=NcyclesNsamples

其中,fin为输入信号频率,fs为采样频率,Ncycles为完整采样的周期数,Nsamples为采样总点数,一般,为方便FFT处理,Nsamples取2的整数次幂,Ncycles取与Nsamples互质的整数。

例如,当时用相干采样时,若设定输入信号频率为85MHz,采样率为400MHz,采样总点数为16384,通过计算,此时,Ncycles为3481.6,取Ncycles为3483,重新计算输入信号频率应为85.03417098MHz。

下图显示了相干采样与非相干采样时FFT的结果,其中红色曲线为非相干采样结果,发生了明显的频谱泄露,从而导致不能得到准确的动态性能计算结果。

 

ADC的动态参数是对正弦波的采样数据进行FFT频谱分析间接计算得到,为了在FFT处理时不发生频谱泄露,从而得到更准确的结果,一般采用相干采样的方式,即需选择特定频率的输入信号与采样频率,从而使得采集到的采样数据能在记录长度内转换的代码尽可能多。这是通过输入信号频率与采样频率之间的一种基本关系实现的,其数学关系如下所示:

其中,fin为输入信号频率,fs为采样频率,Ncycles为完整采样的周期数,Nsamples为采样总点数,一般,为方便FFT处理,Nsamples取2的整数次幂,Ncycles取与Nsamples互质的整数。

例如,当时用相干采样时,若设定输入信号频率为85MHz,采样率为400MHz,采样总点数为16384,通过计算,此时,Ncycles为3481.6,取Ncycles为3483,重新计算输入信号频率应为85.03417098MHz。

下图显示了相干采样与非相干采样时FFT的结果,其中红色曲线为非相干采样结果,发生了明显的频谱泄露,从而导致不能得到准确的动态性能计算结果。

当输入信号确实不能完全满足相干采样的要求时,还可以通过加窗的方式减小频谱泄露的影响,不同的窗函数有不同的特性,选择合适的窗函数可以辅助得到理想的结果,比较常用的窗函数有Blankman、Hamming等,可以在MATLAB中使用help window命令查看不同窗的特性与使用方式。 

在测试过程中,输入信号的“纯度”会影响数字输出的性能。输入信号中的耦合噪声将转换为输出信号数字噪声,如果输入信号中有太多噪声和失真,ADC性能实际上会被测试条件所掩盖。输入信号的精度和纯度最终取决于器件的转换分辨率,一般来说测试设备的精度要比被测器件高10倍以上。另外在输入端使用滤波器,可以除去部分输入信号之外的噪声和失真。

通常受测试条件的限制,我们往往没有完美的信号源,信号源自身的谐波与噪声会超过被测ADC的水平,从而影响测试结果。在测试之前,我们可以先使用频谱仪及输入短接的方式对信号源与ADC底噪做一个简单评估。 

在上图中,左侧图像是对采集数据进行FFT的结果,其中红色曲线对应ADC输入短接,该曲线能够能够直接反应ADC自身量化噪声水平;蓝色曲线对应ADC输入信号频率为85.03417098MHz,幅度为8dBm,从结果中可以看到,其底噪水平提高,说明信号源自身噪声水平大于ADC量化噪声,除此之外还存在较明显谐波,对比右侧直接使用频谱仪对信号源测试的结果看,说明二次谐波主要是由信号源自身产生的。

 

 

以上是个人在ADC测试过程中的一些心得,如有错误,欢迎指正, 

下面附测试过程中使用的MATLAB代码

% Test Script for ADC     Dynamatic Parameters
% ZJ 20181220
clear all;
%% SET OPTIONS (These need to be set)
% ********************************************
DNLgo=1;                      % Execute INL/DNL? [yes=1/no=0]
fin = 85.034e6;%17098e6;


%% SET VALUES FOR FFT (These need to be set)
% *********************************************
%co
N=14;                      % Resolution of converter
N_sample = 16384;          % Sampling points ,it's better being power of 2 
fs=399.99995904e6;                  % Sampling frequency
ts= 1/fs;

t = ts*linspace(1,N_sample,N_sample);
w = 2*pi*fin;
%% DATA Generate (These need to be set)
% ******************************
A1 = 2^(N-1);
A2 = 0.0006*A1;
A3 = 0.00005*A1;
V1 = A1*sin(w*t);
V2 = A2*sin(2*w*t);
V3 = A3*sin(3*w*t);

data = V1+V2+V3 + 0.5*randn(1,N_sample);

%data = data - mean(d50.82ata);
datac=data+2^(N-1);
%datac = datac';

%% WINDOW DATA
% ***********************************
% data = data';
% data=data.*window(@blackman,N_sample);   %加窗截断
NFFT = N_sample;

%% Prepare for FFT
frescalc = fs/NFFT;
Ts=1/fs;                   % Calculate period
Ndelay=0;                  % Number of samples to dump at beginning of transient
Vref=2^(N-1);              % Positive max voltage swing for voltage output (Simulink Model)
                           %     or 2^(N-1) for digital output

num_harm=5;                % # of harmonics to find and use in THD/SNR calculation


%% CALCULATE VALUES FOR FFT
% ***********************************

fft_o = fft(data,NFFT)/NFFT;
fft_amp= 2*abs(fft_o(1:NFFT/2));  % multiply x2 to normalize because fft of 1*sin(x) = 0.5[d(w-wo)+d(w+wo)]
fft_amp_nor = fft_amp/Vref;       % normalize to 1
% fft_amp_nor(6967) = 1e-20;
fft_amp_nor_db = 20*log10(fft_amp_nor+1e-20);% change to [dB], add 1e-20 to avoid log 0
f = fs/2*linspace(0,1,NFFT/2);

% CALCULATE MEAN AND STDDEV OF DATA
% *************************************
ave_data=mean(data);
stddev_data=std(data);

% DETERMINE HARMONIC FREQUENCIES
% ***********************************
% Finds the harmoic frequencies as they fold into the baseband
%   as well as the vector index of those harmonics
for i=1:1:(num_harm+1)   % harmonic number
    done=0;
    k=1;     % frequency band number, 1 = 0 to Fs Hz
    while done==0
        if i*fin < (k-1/2)*fs
            harm(i)=i*fin-(k-1)*fs;
            done=1;    
        elseif i*fin < k*fs
            harm(i)=k*fs-i*fin;
            done=1;
        else
            k=k+1;
        end
    end
end
harm_ind=round(harm/frescalc)+ones(1,length(harm)); % determine vector index of harmonics
                                         %   add 1 because DC = index 1 将谐波对应到采样点上
                                         
%% CALCULATE SNDR, SNR, SFDR, THD
% *************************************

    % Calculate SNR/SNDR/SFDR/THD normally
    
    fundpnts=10;                % # of FFT points on either side of fundamental to include
                           %   in fundamental power due to non-coherence(非相干性)
    
    fftout_n=fft_amp_nor;                                %   Save FFT data, use copy for manipulations
    fund_ind=(harm_ind(1)-fundpnts):1:(harm_ind(1)+fundpnts); %第一个谐波(即harm_ind(1)就是信号频)
                                                    %   Points to include in fundemental
    P_S=sum(fftout_n(fund_ind).^2);                 % Power of fundemental
    P_ND=sum(fftout_n(2:N_sample/2).^2)-P_S;        % Power of Noise and Distortion (exclude DC)不包括直流,所以从2开始
    P_D=sum(fftout_n(harm_ind(2:(num_harm+1))).^2); % Power of harmonics 因为第一个谐波(即harm_ind(1)是主频,不包括在内)
    for i=[1 fund_ind]
        fftout_n(i)=1e-20;                          % Remove DC and fundamental from spectrum for SFDR,画出图像可以决定fundpnts的值
    end
    
    
    [M_H,H_ind]=max(fftout_n(1:N_sample/2));        % Magnitude and index of dominant harmonic
    P_H=M_H^2;                                      % Power of dominant harmonic
    H_num=-1;
    for i=1:1:length(harm_ind)                      % Test to deterimine number of 
        if H_ind==harm_ind(i)                       %   dominant harmonic
            H_num=i;                                %   -1 means not one of primary harmonics
        end
    end

    SNDRo  = 10*log10(P_S/P_ND);                       % SNDR [dB]
    THDo   = 10*log10(P_S/P_D);                        % THD [dB]
    SNRo   = 10*log10(P_S/(P_ND-P_D));                 % SNR [dB] 不能包括谐波
    SFDRo  = 10*log10(P_S/P_H);                        % SFDR [dB]
    ENOBo  = (SNDRo-1.72)/6.02;                        % ENOB [Bit]
                                        
%% plot FFT
% *********************************************
%figure
hold on
plot(f(1:NFFT/2)/1e6,fft_amp_nor_db(1:NFFT/2));  % Choose FFT with frequency or index
%plot(frescalc*N_cycle/1e6,fft_amp_nor_db(N_cycle+1),'rs')   
% for i=1:1:length(harm)     % Mark all the harmonics
%     plot(harm(i)/1e6,fft_amp_nor_db(harm_ind(i)),'rs')
% end
ylabel('Full-Scale Normalized Magnitude[dB]')
xlabel('Frequency [MHz]')
title(sprintf('FFT (%g points)\nFs = %g MSps, Fin = %g MHz (%1.2g dBfs)', ...
      NFFT,fs/1e6,fin/1e6,fft_amp_nor_db(harm_ind(1))));
grid;
box on;
ylim([-140 10]);
set(gca,'xgrid', 'off');
set(gca, 'GridLineStyle' ,'-');
set(gca,'yTick',[-140:10:10]);

s1=sprintf('SFDR = %4.2fdB\n',SFDRo);
s2=sprintf('THD   = %4.2fdB\n',THDo);
s3=sprintf('SNR   = %4.2fdB\n',SNRo);
s4=sprintf('SNDR = %4.2fdB\n',SNDRo);
s5=sprintf('ENOB = %4.2fbit\n',ENOBo);
text(0,-10,s1);
text(0,-20,s2);
text(0,-30,s3);
text(0,-40,s4);
text(0,-50,s5);
hold off;  


% % CALCULATE DNL/INL and PLOT
% % *********************************************
% dnl = 0;
% inl = 0;
% if DNLgo==1
%     % Calculate NNL/INL
%     min_bin=min(datac);
%     max_bin=max(datac);
%     h = hist(datac, min_bin:max_bin);          % Histogram各个数据出现的频数统计
%     ch = cumsum(h);                           % Cumulative histogram累积和
%     Tlevels = -cos(pi*ch/sum(h));             % Raised cosine fit 上升的余弦拟合
%     hlin = Tlevels(2:end) - Tlevels(1:end-1); % Difference between adjacent bins相邻项做差
%     hlin = hlin(3:end-2);                     % Dump outside bins
%     lsb = sum(hlin) / (length(hlin));         % Find average difference between bins
%                                               %   to remove gain error
%     dnl = [0 hlin/lsb-1];                     % Remove gain error, center DNL on 0
%     inl= cumsum(dnl);                         % INL is integral of DNL
% 
%     % PLOT DNL/INL
%     figure;
%     title(sprintf('DNL/INL (%g pnt)',length(datac)));
%     subplot(2,1,1)
%     plot(linspace(min_bin+2, max_bin-2, length(dnl)), dnl);
%     title(sprintf('DNL/INL (%g pnt)',length(datac)));
% %    xlabel('Digital Code [LSB]');
%     ylabel('DNL [LSB]');
%     xlim([0 2^N]);
%     ylim([-2 ceil(max(dnl))]);
%     subplot(2,1,2)
%     plot(linspace(min_bin+2, max_bin-2, length(dnl)), inl);
% %    title(sprintf('DNL/INL (%g points)',length(datac)));
%     xlabel('Digital Code [LSB]');
%     ylabel('INL [LSB]');
%     xlim([0 2^N]);
%     ylim([floor(min(inl)) ceil(max(inl))]);
% end

% % DISPLAY DATA
% % ***********************************************
% 
% disp(sprintf('%s%s%s%s%s%s%s%s', ...
%      sprintf('\n\n**********************\n'), ...
%      sprintf(' Fs   = %g MSps\n', fs/1e6), ...
%      sprintf(' Fin  = %g MHz (%1.2g dBfs)\n', fin/1e6, fft_amp_nor_db(harm_ind(1))), ...
%      sprintf(' MEAN = %g LSB\n',ave_data), ...
%      sprintf(' STD  =  %g LSB\n',stddev_data), ...
%      sprintf(' DNL  = -%2.2g/+%2.2g LSB\n', abs(min(dnl)), max(dnl)), ...
%      sprintf(' INL  = -%2.2g/+%2.2g LSB\n', abs(min(inl)), max(inl)), ...
%      sprintf(' Psignal = %g dB\n',10*log10(P_S)), ...
%      sprintf(' SFDR = %g dB (%g, %gMHz)\n',SFDRo,H_num,H_ind*fres/1e6), ...
%      sprintf(' THD  =  %g dB (%g harms)\n',THDo,num_harm), ...
%      sprintf(' SNR  =  %g dB\n',SNRo), ...
%      sprintf(' SNDR = %g dB\n',SNDRo), ...
%      sprintf(' ENOB = %g Bit\n',ENOBo), ...
%      sprintf(' MAX = %g  min = %g \n',max(data),min(data)), ...
%      sprintf('**********************')));
% %************************************************







  • 33
    点赞
  • 266
    收藏
    觉得还不错? 一键收藏
  • 10
    评论
Matlab ADC测试框架是用于评估和分析模拟-数字转换器(ADC)的性能的一种工具。它提供了一套完整的测试流程和算法,旨在帮助工程师对ADC进行测试、验证和优化。 首先,Matlab ADC测试框架可以生成各种模拟信号,用于模拟真实世界中的输入情况。这些信号可以通过Matlab中的工具进行设计和生成,如正弦波、方波、随机噪声等。生成的信号可以与ADC的输入端相连接,以模拟实际的工作场景。 其次,框架还提供了一系列数据采集和处理的功能,以获取ADC输出的数字数据。通过使用合适的硬件接口和数据采集设备,可以将ADC的输出信号转换为数字数据。这些数据可以通过Matlab进行进一步的处理和分析,以评估ADC的性能指标,如信噪比、动态范围、非线性误差等。 此外,Matlab ADC测试框架还包含了一些常见的测试算法和指标计算方法。例如,频谱分析可以用于检测ADC输出信号的谐波和杂散成分;噪声分析可以用于评估ADC的噪声特性;非线性误差补偿算法可以用于提高ADC的线性性能等等。这些算法和方法都可以在Matlab中直接调用,方便快捷。 总之,Matlab ADC测试框架为ADC测试和分析提供了一套完整、灵活和易用的工具。它可以帮助工程师对ADC的性能进行全面的评估和分析,从而优化和改进ADC的设计和性能。同时,该框架也可以作为教学和研究的工具,用于学生和研究人员对ADC进行学习和研究。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 10
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值