|
|
%% ADC和PLL输出结果FFT频谱分析程序
% 作者:MATLAB助手
% 功能:对ADC和PLL输出信号进行频谱分析
% 说明:可以处理实际数据或生成测试信号进行分析
clear; clc; close all;
%% 1. 参数设置
Fs = 100e6; % 采样频率 (Hz)
Ts = 1/Fs; % 采样间隔
N = 8192; % 采样点数 (FFT长度)
f0 = 10e6; % 信号频率 (Hz)
Amplitude = 1.0; % 信号幅度
% ADC参数
adc_bits = 12; % ADC位数
adc_vref = 2.0; % ADC参考电压 (V)
adc_noise_rms = 0.01; % ADC噪声RMS值
% PLL参数
pll_phase_noise = -100; % PLL相位噪声 (dBc/Hz @ offset)
pll_jitter_rms = 1e-12; % PLL抖动RMS值 (秒)
%% 2. 生成测试信号 (如果无实际数据)
% 生成理想的模拟信号
t = (0:N-1)*Ts; % 时间向量
analog_signal = Amplitude * sin(2*pi*f0*t);
% 添加噪声
noise = randn(1, N) * adc_noise_rms;
analog_signal_noisy = analog_signal + noise;
%% 3. ADC量化过程模拟
% 计算ADC量化步长
adc_lsb = adc_vref / (2^adc_bits);
% 量化信号 (模拟ADC采样和量化)
adc_signal = round(analog_signal_noisy / adc_lsb) * adc_lsb;
% 添加ADC量化误差
quantization_error = adc_signal - analog_signal_noisy;
%% 4. PLL输出信号生成 (模拟频率合成)
% 添加相位噪声模拟PLL输出
phase_noise = pll_jitter_rms * randn(1, N) * 2*pi*f0;
pll_signal = Amplitude * sin(2*pi*f0*t + phase_noise);
% PLL信号也经过ADC量化
pll_adc_signal = round(pll_signal / adc_lsb) * adc_lsb;
%% 5. FFT频谱分析函数
function [freq, spectrum, dB_spectrum] = perform_fft_analysis(signal, Fs, window_type)
% 对信号进行FFT分析
N = length(signal);
% 选择窗函数
switch window_type
case 'hann'
win = hann(N)';
case 'hamming'
win = hamming(N)';
case 'blackman'
win = blackman(N)';
otherwise
win = ones(1, N); % 矩形窗
end
% 加窗
windowed_signal = signal .* win;
% FFT计算
fft_result = fft(windowed_signal, N);
% 计算单边频谱
spectrum = abs(fft_result/N);
spectrum = spectrum(1:floor(N/2)+1);
spectrum(2:end-1) = 2*spectrum(2:end-1);
% 转换为dB
dB_spectrum = 20*log10(spectrum);
% 频率向量
freq = (0:floor(N/2)) * Fs/N;
end
%% 6. 分析ADC信号
% 执行FFT分析
window_type = 'hann'; % 选择窗函数
[freq_adc, spectrum_adc, dB_spectrum_adc] = perform_fft_analysis(adc_signal, Fs, window_type);
% 找到信号峰值
[adc_peak_val, adc_peak_idx] = max(dB_spectrum_adc(2:end)); % 忽略DC
adc_peak_freq = freq_adc(adc_peak_idx + 1);
%% 7. 分析PLL信号
% 执行FFT分析
[freq_pll, spectrum_pll, dB_spectrum_pll] = perform_fft_analysis(pll_adc_signal, Fs, window_type);
% 找到信号峰值
[pll_peak_val, pll_peak_idx] = max(dB_spectrum_pll(2:end)); % 忽略DC
pll_peak_freq = freq_pll(pll_peak_idx + 1);
%% 8. 计算性能指标
function metrics = calculate_metrics(dB_spectrum, freq, peak_idx, Fs, N)
% 计算各种频谱性能指标
% 信号功率
signal_power_dB = dB_spectrum(peak_idx);
% 计算噪声基底
% 排除信号区域和DC附近的频点
exclude_bandwidth = 100; % 排除带宽 (Hz)
exclude_bins = ceil(exclude_bandwidth / (Fs/N));
noise_start = 10; % 从第10个频点开始,避开DC
noise_end = length(dB_spectrum);
% 创建噪声掩码
noise_mask = true(1, noise_end);
noise_mask(max(1, peak_idx-exclude_bins):min(noise_end, peak_idx+exclude_bins)) = false;
noise_mask(1:noise_start) = false;
% 计算噪声功率
noise_dB = dB_spectrum(noise_mask);
noise_floor = mean(noise_dB);
noise_std = std(noise_dB);
% 计算SFDR (无杂散动态范围)
% 查找除主信号外的最高峰值
search_range = 1:length(dB_spectrum);
search_range(peak_idx) = []; % 移除主信号
[spur_val, spur_idx] = max(dB_spectrum(search_range));
sfdr = signal_power_dB - spur_val;
% 计算SNR (估算)
% 假设信号带宽为1个bin
signal_bw_bins = 1;
signal_bins = max(1, peak_idx-signal_bw_bins):min(length(dB_spectrum), peak_idx+signal_bw_bins);
% 计算信号功率 (线性)
signal_linear = 10.^(dB_spectrum(signal_bins)/20);
signal_power_linear = sum(signal_linear.^2);
% 计算噪声功率
noise_linear = 10.^(noise_dB/20);
noise_power_linear = sum(noise_linear.^2);
% SNR计算
snr_linear = signal_power_linear / (noise_power_linear/length(noise_dB)*length(signal_bins));
snr_dB = 10*log10(snr_linear);
% 返回指标结构体
metrics.signal_power_dB = signal_power_dB;
metrics.noise_floor = noise_floor;
metrics.noise_std = noise_std;
metrics.sfdr = sfdr;
metrics.snr_dB = snr_dB;
metrics.fundamental_freq = freq(peak_idx);
end
% 计算ADC信号指标
adc_metrics = calculate_metrics(dB_spectrum_adc, freq_adc, adc_peak_idx, Fs, N);
% 计算PLL信号指标
pll_metrics = calculate_metrics(dB_spectrum_pll, freq_pll, pll_peak_idx, Fs, N);
%% 9. 绘制结果
% 设置图形参数
figure('Position', [100, 100, 1200, 800]);
% 子图1: 原始信号时域图
subplot(3, 2, 1);
plot(t(1:200)*1e6, analog_signal(1:200), 'b', 'LineWidth', 1.5);
hold on;
plot(t(1:200)*1e6, adc_signal(1:200), 'r--', 'LineWidth', 1);
xlabel('时间 (\mu s)');
ylabel('幅度 (V)');
title('ADC输入输出时域信号');
legend('模拟输入', 'ADC输出', 'Location', 'best');
grid on;
% 子图2: PLL时域信号
subplot(3, 2, 2);
plot(t(1:200)*1e6, pll_signal(1:200), 'g', 'LineWidth', 1.5);
xlabel('时间 (\mu s)');
ylabel('幅度 (V)');
title('PLL输出时域信号');
grid on;
% 子图3: ADC信号频谱
subplot(3, 2, 3);
semilogx(freq_adc(2:end)/1e6, dB_spectrum_adc(2:end), 'b', 'LineWidth', 1.5);
xlabel('频率 (MHz)');
ylabel('幅度 (dB)');
title('ADC输出频谱');
grid on;
xlim([freq_adc(2)/1e6, Fs/2/1e6]);
% 标记信号频率
hold on;
plot(adc_metrics.fundamental_freq/1e6, adc_metrics.signal_power_dB, 'ro', ...
'MarkerSize', 10, 'LineWidth', 2);
text(adc_metrics.fundamental_freq/1e6, adc_metrics.signal_power_dB+5, ...
sprintf('f0=%.3fMHz\n%.1f dB', adc_metrics.fundamental_freq/1e6, adc_metrics.signal_power_dB), ...
'FontSize', 8);
% 子图4: PLL信号频谱
subplot(3, 2, 4);
semilogx(freq_pll(2:end)/1e6, dB_spectrum_pll(2:end), 'r', 'LineWidth', 1.5);
xlabel('频率 (MHz)');
ylabel('幅度 (dB)');
title('PLL输出频谱');
grid on;
xlim([freq_pll(2)/1e6, Fs/2/1e6]);
% 标记信号频率
hold on;
plot(pll_metrics.fundamental_freq/1e6, pll_metrics.signal_power_dB, 'bo', ...
'MarkerSize', 10, 'LineWidth', 2);
text(pll_metrics.fundamental_freq/1e6, pll_metrics.signal_power_dB+5, ...
sprintf('f0=%.3fMHz\n%.1f dB', pll_metrics.fundamental_freq/1e6, pll_metrics.signal_power_dB), ...
'FontSize', 8);
% 子图5: 频谱细节对比
subplot(3, 2, [5, 6]);
plot(freq_adc/1e6, dB_spectrum_adc, 'b', 'LineWidth', 1.5);
hold on;
plot(freq_pll/1e6, dB_spectrum_pll, 'r--', 'LineWidth', 1.5);
xlabel('频率 (MHz)');
ylabel('幅度 (dB)');
title('ADC vs PLL频谱对比');
legend('ADC输出', 'PLL输出', 'Location', 'best');
grid on;
xlim([0, Fs/2/1e6]);
% 添加标注
annotation('textbox', [0.15, 0.02, 0.3, 0.1], 'String', ...
sprintf('ADC指标:\nSNR: %.1f dB\nSFDR: %.1f dB\n噪声基底: %.1f ± %.1f dB', ...
adc_metrics.snr_dB, adc_metrics.sfdr, adc_metrics.noise_floor, adc_metrics.noise_std), ...
'FontSize', 9, 'EdgeColor', 'blue', 'BackgroundColor', [0.9, 0.9, 1]);
annotation('textbox', [0.6, 0.02, 0.3, 0.1], 'String', ...
sprintf('PLL指标:\nSNR: %.1f dB\nSFDR: %.1f dB\n噪声基底: %.1f ± %.1f dB', ...
pll_metrics.snr_dB, pll_metrics.sfdr, pll_metrics.noise_floor, pll_metrics.noise_std), ...
'FontSize', 9, 'EdgeColor', 'red', 'BackgroundColor', [1, 0.9, 0.9]);
%% 10. 相位噪声分析 (针对PLL)
% 提取相位噪声信息
if exist('pll_signal', 'var')
figure('Position', [100, 100, 800, 600]);
% 计算相位噪声
% 使用Hilbert变换提取瞬时相位
analytic_signal = hilbert(pll_signal);
instantaneous_phase = unwrap(angle(analytic_signal));
ideal_phase = 2*pi*f0*t;
phase_noise_rad = instantaneous_phase - ideal_phase;
% 对相位噪声进行FFT
[freq_phase, ~, dB_phase_noise] = perform_fft_analysis(phase_noise_rad, Fs, 'hann');
% 转换为dBc/Hz
% 注意:这里简化处理,实际需要更精确的归一化
dBc_per_Hz = dB_phase_noise - 10*log10(Fs/N);
% 绘制相位噪声曲线
semilogx(freq_phase(2:end)/1e6, dBc_per_Hz(2:end), 'LineWidth', 1.5);
xlabel('频率偏移 (MHz)');
ylabel('相位噪声 (dBc/Hz)');
title('PLL相位噪声分析');
grid on;
xlim([freq_phase(2)/1e6, Fs/2/1e6/100]); % 只显示低频部分
% 添加参考线
hold on;
plot([1e-3, 1e3], [pll_phase_noise, pll_phase_noise], 'r--', 'LineWidth', 1);
text(1e-2, pll_phase_noise+5, sprintf('目标: %.0f dBc/Hz', pll_phase_noise), ...
'FontSize', 10, 'Color', 'red');
end
%% 11. 保存结果
% 保存频谱数据
results.adc.freq = freq_adc;
results.adc.spectrum = dB_spectrum_adc;
results.adc.metrics = adc_metrics;
results.pll.freq = freq_pll;
results.pll.spectrum = dB_spectrum_pll;
results.pll.metrics = pll_metrics;
results.parameters.Fs = Fs;
results.parameters.N = N;
results.parameters.f0 = f0;
results.parameters.adc_bits = adc_bits;
% 保存到文件
save('fft_analysis_results.mat', 'results');
%% 12. 显示总结信息
fprintf('\n========== FFT频谱分析结果 ==========\n');
fprintf('采样频率: %.1f MHz\n', Fs/1e6);
fprintf('采样点数: %d\n', N);
fprintf('FFT分辨率: %.1f Hz\n', Fs/N);
fprintf('信号频率: %.3f MHz\n\n', f0/1e6);
fprintf('ADC信号分析:\n');
fprintf(' 信号功率: %.1f dB\n', adc_metrics.signal_power_dB);
fprintf(' 信噪比(SNR): %.1f dB\n', adc_metrics.snr_dB);
fprintf(' 无杂散动态范围(SFDR): %.1f dB\n', adc_metrics.sfdr);
fprintf(' 噪声基底: %.1f ± %.1f dB\n\n', adc_metrics.noise_floor, adc_metrics.noise_std);
fprintf('PLL信号分析:\n');
fprintf(' 信号功率: %.1f dB\n', pll_metrics.signal_power_dB);
fprintf(' 信噪比(SNR): %.1f dB\n', pll_metrics.snr_dB);
fprintf(' 无杂散动态范围(SFDR): %.1f dB\n', pll_metrics.sfdr);
fprintf(' 噪声基底: %.1f ± %.1f dB\n', pll_metrics.noise_floor, pll_metrics.noise_std);
fprintf('\n分析完成!结果已保存到 fft_analysis_results.mat\n'); |
|