|
发表于 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 <- (0 total_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[2 total_codes-1)]) < numpt * sum(sin2ramp[2 total_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") |
|