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

EETOP 创芯网论坛 (原名:电子顶级开发网)

手机号码,快捷登录

手机号码,快捷登录

找回密码

  登录   注册  

快捷导航
搜帖子
查看: 2178|回复: 1

[求助] adc的fft仿真

[复制链接]
发表于 2020-8-18 11:20:00 | 显示全部楼层 |阅读模式

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

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

x
本帖最后由 kongc 于 2020-8-18 11:38 编辑

最近在做一个saradc的fft仿真,在网上找的matlab代码,加上自己的数据,发现得到的频谱图很离谱,有没有大佬有兴趣拿着代码和数据试一下,帮我看看哪里出错了?,谢谢!



  1. %***********************************************************************%
  2. % The following program code plots the FFT spectrum of a desired test tone.
  3. % Test tone based on coherent sampling criteria, and computes SNR, SNDR, THD and SFDR.
  4. % This program is believed to be accurate and reliable.
  5. % This program may get altered without prior notification.;
  6. % Company: xxx Analog Mixed-signal Group
  7. % Author:
  8. % Date: 2016-01-09
  9. %***********************************************************************%




  10. %***********************************************************************%
  11. % 采样时钟240MHz,输入信号频率86.25MHz,FFT点数64,ADC分辨率10bit,仿真时间400ns。
  12. % 从cadence输出时间隔是4.16666667ns,共计97个点,从第20个点开始取64点做FFT。
  13. % cadence输出的是归一化的结果范围是0-1.6V,需除以1.6再乘以1024,转换为数字码。
  14. %***********************************************************************%




  15. clear all;
  16. close all;
  17. %spectP_file='spec.csv';




  18. %***********************************************************************%
  19. % 输入采样时钟、样本点数、分辨率等变量
  20. %***********************************************************************%
  21. fs=100e6;        %采样时钟
  22. Data_Num=32768;   %样本点数
  23. numbit=12;       %ADC分辨率
  24. data_start=1; %取点起始位置
  25. fclk=fs/1e6;     %x坐标轴数值显示
  26. numpt=Data_Num;
  27. fres=fclk/numpt; %Desired frequency resolution of FFT[MHz], fres=fclk/2^N


  28. %***********************************************************************%
  29. % 读取数据
  30. %***********************************************************************%
  31. %d_in=dlmread('E:\kongcaho\ADC\MATLAB\adc_data_0715.csv','%s')';
  32. %d_in=d_in*2^numbit;

  33. d_in=csvread('E:\kongcaho\ADC\MATLAB\adc_data.csv');%以字符形式打开文件
  34. d11=1;d10=2;d9=3;d8=4;d7=5;d6=6;d5=7;d4=8;d3=9;d2=10;d1=11;d0=12;%标示样本矩阵的列
  35. vref=1;
  36. %adc_data=d_in;
  37. adc_data=round(d_in);

  38. for i=1:numpt
  39.     dout(i)=adc_data(i,d11)/2+adc_data(i,d10)/4+adc_data(i,d9)/8 ...
  40.     +adc_data(i,d8)/16+adc_data(i,d7)/32+adc_data(i,d6)/64 ...
  41.     +adc_data(i,d5)/128+adc_data(i,d4)/254+adc_data(i,d3)/512 ...
  42.     +adc_data(i,d2)/1024+adc_data(i,d1)/2048+adc_data(i,d0)/4096;%通过转换器出来的结果,恢复原来的波形
  43.     doute(i)=dout(i)-0.5;%将正弦波的共模电平偏置为0
  44.     %doute(i)=dout(i)-mean(dout(i));
  45. end


  46. code=zeros(1,numpt);  %创建一个全为0元素的数组
  47. %for i=1:1:numpt
  48. %code(1:numpt)=d_in(data_start:data_start+numpt-1);
  49. %end
  50. for i=1:numpt
  51.     code(i)=adc_data(i,d11)*2048+adc_data(i,d10)*1024+adc_data(i,d9)*512 ...
  52.     +adc_data(i,d8)*256+adc_data(i,d7)*128+adc_data(i,d6)*64+adc_data(i,d5)*32 ...
  53.     +adc_data(i,d4)*16+adc_data(i,d3)*8+adc_data(i,d2)*4+adc_data(i,d1)*2+adc_data(i,d0)*1;%通过转换器出来的结果,恢复原来的波形
  54.    
  55. end

  56. dcadc(code,numpt);

  57. %***********************************************************************%
  58. % Plot output code
  59. %***********************************************************************%
  60. figure;
  61. plot(code);
  62. title(sprintf('ADC Digital Output'));


  63. figure;
  64. plot(dout);
  65. title(sprintf('ADC ANALOG Output'));


  66. %***********************************************************************%
  67. % Recenter the digital sine wave, for 2's complement code
  68. %***********************************************************************%
  69. %m_ean=mean(code);   %求code数组的平均值
  70. %for hk=1:length(code)
  71. %    code(hk)=code(hk)-m_ean;
  72. %end


  73. %***********************************************************************%
  74. % Display a warning, when the input generates a code greater than
  75. % full-scale, for 2's complement code
  76. %***********************************************************************%
  77. max_code=max(code)
  78. min_code=min(code)
  79. if (max(code)==2^numbit-1) | (min(code)==0)
  80. %if (max(code)==2^numbit -1) | (min(code)==0)
  81.     disp('Warning: ADC may be clipping!');
  82. end


  83. %***********************************************************************%
  84. % Normalize input signal relative to full-scale
  85. %***********************************************************************%
  86. fin_dB=20*log10((max_code-min_code)/(2^numbit));


  87. %***********************************************************************%
  88. % 对数据样本加窗函数处理
  89. %***********************************************************************%
  90. % If no window function is used, the input tone must be chosen to be unique and with
  91. % regard to the sampling frequency. To achieve this prime numbers are introduced and the
  92. % input tone is determined by Fin = Fsample * (Prime Number / Data Record Size).
  93. % To relax this requirement, window functions such as HANNING and HAMING (see below) can
  94. % be introduced, however the fundamental in the resulting FFT spectrum appears 'sharper'
  95. %without the use of window functions.
  96. Dout=doute';
  97. %Doutw=Dout;
  98. Doutw=Dout.*hanning(numpt);
  99. % Doutw=Dout.*hamming(numpt);
  100. % Doutw=Dout.*blackman(numpt);


  101. %***********************************************************************%
  102. % Performing the Fast Fourier Transform [FFT]
  103. %***********************************************************************%
  104. %span=5;     %Span of the input frequency on each side;
  105. span=max(round(numpt/200),5);
  106. spanh=2;    %Approximate search span for harmonics on each side
  107. spandc=12;   %Approximate search span for DC on right side
  108. Dout_spect=fft(Doutw);
  109. Dout_dB=20*log10(abs(Dout_spect)); %Recalculate to dB abs(Dout_spect)
  110. spectP=(abs(Dout_spect)).*(abs(Dout_spect)); %Determine power spectrum
  111. maxdB=max(Dout_dB(1+spandc:numpt/2));
  112. fin=find(Dout_dB(1:numpt/2)==maxdB); %Find the signal bin number, DC=bin1
  113. %fin=200;

  114. %***********************************************************************%
  115. % Calculate SNR, SNDR, THD and SFDR values.
  116. %***********************************************************************%
  117. %fw=fopen(spectP_file,'w'); %write the power soectrum to file
  118. %fprintf(fw,'%12.9e\n',spectP);
  119. %fclose('all');
  120. %Find DC offset power
  121. Pdc=sum(spectP(1:span));
  122. %Extract overall signal power
  123. idx1=fin-span;
  124. idx2=fin+span;
  125. if(idx1<=0)
  126.     idx1 = 1;
  127. end
  128. Ps=sum(spectP(idx1:idx2));    %信号功率
  129. %Vector/matrix to store both frequency and power of signal and harmonics
  130. Fh=[];
  131. %The 1st element in the vector/matrix represents the signal, the next element represents the 2nd harmonic
  132. Ph=[];
  133. %Vector/matrix to store the sampling points responding to the harmonics
  134. Nh=[];
  135. %Ah represents signal and harmonic amplitude
  136. Ah=[];
  137. %Find harmonic frequencies and power components in the FFT spectrum
  138. %For this procedure to work, ensure the folded back high order harmonics do not overlap
  139. %with DC or signal or lower order harmonics , so it should be modified according to the actual condition
  140. for har_num=1:5
  141.     tone=rem((har_num*(fin-1)+1)/numpt,1); %Input tones greater than fSAMPLE are aliased back into the spectrum
  142.     if tone>0.5
  143.         tone=1-tone; %Input tones greater than 0.5*Fsample (aft er aliasing) are reflected
  144.     end
  145.     Fh=[Fh tone];
  146.     %Check Nh to see the bin of the harmonics
  147.     Nh=[Nh round(tone*numpt)];
  148.     %For this procedure to work, ensure the folded back high order harmonics do not overlap
  149.     %with DC or signal or lower order harmonics
  150.     har_peak=max(spectP(round(tone*numpt)-spanh:round(tone*numpt)+spanh));
  151.     har_bin=find(spectP(round(tone*numpt)-spanh:round(tone*numpt)+spanh)==har_peak);
  152.     har_bin=har_bin+round(tone*numpt)-spanh-1;
  153.     Ph=[Ph sum(spectP(har_bin-spanh:har_bin+spanh))];
  154.     Ah=[Ah Dout_dB(har_bin)];
  155. end
  156. %Determine the total distortion power, it should be modified according to the actual condition.
  157. Pd=sum(Ph(2:5));                      %总谐波功率
  158. %Determine the noise power
  159. Pn=sum(spectP(1:numpt/2))-Pdc-Ps-Pd;  %噪声功率
  160. %Determine the next largest component
  161. spur_max=max(max(spectP(spandc+1:fin-span-1)),max(spectP(fin+span+1:numpt/2)));
  162. spur_bin=find(spectP(1:numpt/2)==spur_max);
  163. %**********************计算动态特性结果**********************%
  164. format; %设置输出格式
  165. SFDR = 10*log10(max(spectP(1:numpt/2))/spur_max); %-fin_dB
  166. THD = 10*log10(Pd/Ps); %+fin_dB
  167. SNR = 10*log10(Ps/Pn); %-fin_dB
  168. SNDR = 10*log10(Ps/(Pn+Pd)); %-fin_dB
  169. ENOB = (SNDR-1.76)/6.02;
  170. %disp('Note: THD is calculated from 2nd through 10th order harmonics.');
  171. %*********************标示信号和谐波位置*********************%
  172. %hold on;
  173. %plot((Nh(2:10)-1).*fres,Ah(2:10)-maxdB+fin_dB,'rs');
  174. % 标示信号
  175. bins=(Nh(1)-1)*fres;
  176. Ahs=Ah(1)-maxdB+fin_dB;
  177. % 标示2次谐波
  178. bin2=(Nh(2)-1)*fres;
  179. Ah2=Ah(2)-maxdB+fin_dB;
  180. % 标示3次谐波
  181. bin3=(Nh(3)-1)*fres;
  182. Ah3=Ah(3)-maxdB+fin_dB;
  183. % 标示4次谐波
  184. bin4=(Nh(4)-1)*fres;
  185. Ah4=Ah(4)-maxdB+fin_dB;   
  186. % 标示5次谐波
  187. bin5=(Nh(5)-1)*fres;
  188. Ah5=Ah(5)-maxdB+fin_dB;
  189. % 在FFT频谱图中追加标示
  190. figure;
  191. plot(bins,Ahs,'rs',bin2,Ah2,'rd',bin3,Ah3,'r^',bin4,Ah4,'r*',bin5,Ah5,'rx');
  192. legend('SINGAL','HD2','HD3','HD4','HD5');
  193. %**********************图表显示**********************%
  194. ylabel('Full-Scale Normalized Magnitude[dB]')
  195. xlabel('Frequency [MHz]')
  196. title(sprintf('ADC FFT Spectrum (%g points)\nFs = %g MSps, Fin = %g MHz (%1.2gdBFS)', Data_Num,fs/1e6,(fin-1)*fres,fin_dB));
  197. grid on;
  198. box on;
  199. ylim([-110 100]);
  200. set(gca,'xgrid', 'off');
  201. set(gca, 'GridLineStyle' ,'-');
  202. set(gca,'yTick',[-110:10:100]);
  203. %****************************************************%
  204. %Display the results in the frequency domAIn with an FFT plot.
  205. for i=0:1:(numpt/2-1)
  206.     hold on;
  207.     line([i*fres,i*fres],[-110,Dout_dB(i+1)-maxdB+fin_dB],'LineWidth',2);
  208.     hold off;
  209. end
  210. %***********************在图中打印结果***********************%
  211. hold on;
  212. s1=sprintf('SFDR = %4.1fdB\n',SFDR);
  213. s2=sprintf('THD = %4.1fdB\n',THD);
  214. s3=sprintf('SNR   = %4.1fdB\n',SNR);
  215. s4=sprintf('SNDR = %4.1fdB\n',SNDR);
  216. s5=sprintf('ENOB = %4.2fbit\n',ENOB);
  217. text(25,-10,s1);
  218. text(25,-20,s2);
  219. text(25,-30,s3);
  220. text(25,-40,s4);
  221. text(25,-50,s5);
  222. hold off;


复制代码




  1. function[DNL,INL,vo]=dcdac(vi,num);
  2. %vi_in=dlmread('E:\kongcaho\ADC\MATLAB\adc_data_0715.csv','%s')';
  3. %num=4096;
  4. vi_f=vi;

  5. format long;
  6. bit=12;%ADC精度
  7. n=2^bit;%ADC输出码数目
  8. N_negetive=0;%高于0的采样总数
  9. N_positive=0;%低于0的采样总数
  10. N_tot=0;%总采样数目
  11. A=0.5;%正弦波幅度
  12. temp=vi_f ; %读入数
  13. %-----------------------------------------------%
  14. %计算每个码的统计次数
  15. %-----------------------------------------------%
  16. hh=zeros(n,1);
  17. for i=1:2^bit
  18.     count=0;%附值
  19.     for j=1:num
  20.         if temp(j)==i-1
  21.             count=count+1;
  22.         else count=count;
  23.         end
  24.     end
  25.     hh(i)=count;
  26. end
  27. h=[hh(1:2^bit)];
  28. LSB=A*2.0/(2^bit);%理想LSB
  29. %-----------------------------------------------%
  30. %计算offset:vo
  31. %-----------------------------------------------%
  32. N_negetive=sum(hh(1:n/2));
  33. N_positive=sum(hh(n/2+1:n));
  34. N_tot=sum(hh(1:n))
  35. vo=A*pi/2*sin((N_positive-N_negetive)/N_tot)
  36. %-----------------------------------------------%
  37. %计算INL、DNL
  38. %-----------------------------------------------%
  39. ch=zeros(n,1);
  40. v=zeros(n,1);%possibility of the ith code occurs
  41. in=zeros(n,1);%每级台阶的INL
  42. dn=zeros(n,1);%每级台阶的DNL
  43. for i=1:n
  44.     for j=1:i
  45.         ch(i)=ch(i)+h(j);
  46.     end
  47.     v(i)=-cos(pi*ch(i)/N_tot);
  48. end
  49. LSB=(v(n-1)-v(2))/(n-3);%实际LSB
  50. for i=1:n-1
  51.     in(i)=v(i)/LSB-i+1024;
  52.   %  in(i)=(v(i)-vo)/LSB-i+2048;
  53.     dn(i)=(v(i+1)-v(i))/LSB-1;
  54. end
  55. INL=max(abs(in))
  56. DNL=max(abs(dn))
  57. %-----------------------------------------------%
  58. %初始化转移曲线坐标
  59. %-----------------------------------------------%
  60. vv(1)=-A;
  61. vv(2)=v(1);
  62. xx(1)=0;
  63. xx(2)=0;
  64. vv(2*(n-1)+1)=v(n-1);
  65. xx(2*(n-1)+1)=n-1;
  66. for i=1:n-2
  67.     vv(2*i+1)=v(i);
  68.     vv(2*i+2)=v(i+1);
  69.     xx(2*i+1)=i;
  70.     xx(2*i+2)=i;
  71. end
  72. %-----------------------------------------------%
  73. figure;
  74. subplot(2,1,1);%画INL
  75. plot(2:n-2,in(2:n-2),'-.rd');
  76. xlabel('DIGITAL OUTPUT CODE');
  77. ylabel('INL(LSB)');
  78. title('INL vs.DIGITAL OUTPUT CODE');
  79. grid on;
  80. subplot(2,1,2);%画DNL
  81. plot(1:n-3,dn(1:n-3));
  82. xlabel('DIGITAL OUTPUT CODE');
  83. ylabel('DNL(LSB)');
  84. title('DNL vs.DIGITAL OUTPUT CODE');
  85. grid on;
  86. figure;
  87. subplot(2,1,1);%画码密度柱状图
  88. bar(1:n,hh,'g');
  89. xlabel('DIGITAL OUTPUT CODE');
  90. ylabel('Count of code');
  91. title('Histogram Graph of Code Density');
  92. axis([-100 2100 0 1000]);
  93. grid on;
  94. subplot(2,1,2);%画转移曲线
  95. plot(vv(1:2*(n-1)),xx(1:2*(n-1)));
  96. %plot(vv(1:n),xx(1:n));
  97. xlabel('Input Voltage(V)');
  98. ylabel('DIGITAL OUTPUT CODE');
  99. title('Transfer Function');
  100. axis([-1,1,0,2^bit-1]);
  101. grid on;



复制代码


频谱图

频谱图

adc_data.zip

87.68 KB, 下载次数: 7 , 下载积分: 资产 -2 信元, 下载支出 2 信元

数据

发表于 2023-3-31 10:19:07 | 显示全部楼层
兄弟,你这什么原因找到了吗?
您需要登录后才可以回帖 登录 | 注册

本版积分规则

关闭

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

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

GMT+8, 2024-4-28 03:38 , Processed in 0.037135 second(s), 7 queries , Gzip On, Redis On.

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