1、 多功能信号发生器 多功能信号发生器 摘要 随着EDA技术以及大规模集成电路技术的迅猛发展,波形发生器的各方面性能指标都达到了一个新的水平。Altera,Xilinx,AMD等公司都推出了比较好的CPLD和FPGA产品,并为这些产品的设计配备了设计、下载软件,这些软件除了支持图形方式设计数字系统外,还支持设计多种数字系统的语言,使数字系统设计起来更加容易。SOPC-NIOS EDA/SOPC实验开发系统是根据现代电子发展的方向,集EDA和SOPC
2、系统开发为一体的综合性实验开发系统,除了满足高校专、本科生和研究生的SOPC教学实验开发之外,也是电子设计和电子项目开发的理想工具。整个开发系统由核心板SOPC-NIOSII-EP2C35、SOPC开发平台和扩展板构成,根据用户不同的需求配置成不同的开发系统。采用CPLD/FPGA器件在QuartuesII设计环境中用VHDL语言完成的波形发生器具有频率稳定性高,可靠性高,输出波形稳定等特点。本文介绍了基于EDA技术的波形发生器的研究与设计。 在本课程设计中使用Altera公司的EP2C35系列的FPGA芯片,利用SOPC-NIOSII-EP2C35开发板高速AD/DA转换模块等资源
3、运用LPM-ROM制定的方法设计的波形发生器,利用4×4键盘阵列实现了正弦波,方波,三角波,以及锯齿波四种波形的输出及频率和幅度的控制,并利用液晶显示模块实现信号频率、波形和幅度的显示,经过实际下载到FPGA实验板上,设计要求已经完全实现。 关键字:FPGA;VHDL;EDA;QUARUS2;多功能信号发生器 © 目 录 1.摘要-----------------------------------------------------------1 2.多功能发生器设计目的与设计的意义---
4、3 2.1多功能发生器设计目的---------------------------------------3 2.2多功能发生器设计的意义-------------------------------------3 3.多功能发生器课程设计的内容及相关要求---------------------------3 4多功能发生器设计的方案以及相关原理-----------------------------4 4.1. 多功能发生器设计的原理框图-------------------------------4 4.2
5、 多功能信号发生器的实现的方案------------------------------4 4.21 频率产生模块------------------------------------------4 4.22 键盘控制模块------------------------------------------5 4.23 波形控制模块------------------------------------------6 4.24 16*16点阵显示模块和数码管显示模块--------------------7 4.25 用LPM-ROM制定的波形数据的文
6、件模块--------------------7 5.多功能发生器的仿真结果及波形------------------------------------8 6 多功能发生器设计的心得体会--------------------------------------8 7. 多功能发生器设计的参考文献-------------------------------------9 8.附录-----------------------------------------------------------10 附录A 多功能发生器的原理总框图---------------------
7、10 附录B 各个模块的相关程序-------------------------------------12 B.1 频率控制模块的程序----------------------------------12 B.2 键盘控制模块程序------------------------------------15 B.3 波形控制模块程序------------------------------------18 B.4 16*16点阵与数码管显示模块--------------------------20 B.5 波形数
8、据文件程序------------------------------------26 2.多功能发生器设计目的与设计的意义 2.1 设计目的 (1)掌握方波—三角波——正弦波函多功能发生器的原理及设计方法。 (2)掌握用VHDL语言来编写相关程序。 (3)了解并熟悉EDA/SOPC系统开发平台。 (4)能够使用电路仿真软件进行电路调试。 2.2 设计意义 多功能信号发生器作为一种常用的信号源,是现代测试领域内应用最为广泛的通用仪器之一。 在研制、生产、测试和维修各种电子元件、部件以及整机设备时,都学要有信号源,由它产生不
9、同频率不同波形的电压、电流信号并加到被测器件或设备上,用其他仪器观察、测量被测仪器的输出响应,以分析确定它们的性能参数。信号发生器是电子测量领域中最基本、应用最广泛的一类电子仪器。它可以产生多种波形信号,如正弦波,三角波,方波等,因而广泛用于通信、雷达、导航、宇航等领域。 3. 多功能发生器课程设计的内容及相关要求 在本课程设计中我们这组使用Altera公司的EP2C35系列的FPGA芯片,利用SOPC-NIOSII-EP2C35开发板利用键盘,液晶显示及数码管显示模块、信号源模块等资源,来实现一个多功能信号发生器。主要的要求是能实现以下几种功能: 1利用4×4键
10、盘阵列实现键盘频率、波形和幅度的控制 2 利用液晶显示模块实现信号频率、波形和幅度的显示 3 利用16*16点阵显示实现信号幅度级别的显示 4 利用8位动态七段码管显示实现信号频率的显示 5 利用信号源模块实现频率、波形和幅度的控制 4.设计方案的提出以及相关原理 4.1 多功能发生器的流程框图 4.2 多功能信号发生器的实现的方案 在本课程设计中我们组将使用Altera公司的EP2C35系列的FPGA芯片,该芯片的EP2C35核心板为基于Altera Cyclone器件的嵌入式系统开发提供了
11、一个很好的硬件平台,在这个平台上我们在该核心板上按照本课程的要求将使用频率产生模块、键盘控制模块,波形类型控制模块,一个显示在16*16点阵显示波形在数码管显示频率模块,以及一个用LPM-ROM制定的波形数据的文件模块共5个模块来实现用键盘及拨码开关来实现波形的控制,及频率和幅度的控制,并在16*16的点阵上显示键盘所控制的我们设计的三角波,正弦波,锯齿波、方波这4种波形,以及可以看到它的幅度在按照我们的设计思路在发生变化,在数码管上则显示其频率按照我们的控制逐步变大和变小的功能。这5个模块的简单介绍以及相关原理如下: 4.21 频率产生模块 频率产生模块的结构框图如下:
12、 频率控制模块主要是通过对信号源模块过来的频率进行分频的原理来实现波形频率增加以及减少的控制,本模块通过拨码开关的接入来分别实现频率的复位,频率增加以及减少的功能。 4.22 键盘控制模块 键盘控制模块的原理框图如下 : 键盘控制模块主要是通过4*4矩阵键盘扫描的方法来识别是那个键被按下,来实现相对应的功能。我们给大家介绍的是比较常用的行扫描法,行扫描法又称为逐行(或列)扫描查询法,是一种最常用的按键识别方法,具体介绍介绍过程如下: 1、判断键盘中有无键按下 将全部行线Y0-Y3置低电平,然后检测列线的状态。只要有一列的电平为低,则表示键盘中有键被按
13、下,而且闭合的键位于低电平线与4根行线相交叉的4个按键之中。若所有列线均为高电平,则键盘中无键按下。 2、判断闭合键所在的位置 在确认有键按下后,即可进入确定具体闭合键的过程。其方法是:依次将行线置为低电平,即在置某根行线为低电平时,其它线为高电平。在确定某根行线位置为低电平后,再逐行检测各列线的电平状态。若某列为低,则该列线与置为低电平的行线交叉处的按键就是闭合的按键。 4.23 波形控制模块 波形控制模块的原理框图如下 波形控制模块主要是通过按键来转换用来波形查表的地址,通过查询到的地址来输出相应的波形,来达到按键控制波形的目的。 4.24 16*16点阵显示模块和数码
14、管显示模块 16*16点阵显示模块和数码管显示模块结构框图如下 : 7段数码管显示的主要利用的动态扫描的原理,具体如下:即在某一时刻,只让某一位的位选线处于导通状态,而其它各位的位选线处于关闭状态。同时,段线上输出相应位要显示字符的字型码。这样在同一时刻,只有选通的那一位显示出字符,而其它各位则是熄灭的,如此循环下去,就可以使各位数码管显示出将要显示的字符。 16*16扫描LED点阵的工作原理与8位扫描数码管类似,只是显示的方式与结果不一样而已. 4.45 用LPM-ROM制定的波形数据的文件模块 用LPM-ROM制定的波形数据的文件模块结构框图: 在这个课程设计中
15、我们制作一个 LPM-ROM波形数据文件,把4种波形数据均放在该数据文件中。这4中波形的产生原理我们都是用查表的原理来实现的,其中正弦表值可以用Matalab,C 语言等程序语言生成。在一个周期中取样点越多则输出的波形失真度越少,但是点越多存储正弦波表值所需要的空间就越大,编写越复杂。在要求不是很严格的情况下取64个点就可以了。 5.多功能发生器的仿真结果及波形 我们首先新建一个波形文件,然后设置下仿真的时间,我们就开始进行仿真,经过仿真得到的结果如下: , 6. 多功能发生器设计的心得体会 在小规模的数字集成电路淘汰的今天,作为一个电子技术工程
16、技术人员不懂VHDL语言和CPLD、FPGA器件设计就像在计算机时代不懂电脑一样可怕。FPGA的EP2C35核心板为基于Altera Cyclone器件的嵌入式系统开发提供了一个很好的硬件平台,它为我们这样的开发人员提供很多资源,也为我们以后的继续学习打下比较坚实的基础。这次EDA课程设计历时两个星期,在整整两个星期的日子里,可以说是苦多于甜,但是可以学的到很多很多的东西,同时不仅可以巩固以前所学过的知识,而且学到了很多在书本上所没有学到过的知识。通过这次设计,进一步加深了对EDA的了解,让我对它有了更加浓厚的兴趣。特别是当每一个子模块编写调试成功时,心里特别的开心。但是在编写顶层文件的程序时
17、遇到了不少问题,特别是各元件之间的连接,以及信号的定义,总是有错误,在细心的检查下,终于找出了错误和警告,排除困难后,程序编译就通过了,心里终于舒了一口气。在波形仿真时,也遇到了一点困难,想要的结果不能在波形上得到正确的显示,后来,在数十次的调试之后,才发现是因为输入的时钟信号对于器件的延迟时间来说太短了。经过屡次调试,终于找到了比较合适的输入数值:时钟周期设置在15秒左右比较合适。另外,Endtime的值需要设置的长一点:500us左右,这样就可以观察到完整的仿真结果。 其次,在连接各个模块的时候一定要注意各个输入、输出引脚的线宽,因为每个线宽是不一样的,只要让各个线宽互相匹配,才能
18、得出正确的结果,否则,出现任何一点小的误差就会导致整个文件系统的编译出现错误提示,在器件的选择上也有一定的技巧,只有选择了合适当前电路所适合的器件,编译才能得到完满成功。 通过这次课程设计使我懂得了理论与实际相结合是很重要的,只有理论知识是远远不够的,只有把所学的理论知识与实践相结合起来,从理论中得出结论,才能真正为社会服务,从而提高自己的实际动手能力和独立思考的能力。在设计的过程中遇到问题,可以说得是困难重重,这毕竟第一次做的,难免会遇到过各种各样的问题,同时在设计的过程中发现了自己的不足之处,对以前所学过的知识理解得不够深刻,掌握得不够牢固。 总的来说,这次设计的多功能发生器还
19、是比较成功的,在设计中遇到了很多问题,最后在老师的辛勤的指导下,终于游逆而解,有点小小的成就感,终于觉得平时所学的知识有了实用的价值,达到了理论与实际相结合的目的,不仅学到了不少知识,而且锻炼了自己的能力,使自己对以后的路有了更好的了解。 7. 多功能发生器设计的参考文献 [1] 《SOPCIIEDA实验指导书》(第二版). [2] 《SOPCII使用手册》(第二版). [3] [4]《EDA技术基础》. 谭会生编著. 湖南大学出版社,2004. [5]《EDA技术实用教程(第二版),潘松、黄继业编著 ,科学出版社 ,2005. 8.附录 附录A 多功
20、能发生器的原理总框图 附录B 各个模块的相关程序 B.1 频率控制模块的程序 library ieee; use ieee.std_logic_1164.all; use ieee.std_logic_arith.all; use ieee.std_logic_unsigned.all; -------------------------------------------------------------------- entity pinglvcon
21、trol is port( Clk : in std_logic; --时钟输入 Rst : in bit; --复位输入 NU,ND : in bit; --输入:控制频率的改变 --keyout1 : in std_logic_vector(3 downto 0); --输入:控制波形的改变 Fout : out std_logic --时钟输出 ); end
22、 pinglvcontrol; -------------------------------------------------------------------- architecture behave of pinglvcontrol is signal M_Buffer : std_logic_vector(19 downto 0); signal N_Count :std_logic_vector(14 downto 0); signal clkin : std_logic; signal Clk_Count : std_log
23、ic_vector(22 downto 0); --产生一个低速时钟,用于按键判断 begin process(Clk) --计数器累加 begin if(Clk'event and Clk='1') then if(N_Count=M_Buffer+M_Buffer) then N_Count<="000000000000000"; else N_Count<=N_Count+1;
24、 end if;
end if;
end process;
process(Clk) --波形判断
begin
if(Clk'event and Clk='1') then
if(N_Count 25、 Fout<='0';
end if;
end if;
end process;
process(Clk)
begin
if(Clk'event and Clk='1') then
Clk_Count<=Clk_Count+1;
end if;
clkin<=Clk_Count(22);
end process;
process(clkin) -- 26、频率及占空比的改变1
begin
if(clkin'event and clkin='0') then
if(Rst='0') then
M_Buffer<="00000000000000100000";
--N_Buffer<="000010000000000";
elsif(NU='0') then
--N_Buffer<=N_Buffer+1;
M_Buff 27、er<=M_Buffer+1 ;
elsif(ND='0') then
--N_Buffer<=N_Buffer-1;
M_Buffer<=M_Buffer-1;
end if;
end if;
end process;
end behave;
B.2键盘控制模块程序
library ieee;
use ieee.std_logic_1164.all;
use ie 28、ee.std_logic_arith.all;
use ieee.std_logic_unsigned.all;
--------------------------------------------------------------------
entity keycontrol is
port( Clk : in std_logic; --时钟信号
Kr : in std_logic_vector(3 downto 0); --键盘行
29、 Kc : buffer std_logic_vector(3 downto 0); --键盘列
keyout : out std_logic_vector(3 downto 0)
);
end keycontrol;
--------------------------------------------------------------------
architecture behave of keycontrol is
signal ke 30、yr,keyc : std_logic_vector(3 downto 0);
signal kcount : std_logic_vector(2 downto 0);
signal dcount : std_logic_vector(1 downto 0);
signal kflag1,kflag2 : std_logic;
signal buff8 : std_logic_vector(3 downto 0);
signal Disp_Temp : integer range 0 to 15;
31、
signal Disp_Decode : std_logic_vector(6 downto 0);
begin
process(Clk) --扫描键盘
begin
if(Clk'event and Clk='1') then
if(Kr="1111") then
kflag1<='0';
kcount<=kcount+1;
if(kcount=0) t 32、hen
kc<="1110";
elsif(kcount=1) then
kc<="1101";
elsif(kcount=2) then
kc<="1011";
else
kc<="0111";
end if;
else
kflag 33、1<='1';
keyr<=Kr;
keyc<=Kc;
end if;
kflag2<=kflag1;
end if;
end process;
process(Clk) -- 获取键值
begin
if(Clk'event and Clk='1') then
if(kflag1='1' and kflag2='0') t 34、hen
if(keyr="0111") then
case keyc is
when "0111"=>buff8<="0001";
when "1011"=>buff8<="0100";
when "1101"=>buff8<="0111";
when "1110"=>buff8<="1110";
35、 when others=>buff8<=buff8; --no change
end case;
elsif(keyr="1011") then
case keyc is
when "0111"=>buff8<="0010";
when "1011"=>buff8<="0101";
when "1101"=>bu 36、ff8<="1000";
when "1110"=>buff8<="0000";
when others=>buff8<=buff8; --no change
end case;
elsif(keyr="1101") then
case keyc is
when "1110"=>buff8<="1111";
37、 when "1101"=>buff8<="1001";
when "1011"=>buff8<="0110";
when "0111"=>buff8<="0011";
when others=>buff8<=buff8; --no change
end case;
elsif(keyr="1110") then
38、 case keyc is
when "1110"=>buff8<="1101";
when "1101"=>buff8<="1100";
when "1011"=>buff8<="1011";
when "0111"=>buff8<="1010";
when others=>buff8<=buff8; --no change
39、 end case;
end if;
end if;
end if;
keyout<=buff8;
end process;
end behave;
B.3 波形控制模块程序
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
use ieee.s 40、td_logic_arith.all;
entity boxingcontrol is
port(clk : in std_logic;
key : in std_logic_vector(3 downto 0);
dout : out integer range 1023 downto 0);
end boxingcontrol;
architecture behave of boxingcontrol is
signal q 41、1: integer range 255 downto 0;
signal q2: integer range 511 downto 256;
signal q3: integer range 767 downto 512;
signal q4: integer range 1023 downto 768;
begin
process(clk,key,q1,q2,q3,q4)
begin
if key="0000" then
if(clk'event a 42、nd clk='1')then
if q1=255 then
q1<=0;
else
q1 <= q1+1;
end if;
end if;
dout<=q1;
elsif key="0001" then
if(clk'event and clk='1')then
if q 43、2=511 then
q2<=256;
else
q2 <= q2+1;
end if;
end if;
dout<=q2;
elsif key="0010" then
if(clk'event and clk='1')then
if q3=767 then
q3<=512 44、
else
q3 <= q3+1;
end if;
end if;
dout<=q3;
elsif key="0011" then
if(clk'event and clk='1')then
if q4=1023 then
q4<=768;
else
45、 q4 <= q4+1;
end if;
end if;
dout<=q4;
end if;
end process;
end ;
B.4 16*16点阵与数码管显示模块
----------------------------------------------------------------------
-- Title:点阵汉字显示实验(共阴极性 )--
46、 -- Author:Pan hongtao --
-- Data: 2004-10-1 --
------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
use ieee.std_logic_un 47、signed.all;
--------------------------------------------------------------------
entity display is
port( clk : in std_logic; --时钟输入
swich : in std_logic_vector(7 downto 0);
SEL:OUT STD_LOGIC_VECTOR(2 DOWNTO 0);
keyc : out std_logic_vecto 48、r(15 downto 0); --点阵列控制
keyr : out std_logic_vector(15 downto 0) --点阵行显示
);
end display;
--------------------------------------------------------------------
architecture behave of display is
signal cdount : std_logic_vector(3 downto 0);
signal 49、dount : std_logic_vector(8 downto 0);
signal s:std_logic_vector(4 downto 0);
signal lout4:std_logic_vector(3 downto 0);
signal xt:std_logic;
begin
process (clk)
begin
if (clk'event and clk='1')then
if (s="10111") then
s<="00000";
else s<=s+1;
end if;
end if;
end process;
process (s)
begin
case s is
when "00000"=>lout4<="1111"; sel<="000"; keyc<="0000000000000000";xt<='1';
when "00001"=>lout4<="1111"; sel<="001"; keyc<="0000000000000000";xt<='1';
when "00010"=>lout4<="1111"; se






