ADC频谱分析
clear;
afs = 1; % 1V full scale
fs = 1e6; % 1MHz sample rate
N = 2^10; % number of samples
cyc = 67;
fx = fs*cyc/N;
t = linspace(0,(N-1)/fs,N);
y = afs*sin(2*pi*fx*t);
B = 10; % internal ADC resolution
delta = afs/2^B;
y = cos(2*pi*fx/fs*[0:N-1]);
%quantize samples to delta=1LSB
y=round(y/delta)*delta;
s = 20*log10(abs(fft(y)/N/afs*2));
s = s(1:N/2); % drop redundant half
f = (0:length(s)-1) / N; % frequency vector (normalized to fs)
figure(1);
plot(f,s);
grid on;
因为log0了
s = 20*log10(abs(fft(y)/N/afs*2));
这一行不要这么写
先fft,然后设一个门限,将低于门限的值都设成门限值,这样就避免了0的出现,再取log
是的,但是fft为什么会产生0?如果不做量化,fft输出是正常的,量化以后就产生0了。
那你告诉我为什么不应该出现0?
没有手算过,只是直觉上感觉不应该出现0。
另外附件的文档中有类似的程序,直接截取了前半个频率范围的fft输出画图,可见没有fft输出没有0.
因为有限的点数,加上截断误差等,凑巧在某个点上出现0,这没什么,并不能代表那个对应的频点就真是零。
你也不必纠结这事
但是对fft结果计算SNR,10-bit量化只有40多dB,说明还是哪里出问题了。
贴个图和计算程序
clear;
afs = 1; % 1V full scale
fs = 1e6; % 1MHz sample rate
N = 2^11; % number of samples
cyc = 67;
fx = fs*cyc/N;
t = linspace(0,(N-1)/fs,N);
B = 10; % internal ADC resolution
delta = afs/2^B;
y = cos(2*pi*fx/fs*[0:N-1]);
%quantize samples to delta=1LSB
y=round(y/delta)*delta;
s = abs(fft(y)/N/afs*2);
sdb = 20*log10(s);
sdb = sdb(1:N/2); % drop redundant half
s = s(1:N/2); % drop redundant half
f = (0:length(sdb)-1) / N; % frequency vector (normalized to fs)
bx = N*fx/fs+1;
As = 10*log10(s(bx)^2);
%set signal bin to 0
s(bx) = 0;
An = 20*log10(sum(s));
SNR = As - An;
figure(1);
plot(f,sdb);
grid on;
text_handle = text(0.3,-30, sprintf('SNR = %4.1fdB\n',SNR));
信号就一个频点?
功率谱密度,求噪声的时候平方后相加,an=10*log10(sum(s.^2))。
另外,你这是11bit的,delta(LSB)=afs/2^B,想要10bit应该是B-1。
信号上加个小的噪声,没有inf,你这个图就会好看多了。
谢谢!确实如你指出:1.程序中应该是11位量化;2. 噪声功率计算错了,更正之后SNR和预期一致;3.加小的噪声后再量化就可以得到好看的频谱(见附件)。
我这个附件怎么不完整?
还是有问题,加入噪声之后,有时候可以画出连续的频谱(fft没有0),有时候还是和原来一样的结果。同样的程序!
加太小了?
虽然在仿真的时候可以保证coherent sampling,但是还是建议加窗。量化"噪声"不是真正的噪声,所以它是只存在特定的频率bin上的,加窗之后这些bin的量化噪声能量会leakage 到旁边能量为0的bin上
但是加了噪声之后还有0很奇怪
确实和大小有关系,大一点fft结果就不会出现0.
谢谢建议,一会试试。
我认为加太小的噪声round的时候可能舍去了,所以仍然有0.