adc的dnl和inl代码
基于美信代码改的,原理是码密度图,将正弦波转为对应的码密度函数曲线,再对经过ADC转换的数字码进行统计。输入同样是数字码经过权重累加的阶梯图。
function my_dnlinl(D_codeWeight,FFTN,Resol)
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% DNL & INL ,method.two %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%用于计算INL和DNL的%代码密度/直方图测试需要大量样本。
%步骤1:施加接近满量程的正弦波(但不削波),并找到所施加信号的中间码。
%步骤2:施加相同的正弦波输入,但幅度稍大些,以对ADC进行稍稍削波。
%FFTN = OSR*(2^Resol);
mid_code=0.5*(max(D_codeWeight)-min(D_codeWeight));%不需要取整!
% D_codeWeight = D_bits_record*DACWeight;
D_codeWeightCount=zeros(1,2^Resol);
for SamPoint =1:FFTN % FFTN个,D_codeWeight为量化权重,为横坐标
D_codeWeightCount(D_codeWeight(SamPoint)+1) =D_codeWeightCount(D_codeWeight(SamPoint)+1)+1;
end
if D_codeWeightCount(1) == 0 || D_codeWeightCount(2^Resol) == 0 || ...
(D_codeWeightCount(1) < D_codeWeightCount(2)) || (D_codeWeightCount(2^Resol-1) > D_codeWeightCount(2^Resol))
disp('ADC not clipping ... Increase sinewave amplitude!');
end
A_Weight=max(mid_code,2^Resol-1-mid_code)+0.1; %权重
Vi_diff=(0:2^Resol-1)-mid_code; %差分权重,只能是0:4095,减4095/2,不能1:4096
sin2ramp=1./(pi*sqrt(A_Weight^2*ones(size(Vi_diff))-Vi_diff.*Vi_diff));
%求出正弦波密度曲线后再乘以总采样次数FFTN,得到每个码的概率次数
while sum(D_codeWeightCount(2:2^Resol-1)) < FFTN*sum(sin2ramp(2:2^Resol-1))
A_Weight=A_Weight+0.1;
sin2ramp=1./(pi*sqrt(A_Weight^2*ones(size(Vi_diff))-Vi_diff.*Vi_diff));
end
% figure
% plot((0:2^Resol-1),sin2ramp)%sine波的码密度曲线,但是曲线为什么不对称?
% 因为mid_code取整了,不能取整
% xlim([-400,4500]);
%disp('You Have Applied a Sine Wave of (dBFS): ');
Amplitude=A_Weight/(2^Resol/2);%美信原代码可能有用,改写之后用不到
figure;
set(gcf, 'Position', [100, 100, 1000, 400]);
subplot(1,2,1)
plot((1:2^Resol),D_codeWeightCount)
xlim([0,2^Resol]);
subplot(1,2,2)
plot((1:2^Resol),sin2ramp*FFTN);
xlim([0,2^Resol]);
%axis([0 2^Resol-1 0 max(D_codeWeightCount)]);
%%%%%%%%% DNL %%%%%%%%%
D_codeWeightCountDiv=D_codeWeightCount(2:2^Resol-1)./(FFTN*sin2ramp(2:2^Resol-1));
%去头去尾
figure;
plot(D_codeWeightCountDiv(1:2^Resol-2));%即原来的2:2^Resol-1
title('CODE HISTOGRAM - NORMALIZED')
xlabel('DIGITAL OUTPUT CODE');
ylabel('NORMALIZED COUNTS');
dnl=D_codeWeightCountDiv-1;
%%%%%%%%% INL %%%%%%%%%
inl=zeros(size(dnl));
for Q=1:length(dnl)
inl(Q)=sum(dnl(1:Q));
end
%INL with end-points fit, i.e. INL=0 at end-points the straight line joining the 2 end points
%[p,S]=polyfit([1,2^numbit-2],[inl(1),inl(2^numbit-2)],1);
%the best-fit straight line
[p,S]=polyfit([1:2^Resol-2],inl,1);
inl=inl-p(1)*[1:2^Resol-2]-p(2);
%disp('End Points Eliminated for DNL and INL Calculations');
figure;
set(gcf, 'Position', [100, 100, 1000, 400]);
subplot(2,1,1)
plot(dnl(1:2^Resol-2));
grid on;
title('DIFFERENTIAL NONLINEARITY vs. DIGITAL OUTPUT CODE');
xlabel('DIGITAL OUTPUT CODE');
ylabel('DNL (LSB)');
xlim([0,2^Resol]);
ylim([min(dnl)-0.25,max(dnl)+0.25])
subplot(2,1,2)
plot(inl(1:2^Resol-2));
grid on;
title('INTEGRAL NONLINEARITY vs. DIGITAL OUTPUT CODE');
xlabel('DIGITAL OUTPUT CODE');
ylabel('INL(LSB)');
xlim([0,2^Resol]);
ylim([min(inl)-0.25,max(inl)+0.25])
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
end

