论坛风格切换切换到宽版
  • 18222阅读
  • 212回复

方波的采样定理和DDS的问题 [复制链接]

上一主题 下一主题
离线bd1es
发帖
2096
只看该作者 60楼 发表于: 2008-08-02
[quote=一异]这个结论不正确!
相位累加器的字长与相位抖动无关,相位累加器的字长只决定相位的步长,换句话说之决定频率分辨率。
用单片机实现dds相位抖动大的主要原因应当是单片机的响应时间造成的。
如果外接dac,可以在dac与单片机之间增加一个多位d触发器来保证相位抖动指标。这样做的话,就不能用单片机的定时中断了,必须用驱动d触发器的时钟移相向后用来做外部中断……
如果不用外部dac,也可以考虑用采样保持电路或者脉冲成型电路。总之要保证采样时钟的稳定。[/quote]

嗯,有可能您是对的。我做两个仿真看看结果再说。
离线bd1es
发帖
2096
只看该作者 61楼 发表于: 2008-08-02
[quote=小比尔/5]关于在160mhz采样频率上出10.7mhz,我的仿真结果与你的大致一样:
图1:采样频率160mhz,输出10.7mhz,累加器32bit,1bit(方波“dds”)
图2:采样频率160mhz,输出10.7mhz,累加器32bit,8bit(1024正弦样点表)

这样的仿真很好玩儿,颇有指点江山的味道,呵呵~
学习了!!![/quote]

,是挺好玩的,喜欢仿真。

我也有scilab,是linux上的4.1.2版,趁现在matlab玩得不熟,干脆转过去算了, !以前拿scilab设计过环路滤波器,挺成功的。
离线bd1es
发帖
2096
只看该作者 62楼 发表于: 2008-08-03
刚才验证了一下,一异的观点是正确的。
1、使用256x16位波表时,32位和16位dds的信噪比都较差,不到50db。
2、使用64kx16位波表时,16位dds的信噪比反而比32位的更好,因为这时候dds有一个完整的波表。mainstreet在前面贴子里也提到过。

见下图,上面两张是32位dds的,下面两张是16位dds的: :d
本主题包含附件,请 登录 后查看, 或者 注册 成为会员
离线bd1es
发帖
2096
只看该作者 63楼 发表于: 2008-08-03
新程序在这里,变化如下:
1、c的dds程序加多了16位的仿真;
2、matlab程序跟mainstreet学,把归一化放到fft之后:

用法跟前面说的一样:
本主题包含附件,请 登录 后查看, 或者 注册 成为会员
离线一异
发帖
868
只看该作者 64楼 发表于: 2008-08-03
我认为,相位累加器的字长和噪声之间的关系其实根本不需要仿真就能知道。
bd1es在仿真时候,不知道是怎么处理的频率的,实际上对于160mhz的采样频率和10mhz输出来说,输出信号频率式采样频率的16分之1。因此,每个时钟周期相位增加π/8,16个时钟周期完成一周。对于这个特例实际上只需要4bit的相位累加器就足够了,如果总是从相位0开始,多于4bit的累加器只有最高4bit有数字,地位永远是零。
所以我很不明白16bit累加器和32bit累加器的差异是从哪里来的。
离线mainstreet
发帖
44
只看该作者 65楼 发表于: 2008-08-03
[quote=一异]我认为,相位累加器的字长和噪声之间的关系其实根本不需要仿真就能知道。
bd1es在仿真时候,不知道是怎么处理的频率的,实际上对于160mhz的采样频率和10mhz输出来说,输出信号频率式采样频率的16分之1。因此,每个时钟周期相位增加π/8,16个时钟周期完成一周。对于这个特例实际上只需要4bit的相位累加器就足够了,如果总是从相位0开始,多于4bit的累加器只有最高4bit有数字,地位永远是零。
所以我很不明白16bit累加器和32bit累加器的差异是从哪里来的。[/quote]

1/16这样的“整数”频率不好,只在波表里几个点跑来跑去,信息很单调。我特意把这种频率变成“无理数”(1/16*exp(1)/2.7)。

从16或32位累加器截断到10位地址时,累加器的字长影响很小。
离线mainstreet
发帖
44
只看该作者 66楼 发表于: 2008-08-03
'
hi mainstreet,俺试着运行了您的程序,发现如下问题
1、波表的位宽超限,已改成2^n-1;
2、fft的功率计算有误。既然前面已对电压平方了,后面就db计算应该是10*log10(),也改了;
3、相位累加部分没看懂,请问如何表示一个16位累加器,又如何表示一个32位累加器呢?否则相位的舍入就不能评估了。是否可介绍一下您程序的设计原理。
下面是俺修改的程序,运行效果与小比尔/5和我的c程序类似了。但还是不知道这个dds是多少位累加器的,我感觉这里还有错误。 [表情] ,运行结果见附图:
function mainstreet_case_modis
close all;
clear all;
m=10; wave=sin(2*pi*(1:2^m)'/2^m); % 1024-entry wave table
n=8-1; wave=round(wave*(2^n-1)); % truncated to 8-b
f0=0.1*exp(1)/2.7; % normalized frequency is 0.1
phase0=rand; % initial phase
k=16; phase1(1:2^k)=phase0+2*pi*f0*(0:2^k-1); % phase
phase2=mod(phase1,2*pi)/2/pi; % phase between 0 and 2*pi
phase3=round(phase2*(2^m-1)+1); % phase as wave table indices
x=wave(phase3); % wave table output
x=x.*hanning(2^k); % windowed
y=fft(x);
y2=abs(y(1:2^k/2)).^2;
y2=y2/max(y2); % normalized
plot((1:2^k/2)/2^k,10*log10(y2));
axis([0 0.5 -100 0]);
title(['fft of dds based on ',num2str(2^m),'x',num2str(n+1),' wave table'])
fhandle=fopen('wave','w');
for i=1:length(wave)
fprintf(fhandle,'%3i\n',wave(i));
end
'
谢谢你找到我的错!我的纵轴都要除以2!

没有模拟累加器,只是在最后截断到10位。或者说累加器的字长是matlab隐含的64位。
离线小比尔/5
发帖
2582
只看该作者 67楼 发表于: 2008-08-03
'
这是从电压轴来看。还可以从时间轴来看。如果输出16 khz的正弦波,时钟的抖动要在ns级,否则16m长的波表也浪费了。
那天我就想到了用dither抖动的办法把谐波转化成噪声改善频谱,但是我觉得在波表的时间轴和电压轴上在外部做不到。在dac内部是可能的。
你是用什么办法实现的?
'

很抱歉,目前在硬件上还未实现,在单片机上做的局限性太大了,主要是对时序的苛刻要求。但在音频应用的时候经常会遇到抖动操作。
关于时基的jitter,今天刚想到一个办法。stc12c5410具有高速硬件定时输出和pwm输出,也许可以利用这一功能来输出dac的锁存脉冲。
离线bd1es
发帖
2096
只看该作者 68楼 发表于: 2008-08-03
[quote=一异]我认为,相位累加器的字长和噪声之间的关系其实根本不需要仿真就能知道。
bd1es在仿真时候,不知道是怎么处理的频率的,实际上对于160mhz的采样频率和10mhz输出来说,输出信号频率式采样频率的16分之1。因此,每个时钟周期相位增加π/8,16个时钟周期完成一周。对于这个特例实际上只需要4bit的相位累加器就足够了,如果总是从相位0开始,多于4bit的累加器只有最高4bit有数字,地位永远是零。
所以我很不明白16bit累加器和32bit累加器的差异是从哪里来的。[/quote]

有问题,我是避开了16分之一的,这里选的10.7 mhz,并非整数,程序也贴出来了。您可以看到,即使是16比特dds,相位增量也是4382,而不是4096。

如果有兴趣您就自己转转看,我觉得挺有收获的。
离线一异
发帖
868
只看该作者 69楼 发表于: 2008-08-03
'
有问题,我是避开了16分之一的,这里选的10.7 mhz,并非整数,程序也贴出来了。您可以看到,即使是16比特dds,相位增量也是4382,而不是4096。
如果有兴趣您就自己转转看,我觉得挺有收获的。 [表情]
'

这就对了!
对于16bit的累加器,4382对应的输出频率理论上应当是:10.698,242,187,5 mhz。估计你在32bit累加器的仿真过程中用了一个更接近10.7 mhz的近似值。
我猜想,两个不同的累加器输出的信号差异应当主要是由于这点微小的频率差异引起的。如果你在32bit 累加器的方针试验中,采用与16bit同样的频率,那么两者的输出是完全一样的,当然频谱也不会有任何差异。
你不妨尝试一下,稍微修改一下频率,频谱应当会有所变化。

再次申明:我不认为相位累加器的字长会导致相位抖动,只会影响频率分辨率。在你这个例子当中,实际上并没有得到10.7 mhz的精确频率,这正是由于有限的频率分辨率。
在这个例子当中,要输出10.7mhz的频率,相位累加器的步长应当是4382.72。如果我们重新设计累加器,让累加器在工作过程中一部分时间按步长4382工作,另一部分时间按步长4383工作,那么我们也可以得到准确地10.7 mhz的输出,但如果这样做就会出现相位抖动。

最后,对于所有的二进制累加器,除非将采样频率设定成2的n次方乘以10的m次方(m=…,-2,-1,0,1,2…),否则我们总是无法得到准确地频率。
所以,我认为比较理想的dds应当采用十进制累加器。
离线小比尔/5
发帖
2582
只看该作者 70楼 发表于: 2008-08-03
关于频率的误差,在程序中已经显示出来了。
离线bd1es
发帖
2096
只看该作者 71楼 发表于: 2008-08-03
这么小的频率误差会有那么大的影响?俺还是半信半疑,明天仿仿再说, ...
离线小比尔/5
发帖
2582
只看该作者 72楼 发表于: 2008-08-03
抱歉一异同学,你似乎没有弄明白截断误差。

例如:
相位累加器值(32bits)=>
  1a ef 00 41(相位步进字舍入误差,导致偏频

由于表格的大小受限(例如1024点,因此只能取高位前10位,剩下的截断)=>
  得到截断前10位:35d(截断误差,周期性的频率抖动。注意,这里不是四舍五入,因此误差比较大)

查表 =>
  例如:table(35d)=9d(量化误差,产生量化噪声。四舍五入,误差为1/2lsb)

送数据至d/a =>
  p0=9d(器件误差,非线性误差,产生谐波干扰)

等待定时信号 =>
  输出模拟电压(时基误差,产生抖动
离线小比尔/5
发帖
2582
只看该作者 73楼 发表于: 2008-08-03
一异的结论是对的。
本主题包含附件,请 登录 后查看, 或者 注册 成为会员
离线代洪波
发帖
4809
只看该作者 74楼 发表于: 2008-08-03
说明dac截断不影响相位抖动吗?
离线一异
发帖
868
只看该作者 75楼 发表于: 2008-08-04
[quote=代洪波]说明dac截断不影响相位抖动吗?[/quote]

这里两个问题有点混淆了。
我是说相位累加器实际上没有截断误差的问题,或者说相位累加器的有限字长只会影响输出频率的分辨率(精度取决于时钟)。
对于常用的dds解决方案:比如用一个24bit的二进制相位累加器,如果你采用16.777,216 mhz的参考频率,那么你可以到到所以1hz整倍数的频率;而通常采用的整数采样频率,比如16.000,000 mhz,那么你肯定无法得到大部分1hz整倍数的频率。

而dac和波表的字长(通常两者是一回事儿)问题,则是另一个问题。dac有限的字长导致的阶段误差肯定会导致产生噪声,而且这个噪声的频谱是和输出信号、采样频率都相关的,不是白噪声。
至于这个阶段误差是否产生相位噪声,似乎没有见到什么文献研究这个问题,没有深入研究过不敢下结论。不过,我估计即使存在相位噪声,大概也不会太大吧。
只不过,有噪声电压存在,除非设法将噪声滤掉,否则这些噪声也可能干扰到相位的稳定,比如你用过零比较器将正弦波输出变成方波的时候,噪声电压有可能会使得方波的边沿在时间轴出现移动……
离线代洪波
发帖
4809
只看该作者 76楼 发表于: 2008-08-04
看来这个问题是一个很深的问题了!我继续潜水学习
离线alchemier
发帖
69
只看该作者 77楼 发表于: 2008-08-04
[quote=小比尔/5]但问题是,样表精确到一定程度,dac就无法表达了。
16.8m的样表终究太大了,无论从成本还是复杂程度都是没必要的。
如果能实现16.8m的样表,还不如直接用级数进行实时的近似运算。

在这个系统里,幅度和相位是可以相互转换的。

请看上面同学的推论。[/quote]

我觉得你把样表的样点数和每个样点的幅度也就是dac的位数搞混了。
离线alchemier
发帖
69
只看该作者 78楼 发表于: 2008-08-04
'
16.8m=2^27
这要配合大概30位的dac。
'

16.8m=2^24,这是样点数,至于dac没必要用这么高的位数,根据上面的实验结果用16bit足够了。
离线alchemier
发帖
69
只看该作者 79楼 发表于: 2008-08-04
[quote=一异]我认为,相位累加器的字长和噪声之间的关系其实根本不需要仿真就能知道。
bd1es在仿真时候,不知道是怎么处理的频率的,实际上对于160mhz的采样频率和10mhz输出来说,输出信号频率式采样频率的16分之1。因此,每个时钟周期相位增加π/8,16个时钟周期完成一周。对于这个特例实际上只需要4bit的相位累加器就足够了,如果总是从相位0开始,多于4bit的累加器只有最高4bit有数字,地位永远是零。
所以我很不明白16bit累加器和32bit累加器的差异是从哪里来的。[/quote]

他说的是每个样点的幅度16位和32位的差别,而不是相位累加器的位数。