EDA365欢迎您登录!
您需要 登录 才可以下载或查看,没有帐号?注册
x
转——基于ZX-2型FPGA开发板的串口示波器(四) $ r5 z* R' b6 r. J0 R2 Z
0 s0 k/ Y4 {) f% O6 L% WDDS基本原理 注:本文内容摘抄自周立功编写的教材《EDA实验与实践》196~197页。* E3 Q5 W; Z$ v
! `4 o! M7 A) H( v, C A& sDDS(Direct Digital Synthesizer)即数字合成器,是一种新型的频率合成技术,具有相对带宽大,频率转换时间短、分辨率高和相位连续性好等优点,很容易实现频率,相位,和幅度的数控调制,广泛应用于通信领域。) {# G: Z9 M7 H5 X! [
DDS的基本结构图如图1所示:
3 x: ~; P, y" I2 w$ N % x5 K# w' b+ a& Y7 u s
" x) t: x( ]( @( c0 `
图1 DDS的基本结构图 主要由相位累加器,相位调制器,正弦数据表,和D/A转换器构成,相位累加器由N位加法器与N位寄存器构成。每来一个时钟,加法器就将频率控制字,与累加寄存器输出的相位数据相加,相加的结果又反馈至累加寄存器的数据输入端,以使加法器在下一个时钟脉冲的作用下继续与频率控制字相加,这样,相位累加器在时钟作用下,不断对频率控制字进行线性相位累加。由此可以看出,在每一个时钟脉冲输入时,相位累加器便把频率控制字累加一次。相位累加器输出的数据就是合成信号的相位,相位累加器的溢出频率,就是DDS输出的信号频率,用相位累加器输出的数据,作为波形存储器的相位采样地址,这样就可以把存储在波形存储器里的波形采样值经查表找出,完成相位到幅度的转换,波形存储器的付出送到D/A转换器,由D/A转换器将数字信号转换成模拟信号输出,DDS信号流程示意图如图4.51所示。 ) ~) q% F7 {. [7 o# x$ x' S
# _$ \8 t5 P* Y6 p% e0 h i# h
图2 DDS信号流程示意图 % ]# ~8 O8 M% \
0 q6 G5 g6 a& \6 ^
由于相位累加器为N位,相当于把正弦信号在相位上的精度定义为N位,(N的取值范围一般为24~32),所以其分辨率为1/2N,若系统时钟频率为Fclk,频率控制字fword为1,则输出频率为Fout=Fclk/2N,这个频率相当于“基频”,若fword为B,则输出频率为
: i O+ D& P; N, _* h b
E. q9 J% E$ ^- J) a- b1 v8 X
当系统输入时钟频率,Fclk不变时,输出信号频率由频率控制字M所决定,由上式可得:
6 {" d% A E6 R3 V5 R4 g( K
其中B为频率字,注意B要取整,有时会有误差,在本设计中,N取32位,系统时钟频率Fclk为120兆,
1 ?, x- n* V' u# Q3 ~4 k/ y4 w' ^! v
选取ROM的地址(即相位累加器的输出数据)时,可以间隔选通,相位寄存器输出的位数一般取10~16位,这种截取方法称为截断式用法,以减少ROM的容量,M太大会导致ROM容量的成倍上升,而输出精度受D/A位数的限制未有很大改善,在本设计中M取12位。
4 E. W; n! a6 [( J! \. ^- F
以上为周立功《EDA实验与实践》一书中对DDS原理的介绍 % j& q8 z: r9 M+ @) S
3 `6 ?* Y" P A3 Q. e5 T' H- s' y
DDS原理再解释。
) [7 R/ u$ ]( J3 N+ t
上面的对DDS原理的解释,还是有部分同学反映不够直观,读完之后还是不明白DDS究竟是怎么控制频率和相位的,那么,这里小梅哥再用更加通俗的方式给大家讲解一下。 ' ], {. y6 L q: e% I/ e
如图3,为一个完整周期的正弦信号的波形,总共有33个采样点,其中第1点和第33点的 值相同,第33点为下一个周期的起始点,因此,实际一个周期为32个采样点(1~32)。因为是在matlab中生成的,因此起始点为1,而不是我们常见的0,这里对我们理解DDS的原理没有任何影响,因此不必过多纠结。 2 k' ^6 e, p& r/ l& t: j
' A7 H& U! \3 s
9 i' x& L- g, P; z, Z$ f
图3 32个采样点的正弦信号波形
# Q% F4 d' J6 L, I
j4 e) \5 ?& C, i4 z: J0 i6 x6 o) C6 y: f# s
图4 16个采样点的正弦信号波形 6 Y/ }5 A% M6 {0 Z, m
& b, \7 s D) y; n8 a) |# _" `
我们要使用FPGA控制DAC来输出这样一个周期的正弦信号,每1ms输出一个数值。如果每个点都输出,则总共输出这一个完整的周期信号需要输出32个点,因此输出一个完整的信号需要32ms,则输出信号的频率为1000/32Hz。 ( S7 q7 Z* ^4 A8 q. C9 |; }5 S
假如,我们现在用这一组数据来输出一个2*(1000/32)Hz的正弦信号,因为输出信号频率为2*(1000/32)Hz,那么输出一个完整的周期的正弦波所需要的时间为32/2,即16ms,为了保证输出信号的周期为16ms,那么,我们就需要对我们的输出策略进行更改,上面输出周期为32ms的信号时,我们采用的为逐点输出的方式,以32个点来输出一个完整的正弦信号,而我们FPGA控制DAC输出信号的频率固定为1ms,因此,我们要输出周期为16ms的信号,只能输出16个点来表示一个完整的周期。我们这里选择以每隔一个点输出一个数据的方式,例如,我们可以选择输出(1、3、5、7……29、31)这些点,因为采用这些点,我们还是能够组成一个完整的周期的正弦信号,而输出时间缩短为一半,则频率提高了一倍。最终结果如上图4所示。
2 A) j$ |) w) j) `
如果我们需要输出频率为(1/2)*(1000/32)Hz,即周期为64ms,则只需要以此组数据为基础,每2ms输出一个数据即可,例如第1ms和第2ms输出第一个点,第3ms和第4ms输出第二个点,以此类推,第63ms和第64ms输出第32个点,即可实现周期加倍,即频率减半的效果。 - e( Z# D& ^' X" [: E
对于相位的调整,则更加简单,我们只需要在每个取样点的序号上加上一个偏移量,便可实现相位的控制。例如,上面默认的是第1ms时输出第一个点的数据,假如我们现在在第1ms时从第9个点开始输出,则将相位左移了90度,这就是控制相位的原理。 , C1 f& g6 X6 Y' N
实现DDS输出时,将横坐标上的数据作为ROM的地址,纵坐标上的数据作为ROM的输出,那么指定不同的地址就可实现对应值的输出。而我们DDS输出控制频率和相位,归结到底就是控制ROM的地址。 了解了以上原理之后,再来设计DDS系统就很容易了,以下为DDS信号发生器的代码: 3 c/ \1 ]( a7 ?0 e) V- L, i& B- ^ g
$ R# Q2 n( l1 U7 A
; m! ]3 ^ z4 V# z/ s; Q$ L( t 01 module DDS_Module( 02 Clk, 03 Rst_n, 04 EN, 05 Fword, 06 Pword, 07 DA_Clk, 08 DA_Data 09 ); 10 11 input Clk;/*系统时钟*/ 12 input Rst_n;/*系统复位*/ 13 input EN;/*DDS模块使能*/ 14 input [31:0]Fword;/*频率控制字*/ 15 input [11:0]Pword;/*相位控制字*/ 16 17 output DA_Clk;/*DA数据输出时钟*/ 18 output [9:0]DA_Data;/*D输出输出A*/ 19 20 reg [31:0]Fre_acc; 21 reg [11:0]Rom_Addr; 22 23 /*---------------相位累加器------------------*/ 24 always @(posedge Clk or negedge Rst_n) 25 if(!Rst_n) 26 Fre_acc <= 32'd0; 27 else if(!EN) 28 Fre_acc <= 32'd0; 29 else 30 Fre_acc <= Fre_acc + Fword; 31 32 /*----------生成查找表地址---------------------*/ 33 always @(posedge Clk or negedge Rst_n) 34 if(!Rst_n) 35 Rom_Addr <= 12'd0; 36 else if(!EN) 37 Rom_Addr <= 12'd0; 38 else 39 Rom_Addr <= Fre_acc[31:20] + Pword; 40 41 /*----------例化查找表ROM-------*/ 42 ddsrom ddsrom( 43 .address(Rom_Addr), 44 .clock(Clk), 45 .q(DA_Data) 46 ); 47 48 /*----------输出DA时钟----------*/ 49 assign DA_Clk = (EN)?Clk:1'b1; 50 51 endmodule
6 x& d: c2 k" L/ }& K% T
2 m X+ v, \3 o2 ~ L" i
小梅哥 2015年4月8日 于至芯科技 1 c- \! Q8 I: }
|