在线咨询 切换到宽版
eetop公众号 创芯大讲堂 创芯人才网

 找回密码
 注册

手机号码,快捷登录

手机号码,快捷登录

搜帖子
查看: 4844|回复: 8

[求助] 关于maxim测ADC dnl,inl的程序的一问

[复制链接]
发表于 2015-4-3 14:49:00 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?注册

×
最近做了个7bitFLASH,想测一下它的DNL和INL,于是找到美信的一段程序,二楼会贴出代码,想问问各位大大,有了解这个程序的么,mid_code是怎么取得?
 楼主| 发表于 2015-4-3 14:49:47 | 显示全部楼层
%Code density/histofgram 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
%This program is believed to be accurate and reliable. This program may get altered without prior notification.

filename=input('Enter File Name: ');
if isempty(filename)
   filename = 'listing';
end
fid=fopen(filename,'r');
numpt=input('Enter Number of Data Points:  ');
numbit=input ('Enter ADC Resolution:  ');
mid_code=input('Enter Mid-Code (Mean Code):  ');

for i=1:13,       
   fgetl(fid);
end
[v1,count]=fscanf(fid,'%f',[2,numpt]);
fclose(fid);

v1=v1';
code=v1(:,2);
code_count=zeros(1,2^numbit);

for i=1:size(code),
   code_count(code(i)+1)=code_count(code(i)+1) + 1;
end

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('ADC not clipping ... Increase sinewave amplitude!');
   break;
end

A=max(mid_code,2^numbit-1-mid_code)+0.1;
vin=(0:2^numbit-1)-mid_code;       
sin2ramp=1./(pi*sqrt(A^2*ones(size(vin))-vin.*vin));

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));
figure;
plot([1:2^numbit-2],code_countn);
title('CODE HISTOGRAM - NORMALIZED')
xlabel('DIGITAL OUTPUT CODE');
ylabel('NORMALIZED COUNTS');

dnl=code_countn-1;
inl=zeros(size(dnl));
for j=1:size(inl')
   inl(j)=sum(dnl(1:j));
end

%End-Point fit INL
%[p,S]=polyfit([1,2^numbit-2],[inl(1),inl(2^numbit-2)],1);

%Best-straight-line fit INL
[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('DIFFERENTIAL NONLINEARITY vs. DIGITAL OUTPUT CODE');
xlabel('DIGITAL OUTPUT CODE');
ylabel('DNL (LSB)');
figure;
plot([1:2^numbit-2],inl);
grid on;
title('INTEGRAL NONLINEARITY vs. DIGITAL OUTPUT CODE');
xlabel('DIGITAL OUTPUT CODE');
ylabel('INL(LSB)');
回复 支持 反对

使用道具 举报

 楼主| 发表于 2015-4-3 14:51:48 | 显示全部楼层


   

        

                
  1. %Code density/histofgram test to calculate INL and DNL require a large number of samples.
  2. %Step 1: Apply a close to full-scale sine wave (but not clipping) and find the mid-code for the applied signal.
  3. %Step 2: Apply the same sine wave input, but slightly larger amplitude to clip the ADC slightly.
  4. %Run the following program, enter the number of samples, resolution and mid-code from Step 1and continue.
  5. %Copyright Au/Hofner, Maxim Integrated Products, 120 San Gabriel Drive, Sunnyvale, CA94086
  6. %This program is believed to be accurate and reliable. This program may get altered without prior notification.

  7. filename=input('Enter File Name: ');
  8. if isempty(filename)
  9.    filename = 'listing';
  10. end
  11. fid=fopen(filename,'r');
  12. numpt=input('Enter Number of Data Points:  ');
  13. numbit=input ('Enter ADC Resolution:  ');
  14. mid_code=input('Enter Mid-Code (Mean Code):  ');

  15. for i=1:13,       
  16.    fgetl(fid);
  17. end
  18. [v1,count]=fscanf(fid,'%f',[2,numpt]);
  19. fclose(fid);

  20. v1=v1';
  21. code=v1(:,2);
  22. code_count=zeros(1,2^numbit);

  23. for i=1:size(code),
  24.    code_count(code(i)+1)=code_count(code(i)+1) + 1;
  25. end

  26. if code_count(1) == 0 | code_count(2^numbit) == 0 | ...
  27.   (code_count(1) < code_count(2)) | (code_count(2^numbit-1) > code_count(2^numbit))
  28.    disp('ADC not clipping ... Increase sinewave amplitude!');
  29.    break;
  30. end

  31. A=max(mid_code,2^numbit-1-mid_code)+0.1;
  32. vin=(0:2^numbit-1)-mid_code;       
  33. sin2ramp=1./(pi*sqrt(A^2*ones(size(vin))-vin.*vin));

  34. while sum(code_count(2:2^numbit-1)) < numpt*sum(sin2ramp(2:2^numbit-1))
  35.   A=A+0.1;
  36.   sin2ramp=1./(pi*sqrt(A^2*ones(size(vin))-vin.*vin));
  37. end

  38. disp('You Have Applied a Sine Wave of (dBFS): ');
  39. Amplitude=A/(2^numbit/2)
  40. figure;
  41. plot([0:2^numbit-1],code_count,[0:2^numbit-1],sin2ramp*numpt);
  42. title('CODE HISTOGRAM - SINE WAVE');
  43. xlabel('DIGITAL OUTPUT CODE');
  44. ylabel('COUNTS');
  45. axis([0 2^numbit-1 0 max(code_count(2),code_count(2^numbit-1))]);
  46. code_countn=code_count(2:2^numbit-1)./(numpt*sin2ramp(2:2^numbit-1));
  47. figure;
  48. plot([1:2^numbit-2],code_countn);
  49. title('CODE HISTOGRAM - NORMALIZED')
  50. xlabel('DIGITAL OUTPUT CODE');
  51. ylabel('NORMALIZED COUNTS');

  52. dnl=code_countn-1;
  53. inl=zeros(size(dnl));
  54. for j=1:size(inl')
  55.    inl(j)=sum(dnl(1:j));
  56. end

  57. %End-Point fit INL
  58. %[p,S]=polyfit([1,2^numbit-2],[inl(1),inl(2^numbit-2)],1);

  59. %Best-straight-line fit INL
  60. [p,S]=polyfit([1:2^numbit-2],inl,1);
  61. inl=inl-p(1)*[1:2^numbit-2]-p(2);

  62. disp('End Points Eliminated for DNL and INL Calculations');
  63. figure;
  64. plot([1:2^numbit-2],dnl);
  65. grid on;
  66. title('DIFFERENTIAL NONLINEARITY vs. DIGITAL OUTPUT CODE');
  67. xlabel('DIGITAL OUTPUT CODE');
  68. ylabel('DNL (LSB)');
  69. figure;
  70. plot([1:2^numbit-2],inl);
  71. grid on;
  72. title('INTEGRAL NONLINEARITY vs. DIGITAL OUTPUT CODE');
  73. xlabel('DIGITAL OUTPUT CODE');
  74. ylabel('INL(LSB)');
            

   

    复制代码
回复 支持 反对

使用道具 举报

发表于 2015-4-5 21:34:54 | 显示全部楼层
学习一下。
回复 支持 反对

使用道具 举报

发表于 2019-12-19 15:44:53 | 显示全部楼层
程序有错误
回复 支持 反对

使用道具 举报

发表于 2023-9-5 20:09:42 | 显示全部楼层
前辈,请问这段代码有问题吗
回复 支持 反对

使用道具 举报

发表于 2023-10-18 11:20:36 | 显示全部楼层


   
黑化的玛奇朵 发表于 2023-9-5 20:09
前辈,请问这段代码有问题吗


请问您后来调通这段代码了吗?
回复 支持 反对

使用道具 举报

发表于 2025-8-1 23:21:47 | 显示全部楼层
% 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 1 and continue.
% Copyright Au/Hofner, Maxim Integrated Products, 120 San Gabriel Drive, Sunnyvale, CA 94086
% This program is believed to be accurate and reliable. This program may get altered without prior notification.

filename = input('Enter File Name: ', 's');
if isempty(filename)
   filename = 'listing';
end

fid = fopen(filename, 'r');
if fid == -1
    error('Cannot open file: %s', filename);
end

numpt = input('Enter Number of Data Points: ');
numbit = input('Enter ADC Resolution: ');
mid_code = input('Enter Mid-Code (Mean Code): ');

% Skip header lines
for i = 1:13
   fgetl(fid);
end

[v1, count] = fscanf(fid, '%f', [2, numpt]);
fclose(fid);

v1 = v1';
code = v1(:, 2);

% Initialize code count array
code_count = zeros(1, 2^numbit);

% Count occurrences of each code
for i = 1:length(code)
   code_idx = code(i) + 1;  % MATLAB uses 1-based indexing
   if code_idx >= 1 && code_idx <= 2^numbit
       code_count(code_idx) = code_count(code_idx) + 1;
   end
end

% Check for proper clipping
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('ADC not clipping ... Increase sinewave amplitude!');
   return;  % Use return instead of break outside loop
end

% Calculate sine wave amplitude
A = max(mid_code, 2^numbit-1-mid_code) + 0.1;
vin = (0:2^numbit-1) - mid_code;

% Calculate theoretical histogram for sine wave
sin2ramp = 1 ./ (pi * sqrt(A^2 * ones(size(vin)) - vin .* vin));

% Adjust amplitude until theoretical matches measured
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)

% Plot histogram
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))]);
legend('Measured', 'Theoretical', 'Location', 'best');

% Normalize histogram (exclude end points)
code_countn = code_count(2:2^numbit-1) ./ (numpt * sin2ramp(2:2^numbit-1));

figure;
plot(1:2^numbit-2, code_countn);
title('CODE HISTOGRAM - NORMALIZED');
xlabel('DIGITAL OUTPUT CODE');
ylabel('NORMALIZED COUNTS');

% Calculate DNL
dnl = code_countn - 1;

% Calculate INL
inl = zeros(size(dnl));
for j = 1:length(inl)
   inl(j) = sum(dnl(1:j));
end

% Best-straight-line fit INL
[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');

% Plot DNL
figure;
plot(1:2^numbit-2, dnl);
grid on;
title('DIFFERENTIAL NONLINEARITY vs. DIGITAL OUTPUT CODE');
xlabel('DIGITAL OUTPUT CODE');
ylabel('DNL (LSB)');

% Plot INL
figure;
plot(1:2^numbit-2, inl);
grid on;
title('INTEGRAL NONLINEARITY vs. DIGITAL OUTPUT CODE');
xlabel('DIGITAL OUTPUT CODE');
ylabel('INL (LSB)');

% Display summary statistics
fprintf('\nSummary Statistics:\n');
fprintf('DNL Max: %.3f LSB\n', max(dnl));
fprintf('DNL Min: %.3f LSB\n', min(dnl));
fprintf('INL Max: %.3f LSB\n', max(inl));
fprintf('INL Min: %.3f LSB\n', min(inl));
回复 支持 反对

使用道具 举报

发表于 2025-8-1 23:34:14 | 显示全部楼层
# ADC INL/DNL Test Code in R
# Save this as a .R file and run with source("filename.R")

# Load required libraries
library(graphics)

# Function to read user input
get_user_input <- function(prompt) {
  cat(prompt)
  return(readline())
}

# Main function
adc_inl_dnl_test <- function() {
  # Get file name
  filename <- get_user_input("Enter File Name: ")
  if (filename == "" || is.na(filename)) {
    filename <- "listing"
  }
  
  # Check if file exists
  if (!file.exists(filename)) {
    stop(paste("Cannot open file:", filename))
  }
  
  # Get parameters from user
  numpt <- as.numeric(get_user_input("Enter Number of Data Points: "))
  numbit <- as.numeric(get_user_input("Enter ADC Resolution: "))
  mid_code <- as.numeric(get_user_input("Enter Mid-Code (Mean Code): "))
  
  # Read file and skip header lines
  con <- file(filename, "r")
  for (i in 1:13) {
    readLines(con, n = 1)
  }
  
  # Read data
  data_lines <- readLines(con, n = numpt)
  close(con)
  
  # Parse data
  data_matrix <- NULL
  for (i in 1:length(data_lines)) {
    line <- trimws(data_lines[i])
    if (line != "" && !startsWith(line, "#")) {
      values <- as.numeric(unlist(strsplit(line, "\\s+")))
      values <- values[!is.na(values)]
      if (length(values) >= 2) {
        data_matrix <- rbind(data_matrix, values[1:2])
      }
    }
  }
  
  # Extract code values
  if (is.null(data_matrix) || nrow(data_matrix) == 0) {
    stop("No valid data found in file")
  }
  code <- data_matrix[, 2]
  code <- code[!is.na(code)]
  
  # Initialize code count array
  total_codes <- 2^numbit
  code_count <- rep(0, total_codes)
  
  # Count occurrences of each code
  for (i in 1:length(code)) {
    code_idx <- code[i] + 1
    if (code_idx >= 1 && code_idx <= total_codes) {
      code_count[code_idx] <- code_count[code_idx] + 1
    }
  }
  
  # Check for proper clipping
  if (code_count[1] == 0 || code_count[total_codes] == 0 ||
      (code_count[1] < code_count[2]) || (code_count[total_codes-1] > code_count[total_codes])) {
    cat("ADC not clipping ... Increase sinewave amplitude!\n")
    return(NULL)
  }
  
  # Calculate sine wave amplitude
  A <- max(mid_code, total_codes-1-mid_code) + 0.1
  vin <- (0total_codes-1)) - mid_code
  
  # Calculate theoretical histogram for sine wave
  calculate_sin2ramp <- function(A, vin) {
    valid_indices <- which(A^2 - vin^2 > 1e-10)
    sin2ramp <- rep(0, length(vin))
    if (length(valid_indices) > 0) {
      sin2ramp[valid_indices] <- 1 / (pi * sqrt(A^2 - vin[valid_indices]^2))
    }
    return(sin2ramp)
  }
  
  sin2ramp <- calculate_sin2ramp(A, vin)
  
  # Adjust amplitude until theoretical matches measured
  max_iterations <- 1000
  iteration <- 0
  while (sum(code_count[2total_codes-1)]) < numpt * sum(sin2ramp[2total_codes-1)]) && iteration < max_iterations) {
    A <- A + 0.1
    sin2ramp <- calculate_sin2ramp(A, vin)
    iteration <- iteration + 1
  }
  
  cat("You Have Applied a Sine Wave of (dBFS):\n")
  Amplitude <- A / (total_codes/2)
  cat("Amplitude =", Amplitude, "\n")
  
  # Normalize histogram (exclude end points)
  denominator <- numpt * sin2ramp[2:(total_codes-1)]
  denominator[denominator < 1e-10] <- 1e-10
  code_countn <- code_count[2:(total_codes-1)] / denominator
  
  # Calculate DNL
  dnl <- code_countn - 1
  
  # Calculate INL
  inl <- rep(0, length(dnl))
  for (j in 1:length(inl)) {
    inl[j] <- sum(dnl[1:j])
  }
  
  # Best-straight-line fit INL
  x_fit <- 1:(total_codes-2)
  fit_model <- lm(inl ~ x_fit)
  inl <- inl - predict(fit_model)
  
  cat("End Points Eliminated for DNL and INL Calculations\n")
  
  # Create a 2x2 plot layout
  par(mfrow = c(2, 2))
  
  # Plot 1: Code histogram
  x_codes <- 0:(total_codes-1)
  plot(x_codes, code_count, type = "l", col = "blue",
       main = "CODE HISTOGRAM - SINE WAVE",
       xlab = "DIGITAL OUTPUT CODE",
       ylab = "COUNTS",
       xlim = c(0, total_codes-1),
       ylim = c(0, max(code_count[2], code_count[total_codes])))
  lines(x_codes, sin2ramp * numpt, col = "red")
  legend("topright", legend = c("Measured", "Theoretical"),
         col = c("blue", "red"), lty = 1, cex = 0.8)
  
  # Plot 2: Normalized histogram
  plot(1:(total_codes-2), code_countn, type = "l", col = "blue",
       main = "CODE HISTOGRAM - NORMALIZED",
       xlab = "DIGITAL OUTPUT CODE",
       ylab = "NORMALIZED COUNTS")
  
  # Plot 3: DNL
  plot(1:(total_codes-2), dnl, type = "l", col = "blue",
       main = "DIFFERENTIAL NONLINEARITY",
       xlab = "DIGITAL OUTPUT CODE",
       ylab = "DNL (LSB)")
  grid()
  
  # Plot 4: INL
  plot(1:(total_codes-2), inl, type = "l", col = "blue",
       main = "INTEGRAL NONLINEARITY",
       xlab = "DIGITAL OUTPUT CODE",
       ylab = "INL (LSB)")
  grid()
  
  # Reset plot layout
  par(mfrow = c(1, 1))
  
  # Display summary statistics
  cat("\nSummary Statistics:\n")
  cat("DNL Max:", sprintf("%.3f", max(dnl)), "LSB\n")
  cat("DNL Min:", sprintf("%.3f", min(dnl)), "LSB\n")
  cat("INL Max:", sprintf("%.3f", max(inl)), "LSB\n")
  cat("INL Min:", sprintf("%.3f", min(inl)), "LSB\n")
  
  # Return results
  return(list(dnl = dnl, inl = inl, amplitude = Amplitude))
}

# Run the test
cat("ADC INL/DNL Test Program\n")
cat("========================\n")
cat("To run the test, execute: result <- adc_inl_dnl_test()\n")
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

关闭

站长推荐 上一条 /1 下一条

手机版| 小黑屋| 关于我们| 联系我们| 隐私声明| EETOP 创芯网
( 京ICP备:10050787号 京公网安备:11010502037710 )

GMT+8, 2025-8-9 13:36 , Processed in 0.022689 second(s), 5 queries , Gzip On, Redis On.

eetop公众号 创芯大讲堂 创芯人才网
快速回复 返回顶部 返回列表