DDS数字频率计设计
- 格式:doc
- 大小:1.08 MB
- 文档页数:11
DDS设计一、基本原理直接数字频率合成器(DDS)是通信系统中常用到的部件,利用DDS可以制成很有用的信号源。
与模拟式的频率锁相环PLL相比,它有许多优点,突出为(1)频率的切换迅速;(2)频率稳定度高。
一个直接数字频率合成器由相位累加器、波形ROM、D/A转换器和低通滤波器构成。
DDS的原理框图如下所示:其中K为频率控制字,f c为时钟频率,N为相位累加器的字长,D为ROM 数据位及D/A转换器的字长。
相位累加器在时钟f c的控制下以步长K作为累加,输出N位二进制码作为波形ROM的地址,对波形ROM进行寻址,波形ROM 输出的幅码S(n)经D/A转换器变成梯形波S(t),再经低通滤波器平滑后就可以得到合成的信号波形了。
合成的信号波形形状取决于波形ROM中存放的幅码,因此用DDS可以产生任意波形。
本设计中直接利用D/A转换器得到输出波形,省略了低通滤波器这一环节。
1、频率预置与调节电路不变量K被称为相位增量,也叫频率控制字。
DDS方程为:f0= f c K/2n,f0为输出频率,f c为时钟频率。
当K=1时,DDS输出最低频率(也既频率分辩率)为f c /2nDDS的最大输出频率由Nyguist 采样定理决定,即f c /2,也就是说K的最大值为2n-1.因此,只要N足够大,DDS可以得到很细的频率间隔。
要改变DDS的输出频率,只要改变频率控制字K即可。
2、累加器相位累加器的原理图如下图相位累加器由N为加法器与N位寄存器级联构成。
每来一个时钟脉冲f c,加法器将频率控制字与寄存器输出的累加相位数据相加,再把相加后的结果送至寄存器的数据输入端,寄存器将加法器在上一个时钟作用后所产生的下数据反馈到加法器的输入端;以使加法器在下一个时钟作用下继续频率控制字进行相加。
这样,相位累加器在时钟的作用下,进行相位累加,当相位累加器累加满量时,就产生一次溢出,完成一个周期性的动作,这个周期应为u k= 2n / GCD(2N ;k),其中GCD表示最大公约数。
3、波形存储器用相位累加器输出的数据作为波形存储器的取样地址进行波形的相位——幅值转换,即可在给定的时间上确定输出的波形的抽样幅值。
N位的寻址ROM相当于把00--- 3600 的正弦信号离散成具有2n样值的序列,若波形ROM有D位数据位,则2n个样值的幅值以D位二进制数值固化在ROM 中,按照地址的不同可以输出相宜相位的正弦信号的幅值。
相位----幅值变换原理图如下所示。
4、D/A转换器D/A转换器的作用是把已经合成的正弦波的数字量转换成模拟量,正弦幅度量化序列S(n)经D/A转换后变成了包络为正弦波的阶梯波S(t),S(t)的周期为T=uk*T c.需要注意的是,频率合成器对D/A转换器的分辨率有一定的要求,。
D/A转换器的分辨率越高,合成的正弦波S(t)台阶数就越多,输出波形的精度也就越高。
二、整体的设计原理图三、各个模块的实现1.频率预置模块通过“freq_in”可以产生频率控制字。
在“frep_in”的上升沿来的时候,频率控制字加1。
输出宽度为4位的频率控制字,范围为1~16。
2.相位累加器相位累加器实现的功能是:(1)设置DDS的初始相位。
(2)波形ROM地址发生器。
(3)DDS工作状况显示。
(1)、通过xiang_en,set_up,set_ok设置初始相位。
初始相位的调节范围可以是0度到360度。
(2)、system_clk为系统时钟的输入端。
Count_clk 为地址发生器的工作时钟输入端。
Frep_in为频率控制字输入端。
(3)、load_data[9..0]为波形ROM的地址发生器地址输出端,led_out[2..0]为系统工作状态显示。
3.波形ROM.address[9..0]为波形ROM的地址输入端,宽度为10位,可寻址空间为1K。
clock为地址锁存信号输入端。
.q[7..0]为相应地址存储的波形信号数据输出端。
45.D/A控制六、附件/*--------set360.vhd-----*/ 相位与频率设置模块library ieee;use ieee.std_logic_1164.all;use ieee.std_logic_unsigned.all;use ieee.std_logic_arith.all ;entity set360 isport( set_up, set_ok, clk, clk1 : in std_logic ;en : in std_logic ;frep_in : in std_logic_vector(3 downto 0) ;led_out : out std_logic_vector(2 downto 0) ;load_data : out std_logic_vector(9 downto 0)) ;end set360 ;architecture behav of set360 issignal static_pre, static_nex : std_logic_vector(1 downto 0) ;signal time : integer range 0 to 1023 ;signal coun : std_logic_vector( 9 downto 0) ;signal cnt : integer range 0 to 100 ;signal load_en : std_logic ;signal cc : integer range 0 to 100 ;signal k0, k1 : std_logic_vector(1 downto 0) ;beginprocess(static_pre, k1)--variable time_v : integer range 0 to 359 ;begincase static_pre iswhen "00" => cnt <= 0 ;k0 <= "00" ;led_out <= "000" ;if k1 = "11" thenstatic_nex <= "01" ;else static_nex <= "00" ;end if ;when "01" => cnt <= 100 ;k0 <= "01" ;led_out <= "100" ;if k1 = "10" thenstatic_nex <= "10" ;else static_nex <= "01" ;end if ;when "10" => cnt <= 10 ;k0 <= "10" ;led_out <= "010" ;if k1 = "01" thenstatic_nex <= "11" ;else static_nex <= "10" ;end if ;when "11" => cnt <= 1 ;k0 <= "11" ;led_out <= "001" ;if k1 <= "00" thenstatic_nex <= "00" ;else static_nex <= "11" ;end if ;when others => null ;end case ;end process ;process(set_ok, k0)beginif set_ok 'event and set_ok = '1' thenif k0 = "00" thenk1 <= "11" ;elsif k0 = "01" thenk1 <= "10" ;elsif k0 = "10" thenk1 <= "01" ;elsif k0 = "11" thenk1 <= "00" ;end if ;end if ;end process ;process(set_up, cnt)variable kk : integer range 0 to 1023 ;beginif set_up 'event and set_up = '1' thenkk := kk + cnt ;else kk := kk ;end if ;if kk > 1023 thenkk := kk - 1023 ;else kk := kk ;end if ;time <= kk ;end process ;process(static_nex, clk, static_pre)beginif clk 'event and clk = '1' thenstatic_pre <= static_nex ;else static_pre <= static_pre ;end if ;end process ;process(clk, en, cc, clk1, coun, time)--variable cnt_k : std_logic_vector(9 downto 0) ;beginif en = '0' thencoun <= conv_std_logic_vector(time,10) ;elseif clk1 'event and clk1 = '1' thencoun <= coun + cc ;else coun <= coun ;end if ;end if ;load_data <= coun ;end process ;process(frep_in)begincase frep_in iswhen "0000" => cc <= 1 ;when "0001" => cc <= 2 ;when "0010" => cc <= 3 ;when "0011" => cc <= 4 ;when "0100" => cc <= 5 ;when "0101" => cc <= 6 ;when "0110" => cc <= 7 ;when "0111" => cc <= 8 ;when "1000" => cc <= 9 ;when "1001" => cc <= 10 ;when "1010" => cc <= 11 ;when "1011" => cc <= 12 ;when "1100" => cc <= 13 ;when "1101" => cc <= 14 ;when "1110" => cc <= 15 ;when "1111" => cc <= 16 ;end case ;end process ;end behav ;/*-----------tri_s.vhd--------*/ 二选一,选择器library ieee;use ieee.std_logic_1164.all ;entity tri_s isport( en : in std_logic ;dat_0, dat_1 : in std_logic_vector(7 downto 0) ;dat_out : out std_logic_vector(7 downto 0) ); end tri_s ;architecture behav of tri_s isbeginprocess(en, dat_0, dat_1)beginif en = '1' thendat_out <= dat_1 ;else dat_out <= dat_0 ;end if ;end process ;end behav ;/*--------ttt.vhd------*/ 频率字控制模块library ieee;use ieee.std_logic_1164.all;use ieee.std_logic_unsigned.all;entity ttt isport( clk : in std_logic ;dout : out std_logic_vector(3 downto 0));end ttt ;architecture kk of ttt isbeginprocess(clk)variable k0 : std_logic_vector(3 downto 0) ;beginif clk 'event and clk = '1' thenk0 := k0 + 1 ;end if ;dout <= k0 ;end process ;end kk ;/*---------dds.vhd------*/ 顶层文件LIBRARY ieee;USE ieee.std_logic_1164.all;LIBRARY work;ENTITY dds ISport(xiang_set : IN STD_LOGIC;count_clk : IN STD_LOGIC;system_clk : IN STD_LOGIC;set_ok : IN STD_LOGIC;set_up : IN STD_LOGIC;sel_in1 : IN STD_LOGIC;frep_in : IN STD_LOGIC;sel_in2 : IN STD_LOGIC;cs : OUT STD_LOGIC;wr : OUT STD_LOGIC;data20832 : OUT STD_LOGIC_VECTOR(7 downto 0);led_out : OUT STD_LOGIC_VECTOR(2 downto 0) );END dds;ARCHITECTURE bdf_type OF dds IScomponent set360PORT(set_up : IN STD_LOGIC;set_ok : IN STD_LOGIC;clk : IN STD_LOGIC;clk1 : IN STD_LOGIC;en : IN STD_LOGIC;frep_in : IN STD_LOGIC_VECTOR(3 downto 0);led_out : OUT STD_LOGIC_VECTOR(2 downto 0);load_data : OUT STD_LOGIC_VECTOR(9 downto 0) );end component;component sinPORT(clock : IN STD_LOGIC;address : IN STD_LOGIC_VECTOR(9 downto 0);q : OUT STD_LOGIC_VECTOR(7 downto 0));end component;component tri_sPORT(en : IN STD_LOGIC;dat_0 : IN STD_LOGIC_VECTOR(7 downto 0);dat_1 : IN STD_LOGIC_VECTOR(7 downto 0);dat_out : OUT STD_LOGIC_VECTOR(7 downto 0));end component;component fangPORT(clock : IN STD_LOGIC;address : IN STD_LOGIC_VECTOR(9 downto 0);q : OUT STD_LOGIC_VECTOR(7 downto 0));end component;component shanjiaoPORT(clock : IN STD_LOGIC;address : IN STD_LOGIC_VECTOR(9 downto 0);q : OUT STD_LOGIC_VECTOR(7 downto 0));end component;component tttPORT(clk : IN STD_LOGIC;dout : OUT STD_LOGIC_VECTOR(3 downto 0));end component;signal SYNTHESIZED_WIRE_0 : STD_LOGIC_VECTOR(3 downto 0); signal SYNTHESIZED_WIRE_9 : STD_LOGIC_VECTOR(9 downto 0); signal SYNTHESIZED_WIRE_2 : STD_LOGIC_VECTOR(7 downto 0); signal SYNTHESIZED_WIRE_3 : STD_LOGIC_VECTOR(7 downto 0); signal SYNTHESIZED_WIRE_6 : STD_LOGIC_VECTOR(7 downto 0); signal SYNTHESIZED_WIRE_7 : STD_LOGIC_VECTOR(7 downto 0); signal SYNTHESIZED_WIRE_8 : STD_LOGIC;BEGINcs <= '0';wr <= '0';b2v_inst : set360PORT MAP(set_up => set_up,set_ok => set_ok,clk => system_clk,clk1 => count_clk,en => xiang_set,frep_in => SYNTHESIZED_WIRE_0,led_out => led_out,load_data => SYNTHESIZED_WIRE_9);b2v_inst1 : sinPORT MAP(clock => system_clk,address => SYNTHESIZED_WIRE_9,q => SYNTHESIZED_WIRE_6);b2v_inst10 : tri_sPORT MAP(en => sel_in2,dat_0 => SYNTHESIZED_WIRE_2,dat_1 => SYNTHESIZED_WIRE_3,dat_out => data20832);b2v_inst11 : fangPORT MAP(clock => system_clk,address => SYNTHESIZED_WIRE_9,q => SYNTHESIZED_WIRE_3);b2v_inst2 : shanjiaoPORT MAP(clock => system_clk,address => SYNTHESIZED_WIRE_9,q => SYNTHESIZED_WIRE_7);b2v_inst7 : tttPORT MAP(clk => frep_in,dout => SYNTHESIZED_WIRE_0);b2v_inst8 : tri_sPORT MAP(en => sel_in1,dat_0 => SYNTHESIZED_WIRE_6,dat_1 => SYNTHESIZED_WIRE_7,dat_out => SYNTHESIZED_WIRE_2); END;。