adc的dnl和inl代碼
基于美信代碼改的,原理是碼密度圖,將正弦波轉為對應的碼密度函數(shù)曲線,再對經(jīng)過ADC轉換的數(shù)字碼進行統(tǒng)計。輸入同樣是數(shù)字碼經(jīng)過權重累加的階梯圖。
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));
%求出正弦波密度曲線后再乘以總采樣次數(shù)FFTN,得到每個碼的概率次數(shù)
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