我最近在设计一个正弦波发生器的过程中,出现了很诡异的问题。频率稍微上调多点,输出波形就截止。采取fpga的de0开发板,方案如下:1. 输入正弦波频率f(可调节频率) ——> 频率处理以及显示(元件1) ——> 输出整形(integer)频率 f
2. 输入频率 ——> 选择一个周期内对正弦波的采样次数 sa_times(元件2) ——> 输出sa_times
3. f 和 sa_times 以及 50MHz晶振时钟 同时输入 ——> 分频(元件3)(n=f * sa_times , count=50M / n)——> 输出采样时钟(即采样频率为sa_times*f)
4 .输入采样时钟和sa_times ——> 扫描正弦函数表,分离出正弦波频率(元件4) ——> 输出按正弦变化的8位二进制序列
按此方案编程,外接数模转换以及滤波电路等输至示波器内,外部硬件电路经过检测毫无问题。而且能产生精确度极高,很漂亮的波形。 但当我们调节频率时,在初始化频率的基础上, 当我们把频率往上调时,调到初始化频率的数倍(3~4倍)以上后,输出波形总是突然截止,只能通过重新载入程序(重启开关)的方式回复波形。 而当我们初始化频率设置在任何频率时,都能得到对应频率的初始化波形。这是为何?是不是程序有问题?本人已纠结数周,求求大神解救!!!
附部分vhdl代码:(可读性非常好!)
元件1:频率预置(preset)f entity preset is port( clk: in std_logic; botton2 : in std_logic; en_switch : in std_logic_vector(5 downto 0); ------------限于DE0板,采用开关使能,按钮计数的方式调频 ...... f: out integer ); end preset architecture behavor of preset is -----------------------------内部信号------------------------------------- -----------------------------频率位BCD码----------------------------- signal tmp0: std_logic_vector(3 downto 0):=(others =>'0'); -----------频率个位 signal tmp1: std_logic_vector(3 downto 0):=(others =>'0'); signal tmp2: std_logic_vector(3 downto 0):=(others =>'0'); signal tmp3: std_logic_vector(3 downto 0):=(others =>'0'); signal tmp4: std_logic_vector(3 downto 0):=(others =>'0'); signal tmp5: std_logic_vector(3 downto 0):=(others =>'0');--------------频率百千位 signal ftmp: integer range 20 to 200000 = 20; ---------------------------------------------------------------------------------- begin --------------------------预置频率进程--------------------------------- process(botton2) begin if falling_edge(botton2) then ---------------------------------------------------------------- if tmp0="1001" and en_switch(0)='1' then tmp0<="0000"; tmp1<=tmp1+1; elsif(en_switch(0)='1') then tmp0<=tmp0+1; end if; …… if tmp5="1001" and en_switch(5)='1' then
tmp5<="0000";
elsif(en_switch(5)='1') then
tmp5<=tmp5+1;
end if; end progess; ftmp<=cov_integer(tmp0)+10*conv_integer(tmp1)+....;f<=ftmp; end behavor;
元件2:选择一周期采样次数sa_n entity sa_choose is port( f: in integer ; sa_n:out integer ); end sa_choose; architecture behavor of sa_choose is signal sa:integer range 0 to 512 :=64; begin process(f) begin if f <15000 then sa<=256; elsif f >= 15000 and f < 30000 then sa<=128; elsif f >= 30000 and f < 70000 then sa<=64; elsif f >= 70000 and f < 140000 then sa<=32; else sa<=20; end if; end process; sa_n<=sa; end behavor;
元件3:分频产生采样时钟 entity frequency_tune is port( clk : in std_logic; sa_n: in integer; f : in integer ; sa_clk : out std_logic ----------------采样时钟输出 ); end frequency_tune; architecture behavor of frequency_tune is signal count : integer :=0; signal n: integer; signal sa_clk_f:integer:=10240; begin n<=50000000/sa_clk_f; sa_clk_f<=sa_n*f; ------------------------分频系数 process(clk,f) begin if rising_edge(clk) then if(count=n) then count<=0; sa_clk <='1'; else count<=count+1; sa_clk <='0'; end if; end if; end process; end behavor;
[ 本帖最后由 simpheele 于 2012-5-21 17:38 编辑 ]
|