前言
目前内外网自用ADC动态参数计算的matlab程序都是同一套模板的改版,存在共同的问题,迟迟没有得到解决,也困扰了我几天,不过还好,最终搞明白了几点。
一、ADC动态参数分析的源程序从何而来?
目前看到的各种文章,很多都可以追溯到2002年的这篇文章:
https://www.maximintegrated.com/en/design/technical-documents/tutorials/7/729.html后面附带的示例程序,大部分改编的文章都是在这个基础上改了数据读出的方式(每个人采集数据的保留格式不同),后面的具体程序几乎没有实质性改变,这也造成了几个问题:
1,没有交代清楚 signal 的 span 该取,谐波的spanh 该取多少,为什么要使用这个公式,为什么取这个值:
%Span of the input frequency on each side
span=max(round(numpt/200),5);
%Approximate search span for harmonics on each side
spanh=2;
2, 没有考虑非满量程下的幅度比例因子的问题,导致程序结果有偏差。
3,迭代过程中数组可以预设置内存大小,加快计算速度。
二、直接上代码
1.修改后的matlab code
代码如下(示例):
clc
clear
%extract array data from the datasource file
fileID = fopen('E:\data\matlab\100mV_0912_1.c','r');
[data4,~] = fscanf(fileID,'%d');
data4 = data4'; %转置数组
numpt = 20000; %数据点个数(可根据需求调节)
num_bit=12; % %ADC数据位。(有符号整型数)
fclose(fileID); %关闭文件
x = 1:1001; %作图点数
data100 = data4(1:1001); %原始波形取作图点数个点
subplot(1,2,1); %作图 一行 二列 中的第一个小图
plot(x,data100); %作图,仅作波形示意,和后面的数据处理关系不大
mul=mean(data4); %求数据平均值,用于后面的数据 正负中心对齐
%span=40; %信号频率+ -span范围都算作信号能量
span=max(round(numpt/200),5);%一种经验公式,来自maxim网站源码,基本正确,确实可以涵盖信号带宽
spanh=5; %谐波频率+ -spanh范围都算作谐波能量,可由小达到实验,ENOB数值稳定后即可
Fsample=125; %采样率125M,单位MHz
m=1:numpt; %生成数组
data33=(data4(m)-mul)/(2^(num_bit-1)-1); %正负中心(基线)对齐,并转化为具体幅度0-1;
% data33,需要做FFT变换的数据,4000个点,必须是连续的周期信号
beta=5.658; %没有使用此变量
data44=data33'.*hanning(numpt); %加窗,汉宁窗
%data44=data33'.*hamming(numpt); %加窗,汉明窗
%data44=data33;
data55=fft(data44); %fft变换
data66=abs((data55)); %取绝对值,表示信号幅度
data77=20*log10(data66); %取对数,分贝
data88=data66.*data66; %平方,表示信号能量
max_voltage = max(abs(data33)); %最大电压值
max_voltagedb = 20*log10(max_voltage/1); %最大电压分贝
%max_voltagedb = 0; %试验不设置为零的时候频谱图形状
bili_factor_1=1/max_voltage; %幅度比例因子
bili_factor=bili_factor_1^2; %功率比例因子
%bili_factor=1; %测试比例因子为1时参数变化
maxdb=max(data77(1:numpt/2)); %最大幅值,分贝
x=((0:(numpt/2-1)).*Fsample/numpt); %x轴,频率单位,Mhz,
y1=data77(1:numpt/2)-maxdb+max_voltagedb; %y轴,幅值,db,最大0db
figure(1);
subplot(1,2,2)
plot(x,y1); % 作图
fin=find(data77(1:numpt/2)==maxdb); %输入信号,赋值,找到最大的频率
% fin=fin+1;
% 如果含直流成分过大,那么fin可能是直流频率
%所以不考虑直流分量
Fh= zeros(1:8); %谐波频率 数组 预设置内存
Ph= zeros(1:8); %谐波能量 数组 预设置内存
for har_num=1:8 %1到15次谐波分量
tone=rem((har_num*(fin)+1)/numpt,1);
%各次谐波对应的能量
if tone>0.5
tone=1-tone; %对称
end
%Fh=[Fh tone]; %旧版本,每次迭代的时候append 数据,速度慢,现改称预设内存大小,根据数组下标赋值
Fh(har_num)=tone;
%谐波,在Fh中加入tone
if round(tone*numpt)-spanh>0
har_peak=max(data88(round(tone*numpt)-spanh:round(tone*numpt)+spanh));%谐波附近+-spanh最大值
har_bin=find(data88(round(tone*numpt)-spanh:round(tone*numpt)+spanh)==har_peak);%最大值对应频率
har_bin=har_bin+round(tone*numpt)-spanh-1;
Ph(har_num)=sum(data88(round(tone*numpt)-spanh:round(tone*numpt)+spanh));
% har_bin-spanh:har_bin+spanh;
else
har_peak=max(data88(1:round(tone*numpt)+spanh));%谐波附近+-spanh最大值
har_bin=find(data88(1:round(tone*numpt)+spanh)==har_peak); %最大值对应频率
har_bin=har_bin+round(tone*numpt)-spanh-1;
Ph(har_num)=sum(data88(1:har_bin+spanh)); %旧版本,每次迭代的时候append 数据,速度慢,现改称预设内存大小,根据数组下标赋值
end
%某谐波分量
end
%你好
Pdc=sum(data88(1:span)); %直流能量
Ps=bili_factor*sum(data88(fin-span:fin+span)); %信号能量,前后span个都算作信号能量,
Pd=bili_factor*sum(Ph(2:8)); %谐波能量
Pn=sum(data88(1:numpt/2))-Pdc-Pd/bili_factor-Ps/bili_factor;
%噪声能量%
fin_MHz=fin/numpt*Fsample; %信号频率
SNR=10*log10(Ps/Pn); %信噪比
SINAD=10*log10(Ps/(Pn+Pd)); %信纳比
SFDR=10*log10(Ph(1)/max(Ph(2:8))); %无杂散动态范围
ENOB=(SINAD-1.76+20*log10(1/max_voltage))/6.02; %幅度校正后有效位
2.代码处理的数据
代码+数据压缩文件链接https://download.csdn.net/download/qq_38239093/86533881
三、讲解
1,span、spanh本质都是测出来的
放大信号的频谱图,测量频谱图信号峰值两边到峰值频率的-3dB带宽的,再除以FFt的Bin宽取整,就得到了span的数值,经过验证,段落一中引用的经验公式,基本可以将信号的能量囊简括在内,保证ADC参数结果基本稳定。
谐波的范围参数spanh则是试出来的!从最小的正整数1开始,逐渐增加,直到SINAD或者ENOB数值不发生明显变化即可,省去了计算的过程,不过理论是可行的,基本上此数值下,已经囊括了大部分的谐波能量。
2,整型数据需要中心对齐(recenter),需要转化成幅度,这是源程序没有的,原因是其数据格式已经是代表幅度的浮点数。
data33=(data4(m)-mul)/(2^(num_bit-1)-1); %正负中心(基线)对齐,并转化为具体幅度0-1;
3,最好根据迭代的次数(根据计算的谐波个数)预设置内存大小,加快运算速度
Fh= zeros(1:8); %谐波频率 数组 预设置内存
Ph= zeros(1:8); %谐波能量 数组 预设置内存
4,比例因子的引入,如代码所示,需要提醒的是最后的ENOB也要考虑到这一点:
ENOB=(SINAD-1.76+20*log10(1/max_voltage))/6.02; %幅度校正后有效位
理论来源:冯雪. ADC动态参数估算算法的优化与实现[D]. 江苏:东南大学,2016. DOI:10.7666/d.Y3142543.
总结
本文简单介绍了关于ADC动态参数matlab程序的一些思考和改进。
今天的文章MATLAB矩阵特征值_matlab插值函数[通俗易懂]分享到此就结束了,感谢您的阅读。
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
如需转载请保留出处:https://bianchenghao.cn/87124.html