Re: INL,DNL measurement
I am trying to measure INL/DNL for DAC.I am facing problem with MATLAB script of dallas for measuring INL/DNL for ADC in the following.PLs suggest me to get the simulation .
%Code density/histogram test to calculate INL and DNL require a
large number of samples.
%Step 1: Apply a close to full-scale sine wave (but not clipping)
and find the mid-code for the applied signal.
%Step 2: Apply the same sine wave input, but slightly larger
amplitude to clip the ADC slightly.
%Run the following program, enter the number of samples,
resolution and mid-code from Step 1and continue.
%Copyright Au/Hofner, Maxim Integrated Products, 120 San Gabriel
Drive, Sunnyvale, CA94086
www.maxim-ic.com/an2085
Page 7 of 9
%This program is believed to be accurate and reliable. This
program may get altered without prior notification.
filename=input('File Name or press ENTER for Listing Transfer
HP16500C: ');
if isempty(filename)
filename = 'listing';
end
fid=fopen(filename,'r');
numpt=input('Number of Data Points? ');
numbit=input ('ADC Resolution? ');
mid_code=input(Enter Mid-Code (Mean): ');
for i=1:13, %Discard 13 lines of redundant or header-related
HP16500C data
fgetl(fid);
end
[v1,count]=fscanf(fid,'%f',[2,numpt]);
fclose(fid);
v1=v1';
code=v1
,2);
code_count=zeros(1,2^numbit); %Code count
for i=1:size(code),
code_count(code(i)+1)=code_count(code(i)+1) + 1;
end
%Routine to detect whether the ADC's input is clipping or not
if code_count(1) == 0 | code_count(2^numbit) == 0 | ...
(code_count(1) < code_count(2)) | (code_count(2^numbit-1) >
code_count(2^numbit))
disp('Increase Sine-Wave Amplitude to Slightly Clip the
ADC!!!');
break;
end
A=max(mid_code,2^numbit-1-mid_code)+0.1; %Initial estimate of
actual sine wave amplitude
vin=(0:2^numbit-1)-mid_code; %distance of codes to mid code
sin2ramp=1./(pi*sqrt(A^2*ones(size(vin))-vin.*vin));
%sin2ramp*numpt is the expected
%Count each code; keep increasing estimate of A until the actual
total number of counts from
%code 1 to 2^numbit-2 matches with that predicted by
sin2ramp*numpt
while sum(code_count(2:2^numbit-1)) <
numpt*sum(sin2ramp(2:2^numbit-1))
A=A+0.1;
sin2ramp=1./(pi*sqrt(A^2*ones(size(vin))-vin.*vin));
end
disp('You Have Applied a Sine Wave of (dBFS): ');
Amplitude=A/(2^numbit/2)
figure;
plot([0:2^numbit-1],code_count,[0:2^numbit-1],sin2ramp*numpt);
title('CODE HISTOGRAM - SINE WAVE');
xlabel('DIGITAL OUTPUT CODE');
ylabel('COUNTS');
axis([0 2^numbit-1 0 max(code_count(2),code_count(2^numbit-1))]);
code_countn=code_count(2:2^numbit-1)./(numpt*sin2ramp(2:2^numbit-
1)); %End points discarded!
figure;
plot([1:2^numbit-2],code_countn);
title('CODE HISTOGRAM - NORMALIZED')
xlabel('DIGITAL OUTPUT CODE');
ylabel('NORMALIZED COUNTS');
dnl=code_countn-1; %DNL=Vj+1-Vj-1LSB where Vj represents a
transition point
%Vj+1-Vj is proportional to normalized code
count
inl=zeros(size(dnl));
for j=1:size(inl')
inl(j)=sum(dnl(1:j)); %INL,j=DNL,0+DNL,1+...+DNL,j
end
%INL still contains the offset and gain error!
%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^numbit-2],inl,1);
inl=inl-p(1)*[1:2^numbit-2]-p(2);
disp('End Points Eliminated for DNL and INL Calculations');
figure;
plot([1:2^numbit-2],dnl);
grid on;
title('DNL');
xlabel('DIGITAL OUTPUT CODE');
ylabel('DNL (LSB)');
figure;
plot([1:2^numbit-2],inl);
grid on;
title('INL (BEST END-POINT FIT)');
xlabel('DIGITAL OUTPUT CODE');
ylabel('INL(LSB)');
regards,
fazal