原创 【博客大赛】利用FPGA+DAC0832制作的信号源

2013-12-2 10:21 5933 21 28 分类: FPGA/CPLD

利用FPGA+DAC0832制作的信号源

制作信号源有多种方法,但是由于接口数量以及手头资源的因素,我选择了用FPGA来产生一个信号源,算是自己正式开始了FPGA逻辑设计吧。本文介绍的就是我自己利用cyclone系列的FPGA制作的信号源,信号源的设计包括以下几个部分:

1、整个设计框架

2、各个小模块的实现(可调分频模块,三角波产生模块(含rom的定制,需先生成.mif文件),正弦波产生(同上)模块,方波产生模块,锯齿波产生模块,具体生成方法同上,4选1多路选择器模块,4路输入及输出均为8位,DAC0832控制器)

3、外围电路的设计(包括频率控制,加 减 设置功能,以及直接设置多少频率,显示模块(待设计),DAC0832模块)

4、仿真结果

在每一个设计开始的时候,首先要进行的是整体框架的划分,即系统有哪些部分组成,模块与模块之间应该怎样互联,明确这些之后才是具体的底层实现。

一、整体设计的框架图

框图.jpg

系统时钟是FPGA正常工作所需的时钟(选取的是50MHz),时钟分频模块用于将系统时钟分频,它决定了信号波形的周期,通过控制它可以调整信号发生器产生的信号的周期(这里先介绍含有两个固定分频系数的分频器,如何产生可调周期的信号等下次详述)。接着是四个波形发生器,它们都需要先定制rom的初始化数据,然后再利用初始化的存储数据产生rom,利用QUARTUS Ⅱ产生各模块。4选1多路选择器,用于选择输出的波形,DAC0832控制器用于产生外部硬件的控制信号。接下来的是DAC0832的外部电路,用于产生最终输出的模拟信号。

在以上各模块中,难点是如何产生波形发生器,以及如何进行调频和调幅。(在本设计中只是用到了两个固定的周期,而且没有涉及到调幅,这些都将在下一篇中进行详述介绍)。

二、各小模块的具体实现

1、时钟分频模块

本部分设计的周期是6.25MHz和12.5MHz,对系统时钟进行8分频和4分频即可,分频系数分别为8和4。

具体实现电路原理图如下,rst信号用于复位,k4用于选择频率选择,当K4为高电平时输出频率为6.25MHz,为低电平时是12.5MHz。clkin是系统时钟为50MHz。

 

1.jpg

图1、分频模块

具体的FPGA实现代码如下:

library ieee;

use ieee.std_logic_1164.all;

use ieee.std_logic_unsigned.all;

use ieee.std_logic_arith.all;

 

entity divide_8 is

   port(

       rst : in std_logic;

       clkin: in std_logic;

       k4: in std_logic;

       clkout: out std_logic

   );

end entity;

 

architecture divide of divide_8 is

signal n :integer range 0 to 7;

signal clk: std_logic;

begin

   devide:process(clkin,rst)

   begin

       if rst='0' then                         --reset configration

          clkout<='0';

          n<=0;

          clk<='0';

       elsif rising_edge(clkin) then

          if k4='1' then

              if n=7 then                     --6.25MHz

                 n<=0;

                 clk<= not clk;

              else

                 n<=n+1;

              end if;

          else

              if n=3 then                     --12.5MHz

                 n<=0;

                 clk<=not clk;

              else

                 n<=n+1;

              end if;

          end if;

       end if;

       clkout<=clk;

   end process;

end architecture;

    2、波形发生模块

本模块分为正弦波发生器模块,三角波发生器模块,方波发生器模块,锯齿波发生模块,分别用于产生对应的波形数据。

产生流程如下:1、建立存储器初始化数据表(用于存储波形数据)。2、利用新建立的初始化数据表.mif文件定制对应的rom,生成对应的波形发生器。

具体步骤如下:

2.1新建一个.mif文件。File→new→memory initialization file→ok 填入的字数为128,字节位数为8(字),这用于确定建立的数据表的大小。

2.jpg

图2、新建的.mif文件

在里面填入波形初始化数据即可,由于采用的是8位的数模转换器,转换精度为8位,最大值为255,对应的如果参考电压为5V的话,精度即为19.6mV。 

定制rom过程如下:

利用megawizard plug-in manager定制正弦信号数据ROM宏功能块,并将上面的波形数据加载于此ROM中。

选择菜单tools—>megawizard plug-in manager命令,在出现的对话框中选择create a new custom,单击next,产生图3所示对话框,如图设置

3.jpg

                    图3. LPM宏功能模块设定

在左栏选择memory compiler项下的ROM:1-PORT,再选择器件和VHDL语言方式,输入ROM文件存放的路径和文件名。单击next出现图4对话框,按图中设置

4.jpg

图4. 选择控制线、地址线和数据线

注意需要将上面设置框中的64改选为128,产生7位地址线,单击next,按图5所示设置

5.jpg

                   图5. 选择地址锁存信号inclock

单击next,按图6所示设置

6.jpg

          图6. 调入ROM初始化数据文件并选择在系统读写功能

在上面的窗口中,点击browse选择工程下面的之前建立的sinwave.mif初始化数据文件,单击finish按钮完成ROM定制。将生成的sinwave.vhd文件加入工程中。

library ieee;

use ieee.std_logic_1164.all;

use ieee.std_logic_unsigned.all;

 

entity rom_out is

port(clk:in std_logic;

    dout:out std_logic_vector(7 downto 0));

end rom_out;

 

architecture dacc of rom_out is

component sinwave                                   

port(address:in std_logic_vector(6 downto 0);

    clock:in std_logic;

    q:out std_logic_vector(7 downto 0));

end component;

signal q1:std_logic_vector(6 downto 0);                 --generate --address signal,address rise by 1 along with clk's rising_edge

begin

process(clk)

begin

if clk'event and clk='1' then q1<=q1+1;

end if;

end process;

u1:sinwave port map(address=>q1,q=>dout,clock=>clk);    --call --sinwave.mif file

end dacc;

生成原理图文件:file-> Create/Update->create symbol files for current file即可生成。如图7所示:

7.jpg

图7、正弦波发生器

其余三种波形发生器的生成方法与正弦波类似,这里就不再赘述,下面只将三角波、方波、锯齿波的初始化数据表和波形发生器顶层设计列出。

2.2三角波生成器

数据表如图8所示(这些数据都是可以自己计算的,方法是在对应的函数图形上取点,只取纵坐标上的点,并将其存入数据表即可),

 

8.jpg

图8、三角波数据

三角波发生器顶层设计

library ieee;

use ieee.std_logic_1164.all;

use ieee.std_logic_unsigned.all;

 

entity tri_angle_out is

   port(

       clk: in std_logic;

       dout: out std_logic_vector(7 downto 0)

   );

end entity;

 

architecture transmit of tri_angle_out is

   component tri_angle                                                                                           --tri_angle rom claim

       port(

          address: in std_logic_vector(6 downto 0);

          clock: in std_logic;

          q: out std_logic_vector(7 downto 0)

       );

   end component;

signal q1 : std_logic_vector(6 downto 0);

 

begin

   process(clk)

   begin

       if(rising_edge(clk)) then

          q1<=q1+1;

       end if;

   end process;

   u1: tri_angle port map(clock=>clk,address=>q1,q=>dout);            --call tri_angle.vhd file

end architecture;

生成原理图文件,如图9所示

9.jpg

图9、三角波发生器原理图

2.3锯齿波发生器

波形数据如图10所示:此处只选取了64个数据,(这在数据rom定制中可以修改)

10.jpg

图10、锯齿波发生器数据

锯齿波发生器的顶层设计

library ieee;

use ieee.std_logic_1164.all;

use ieee.std_logic_unsigned.all;

 

entity sawtooth_out is

   port(

       clk: in std_logic;

       dout: out std_logic_vector(7 downto 0)

   );

end entity;

 

architecture transmit of sawtooth_out is

   component sawtooth

       port(

          address: in std_logic_vector(5 downto 0);

          clock: in std_logic;

          q: out std_logic_vector(7 downto 0)

       );

   end component;

signal q1 : std_logic_vector(5 downto 0);--由于是64个数据,所以此--处只有5位地址线  

 

begin

   process(clk)

   begin

       if(rising_edge(clk)) then

          q1<=q1+1;

       end if;

   end process;

   u1: sawtooth port map(clock=>clk,address=>q1,q=>dout);

end architecture;

原理图符号生成如图11所示:

11.jpg

图11锯齿波发生器原理图符号

2.4方波发生器模块

数据表如图12所示:

12.jpg

图12、方波发生器数据

方波发生器顶层设计:

library ieee;

use ieee.std_logic_1164.all;

use ieee.std_logic_unsigned.all;

 

entity fangbo_out is

   port(

       clk: in std_logic;

       dout: out std_logic_vector(7 downto 0)

   );

end entity;

 

architecture transmit of fangbo_out is

   component fangbo

       port(

          address: in std_logic_vector(6 downto 0);

          clock: in std_logic;

           q: out std_logic_vector(7 downto 0)

       );

   end component;

signal q1 : std_logic_vector(6 downto 0);

 

begin

   process(clk)

   begin

       if(rising_edge(clk)) then

          q1<=q1+1;

       end if;

   end process;

   u1: fangbo port map(clock=>clk,address=>q1,q=>dout);

end architecture;

方波发生器的原理图13所示:

13.jpg

图13、方波发生器原理图

注:在以上的顶层设计中,只是相对于定制的rom模块来说是顶层设计,并不是整个设计的顶层设计,每一个发生器的顶层设计中均需要调用已生成的IP核,即rom模块,这就需要先进行被调用模块的声明,然后还需要对其进行例化才能正确调用。

三、4选1多路选择器的设计

4选1多路选择器由4路8输入端及两条选择线控制,输出为1路8输出信号。当选择输入信号sel与输出的对应关系见具体设计。

具体实现如下所示:

library ieee;

use ieee.std_logic_1164.all;

use ieee.std_logic_unsigned.all;

 

entity mux4_1 is

   port(

       rst: in std_logic;

       din4,din3,din2,din1: in std_logic_vector(7 downto 0);

       sel: in std_logic_vector(1 downto 0);

       q: out std_logic_vector(7 downto 0)

   );

end entity;

architecture sel of mux4_1 is

begin

   process(sel,din4,din3,din2,din1,rst)

   begin

       if rst='0' then

          q<="00000000";                     --复位

       else

          case sel is                        --输入选择控制

              when "00"=> q<=din1;

              when "01"=> q<=din2;

              when "10"=> q<=din3;

              when "11"=> q<=din4;

              when others=> q<=din1;

          end case;

       end if;

   end process;

end architecture;

生成的原理图文件如图14所示:

14.jpg

图14、4选1多路选择器

四、DAC0832外部电路的设计:如图15所示:DAC0832的具体使用介绍网上已有很多资料介绍,本设计不再单独列出,可参照网上。本设计的DAC0832的引脚图如下所示:

15.jpg

图15、DAC0832的引脚图

DI0~DI7:数据输入线,TLL电平。

ILE:数据锁存允许控制信号输入线,高电平有效。

CS:片选信号输入线,低电平有效。

WR1:为输入寄存器的写选通信号。

XFER:数据传送控制信号输入线,低电平有效。

WR2:为DAC寄存器写选通输入线。

Iout1:电流输出线。当输入全为1时Iout1最大。

Iout2: 电流输出线。其值与Iout1之和为一常数。

Rfb:反馈信号输入线,芯片内部有反馈电阻.

Vcc:电源输入线  (+5v~+15v) 。

Vref:基准电压输入线  (-10v~+10v) 。

AGND:模拟地,摸拟信号和基准电源的参考地.。

DGND:数字地,两种地线在基准电源处共地比较好。

D/A转换结果采用电流形式输出。若需要相应的模拟电压信号,可通过一个高输入阻抗的线性运算放大器实现。运放的反馈电阻可通过RFB端引用片内固有电阻,也可外接。

控制时序如图16所示:

16.jpg

图16、DAC0832的控制时序图

具体设计如下所示:

library ieee;

use ieee.std_logic_1164.all;

use ieee.std_logic_unsigned.all;

use ieee.std_logic_arith.all;

 

entity DAC0832 is 

  port(din     :in std_logic_vector(7 downto 0);        --data input

       rst     :in std_logic;

       cs      :out std_logic;                          --控制信号cs

       wr1     :out std_logic;                          --控制信号wr1

       dout:out std_logic_vector(7 downto 0)        --波形数据输出

       );        

end DAC0832; 

architecture behav of DAC0832 is

begin

    process(rst)

    begin

       if rst='0' then

           cs<='1';

           wr1<='1';

           dout<="00000000";

       else

           cs<='0';

           wr1<='0';

           dout<=din;                   --cs、wr1赋值;波形数据输出;

       end if;

    end process;

end behav;

注:以上设计中没有涉及到的控制引脚信号,已利用外部硬件对应的连到地或电源线上了。

具体生成的原理图符号如图16所示:

17.jpg

图16、DAC0832控制模块原理图文件

将以上所生成的各部分按对应关系连接在顶层文件中,即构成了整个设计,具体如下(图17)可放大

 

 

18.jpg

六、仿真结果如下所示:

19.jpg

6.25MHz的正弦波

12.5 MHz的正弦波

 

6.25 MHz的方波

 

12.5 MHz的方波

6.25 MHz的三角波

 

12.5 MHz的三角波

       6.25 MHz的锯齿波

12.5 MHz的锯齿波

 

 

PARTNER CONTENT

文章评论7条评论)

登录后参与讨论

用户552311 2014-2-20 13:41

还不错,正好借鉴一下.

用户430542 2013-12-9 14:57

good 借鉴了

用户1725882 2013-12-2 19:41

为什么看起来不是很完美,不过总体还行

用户1725879 2013-12-2 19:22

不错,正好可以用到

用户1725879 2013-12-2 19:22

不错,正好可以用到

644398774_263592779 2013-12-1 23:54

明天胖叔叔要说你图挂了

1053683568_507245520 2013-12-1 20:56

图不能直接复制进去,大家可以下载附件查看
相关推荐阅读
1053683568_507245520 2014-03-20 11:19
cadence16.6 软件绘制PCB板
   最近一直在学习cadence的使用,现在就对近来学习做个总结,虽然还没有达到熟练的程度,但是也希望可以给后来者做个借鉴吧。         本人的方向是硬件方向,马上面临着找工作的压力。...
1053683568_507245520 2014-01-03 21:02
【博客大赛】自己定制DPRAM的读写操作
DPRAM的读写操作 下面是本人写的DPRAM的读写操作,自己定制DPRAM,不用altera FPGA 内部自带的IP core,选择的存储器块类型是M9K(对于不同类型的存储器块,当同时对...
1053683568_507245520 2013-12-15 20:51
【博客大赛】我的EDN
我的EDN 每次进入EDN网站,看到大家在踊跃的分享自己的学习经历,经验,以及聊生活谈梦想,都会激发我的热情,激发我对生活的热爱,对未来的幻想,对自己的思索。当我懒惰时,我会进来看看,看看特权...
1053683568_507245520 2013-12-07 11:31
【博客大赛】利用FPGA控制VGA接口来使显示器显示彩条纹(里面包括调试中的查错检查方法)
利用FPGA控制VGA接口来使显示器显示彩条纹 最近一直在调关于通过VGA接口来控制显示器的程序,今天终于调试出结果来了,赶紧上来与大家分享一下。 1、VGA显示原理 常见的彩色显示器...
1053683568_507245520 2013-12-06 11:45
【博客大赛】利用VHDL产生奇分频器
利用VHDL产生占空比为50%的奇倍数分频电路 一般的介绍VHDL语言的书在对分频器进行举例描述的时候,都是举得偶数倍分频的例子,因为那相对来说比较简单(只需要设置一个中间信号变量,然后在分频...
1053683568_507245520 2013-12-06 11:45
【博客大赛】VHDL进程语句的并行执行分析
相信许多人在学习VHDL时,都会对进程如何执行的,以及进程之间的并行执行产生疑问,本文将以下面一个具体的例子来分析单个进程的执行,与进程之间的并行执行。 library ieee; use...
EE直播间
更多
我要评论
7
21
关闭 站长推荐上一条 /3 下一条