任意波形发生器
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
1绪论
1.1任意波形发生器的发展历程
任意波形发生器(Arbitrary Wave Generator)是在1975年开发成功的,从此,信号发生器产品增加了一个新品种。
在任意波形发生器作为测量用信号激励源进入市场之前,为了产生非正弦波信号,已使用函数发生器提供三角波、斜波、方波和余弦波等几种特殊波形。
声音和振动分析需要复杂调制的信号源,以便仿真真实的信号,只有借助任意波形发生器,例如医疗仪器测试往往需要心电波形,任意波形发生器很容易产生各种非标准的振动信号。
早期的任意波形发生器主要着重音频频段,现在的任意波形发生器已扩展到射频频段,它与数字示波器(DSO)密切配合,只要数字示波器捕获的信号,任意波形发生器就能复制出同样的波形。
在电路构成上,数字示波器是模拟/数字转换,任意波形发生器是数字/模拟的逆转换,目前任意波形发生器的带宽达到2GHz,足够仿真许多移动通信、卫星电视的复杂信号。
生产数字示波器的仪器公司一般都供应任意波形发生器,如安捷伦、力科、泰克公司,也有只生产任意波形发生器的公司,如雷科、斯坦福公司。
仪器有台式、PC机虚拟、VXI总线、PXI总线等多种方式,大部分产品只有1路输出,有的高达16路输出。
仪器采样率从最低的100KS/s到4GS/s,相当实时带宽50kHz到最高的2GHz。
产生任意波形的方法主要有两种:即存储器和直接数字合成(DDS),前者电路比较简单,分两种形式:相位累加器式与计数器式,但需要较深的存储容量。
任意波形发生器的波形定义主要有面板设定、方程式设定、波形下载、软件设定、数字示波器下载、内置编辑器等多种。
1.2任意波形发生器的发展趋势及应用
任意波形发生器的应用非常广泛,在原理上可仿真任意波形,只要数字示波器或其它记录仪捕捉到的波形,任意波形发生器都可复制出,特别有用的是仿真单次偶发的信号,例如地震波形、汽车碰撞波形等等。
任意波形发生器的发展趋势是更高取样率,更高分辨率和更大存储量,目前实时带宽超过1GHz的产品比较少,而且分辨率只有8位,不能满足快速发展的移动通信和高速网络的测量要求。
与数字存储示波器相比,任意波形发生器的全面指标存在明显差距,前者的取样率达到20GS/s和带宽6GHz,后者的取样率是4.8GS/s 和带宽2GHz。
任意波形发生器首先要赶上数字存储示波器,然后再往前发展,因为在电路构成方面,任意波形发生器的核心部件是高速数/模转换器,它的工艺潜力还很大,显然缺少的是市场需求。
任意波形发生器在通信系统、测试系统等方面得到广泛应用。
任意波形发生器的另一重要应用领域是低频,例如心电图、汽车点火、防撞气囊、医疗仪器等。
2统分析及方案论证
2.1系统分析
本设计要求利用实验仪器现有的资源,通过FPGA(EPM7128SLC84-15)、D/A (AD558)、时钟模块等设计一个全数字化的波形发生器。
通过对输入端的控制,可输出方波、三角波、锯齿波、正弦波四种波形,并可通过频率控制端对输出波形的频率进行简单控制。
波形发生器有多种实现方案,一种是根据波形函数通过VHDL写出每一种波形的描述代码,再把产生的数据通过外部的D/A转换成相应的模拟波形;另一种是用其他的工具产生各种波形的16进制代码,通过VHDL描述一个ROM和相应的控制器,再在时钟信号作用下,把数据输出到外部D/A转换成相应的模拟波形。
由于对ROM的设计并不熟悉,故采用第一种方案。
2.1方案论证
对于采用第一种方案实现,其外部电路主要有:波形选择开关(拨码开关)、D/A转换器(AD558)、时钟信号源。
1.波形发生器的组成电路主要有:信号输入电路,A/D采样电路,时钟电路,FPGA芯片。
除FPGA芯片需自行设计外,其他电路在实验仪器中都已做好,只需将它们与FPGA芯片连接起来即可。
2.考虑D/A采样方法。
在设计波形发生器时,对于D/A采用何种方法对信号进行采样也是很关键的,采样方法主要有实时采样和等效采样两种。
一般来说,对于使用哪种取样类型取决于测试信号的形式:如果是重复信号波形,采用实时取样和等效取样都行,但使用等效取样方法更为经济。
对观察非周期信号和瞬态信号,实时取样方法能更好的处理和分析。
3.FPGA设计。
FPGA设计是关键,它是整个波形发生器的控制中心和数据处理中心,负责完成D/A的控制。
在FPGA芯片中,至少需要设计的模块有:D/A控制器,时序产生器,同步器等。
1)D/A控制器:生成采样时钟及D/A采样芯片的控制信号,并读取D/A
采样结果。
2)时序产生器:产生各单元所需的各种时钟信号。
3)同步器:产生各种所需的同步信号,用来实现对相应数据的同步传送
3系统设计
3.1 VHDL设计
VHDL描述见附录。
生成器件
端口说明:
CLK:时钟脉冲CLR:清零ENA:使能控制
FC:频率选择 WC:波形选择CQ:输出(接AD558)
3.2 设计说明
D/A转换器的功能是把二进制数字量电信号转换为与其数值成正比的模拟量电信号。
AD558可读入从“00000000”到“11111111”共256个二进制数,转换成对应模拟量电信号的值从0V到2.56V。
本VHDL设计以计数器为基础,针对AD558的特性,通过不同的计数方式来产生不同的波形描述代码。
通过时钟信号clk 来产生方波、三角波的计数控制信号clk1和clk2;clk1为clk的128分频信号,clk2为clk的256分频信号;并对clk 进行2分频来产生正弦波的时钟触发信号ck。
➢方波:在clk时钟触发信号下,分别以clk1和clk2为控制信号,对fb进行赋值。
➢锯齿波:在clk时钟触发信号下,对jcb分别进行7位二进制计数和8位二进制计数。
➢三角波:在clk时钟触发信号下,以clk1和clk2为控制信号,分别对sjb 进行7位二进制计数和8位二进制计数。
➢正弦波:首先将正弦波的半周期分成64份,每份取一点,并算出各点的值。
在ck时钟触发信号下,通过count 计数,逐一将正弦波半周期
内64个点的值赋给zxb,再通过clk2来控制zxb的输出。
由于方波、三角波均以clk为时钟信号,且以clk1和clk2为计数控制信号,故输出波形的频率高、低分别为clk频率的1/256和1/512,;锯齿波的高频和低频分别为clk频率的1/128和1/256;正弦波的频率为clk频率的1/128。
4系统仿真测试
4.1波形仿真
4.1.1清零
说明:当clk=0或ena=0时,或二者都等于0时,电路不工作。
4.1.2方波
说明:电路工作,当fc=0且wc=00时,输出低频方波,以clk1为赋值控制信号,分别赋给输出信号低电平“00000000”(0V),高电平“11111111”(2.56V)。
说明:电路工作,当fc=1且wc=00时,输出高频方波,赋值以clk2为控制信号,分别赋给输出信号低电平“00000000”(0V),高电平“11111111”(2.56V)。
说明:电路工作,当fc=0且wc=01时,输出低频三角波,计数以clk2为控制信号,输出信号进行8位二进制加/减计数。
说明:电路工作,当fc=1且wc=01时,输出高频三角波,计数以clk1为控制信号,输出信号进行7位二进制加/减计数。
说明:电路工作,当fc=0且wc=10时,输出低频锯齿波,计数以clk2为控制信号,输出信号进行8位二进制计数。
说明:电路工作,当fc=1且wc=10时,输出高频锯齿波,计数以clk1为控制信号,输出信号进行7位二进制计数。
说明:电路工作,当wc=11时,输出正弦波,以ck为count的计数时钟信号,利用count进行6位二进制加/减计数,将正弦波半周期64点所的对应的二进制数值逐一赋给输出信号。
4.2硬件调试
Clk:f=4.99989-4.99988MHz
方波
fc=0时 f=9.76-9.77KHz, 周期T=102.3-102.9us;
振幅:2.55V 占空比:50.03%-50.46% fc=1时 f=19.53-19.54KHz, 周期T=51.00-51.95us;
振幅:2.56V 占空比:49.83%-50.94%
三角波
fc=0时 f=9.78-9.83KHz, 周期T=101.5-102.8us;
振幅:2.56V 占空比:48.9%-51.8%
fc=1时 f=19.48-19.61KHz, 周期T=50.69-51.16us;
振幅:1.27V 占空比:49.51%-52.21%
锯齿波
fc=0时 f=19.27-17.79KHz, 周期T=50.63-51.33us;
振幅:2.56V 占空比:50.68%-51.04%
fc=1时 f=38.22-40.01KHz, 周期T=25.03-26.92us;
振幅:1.26V 占空比:50.76%-53.05%
正弦波
经过调试,若要产生正弦波clk需要提高频率
当clk :f=19.9995-19.9996MHz时,产生正弦波频率为
f=39.15-39.84KHz, 周期T=25.30-25.74us;
振幅:2.56V 占空比:50.88%-51.64%
分析:由硬件测试可知,产生的各波形的频率符合实验设计思路。
但是,在生成正弦波时,需要增大clk的频率,且生成的正弦波不是很稳定。
5总结
通过本次设计,使我进一步的掌握了MAX plusⅡ的操作和使用,也对VHDL描述语言有了更深刻的认识和理解,充分提高了自己独立设计的能力。
对于设计过程中出现的问题,能够及时地处理和解决。
在这次设计中,我学到了很多东西,例如对于上网如何更有效的搜索资料,在设计中,对于资料的有效整理、分类、取舍都有了很大收获。
同时在这个过程中也加深了对所学理论知识的理解。
通过查阅大量的资料和书籍,学到了很多新的方法,拓展了自己的思维。
也了解很多相关方面的新技术,新理论,新动向。
6参考文献
电子工业出版社《VHDL语言设计技术》陈耀和著
机械工业出版社《VHDL与数字电路设计》将亮、齐兆群、李晓凯著
7附录
根据设计要求,VHDL设计描述如下:
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
entity waves is
port(clk,clr,ena,fc:in std_logic;
wc:in std_logic_vector(1 downto 0);
cq:out std_logic_vector(7 downto 0));
end entity;
architecture a of waves is
signal fb,jcb,sjb,zxb:std_logic_vector(7 downto 0); --各种波形 signal cqi:std_logic_vector(8 downto 0);
signal count:std_logic_vector(5 downto 0);
signal count1:std_logic_vector(1 downto 0);
signal clk1,clk2,ck: std_logic;
begin
p1:process(clk,clr,ena) is --产生计数控制信号 begin
if clr='0' then cqi<="000000000";
elsif clk'event and clk='1' then
if ena='1' then
cqi<=cqi+'1';
end if;
end if;
end process p1;
clk1<='0' when cqi<128 or (cqi>255 and cqi<384)
else '1';
clk2<='0' when cqi<256
else '1';
p3:process(clk,clr,clk1,clk2) --方波产生模块begin
if clr='0'then
fb<=(others=>'0');
elsif(clk'event and clk='1') then
if (clk1='0'and fc='1') then
fb<="00000000";
elsif (clk1='1' and fc='1') then
fb<="11111111";
elsif (clk2='0' and fc='0') then
fb<="00000000";
elsif (clk2='1' and fc='0') then
fb<="11111111";
end if;
end if;
end process p3;
p4:process(clk,clr,clk1,clk2) --三角波产生模块
begin
if clr='0'then
sjb<="00000000";
elsif(clk'event and clk='1') then
if (clk1='0'and fc='1')then
if sjb="01111111" then sjb<="00000000";
else sjb<=sjb+1;
end if;
elsif (clk1='1'and fc='1')then
if sjb="00000000" then sjb<="01111111";
else sjb<=sjb-1;
end if;
elsif (clk2='0'and fc='0')then
sjb<=sjb+1;
elsif (clk2='1'and fc='0')then
sjb<=sjb-1;
end if;
end if;
end process p4;
p5:process(clk,clr,ena) is --锯齿波产生模块begin
if clr='0' then jcb<="00000000";
elsif clk'event and clk='1' then
if (ena='1'and fc='1') then
if jcb="01111111" then jcb<="00000000";
else jcb<=jcb+'1';
end if;
elsif (ena='1'and fc='0') then
jcb<=jcb+'1';
end if;
end if;
end process p5;
p6:process(clk,clr,ena) --分频模块,产生正弦波触发脉冲 begin
if clr='0' then count1<="00";
elsif clk'event and clk='1' then
if ena='1' then
count1<=count1+'1';
end if;
end if;
end process p6;
ck<='1' when count1<="01"
else '0';
p7:process(ck,clk1,clr,ena) --正弦波产生模块begin
if clr='0' then count<="000000";
elsif ck'event and ck='1' then
if clk2='0' then
count<=count+'1';
elsif clk2='1' then
count<=count-'1';
end if;
end if;
end process p7;
zxb<="00000000" when count="00000" else --正弦波赋值"00000000" when count="00001" else
"00000000" when count="00010" else
"00000001" when count="00011" else
"00000001" when count="00100" else
"00000010" when count="00101" else
"00000011" when count="00110" else
"00000100" when count="00111" else
"00000110" when count="01000" else
"00001000" when count="01001" else
"00001011" when count="01010" else
"00001110" when count="01011" else
"00010001" when count="01100" else
"00010101" when count="01101" else
"00011000" when count="01110" else
"00011100" when count="01111" else
"00100001" when count="10000" else
"00100101" when count="10001" else
"00101010" when count="10010" else
"00101111" when count="10011" else
"00110101" when count="10100" else
"00111010" when count="10101" else
"01000000" when count="10110" else
"01000110" when count="10111" else
"01001100" when count="11000" else
"01010010" when count="11001" else
"01011000" when count="11010" else
"01011111" when count="11011" else
"01100101" when count="11100" else
"01101100" when count="11101" else
"01110010" when count="11110" else
"01111001" when count="11111" else
"10000000" when count="100000" else
"10000110" when count="100001" else
"10001101" when count="100010" else
"10010011" when count="100011" else
"10011010" when count="100100" else
"10100000" when count="100101" else
"10100111" when count="100110" else
"10101101" when count="100111" else
"10110011" when count="101000" else
"10111001" when count="101001" else
"10111111" when count="101010" else
"11000101" when count="101011" else
"11001010" when count="101100" else
"11010000" when count="101101" else
"11010101" when count="101110" else
"11011010" when count="101111" else
"11011110" when count="110000" else
"11100011" when count="110001" else
"11100111" when count="110010" else
"11101010" when count="110011" else
"11101110" when count="110100" else
"11110001" when count="110101" else
"11110100" when count="110110" else
"11110111" when count="110111" else
"11111001" when count="111000" else
"11111011" when count="111001" else
"11111100" when count="111010" else
"11111101" when count="111011" else
"11111110" when count="111100" else
"11111111" when count="111101" else
"11111111" when count="111110" else
"11111111" when count="111111" else
"000000";
p8:process(wc,fb,sjb,jcb,zxb) --波形选择模块begin
if wc="00" then
cq<=fb;
elsif wc="01" then
cq<=sjb;
elsif wc="10" then
cq<=jcb;
elsif wc="11" then
cq<=zxb;
else cq<="00000000";
end if;
end process p8;
end a;。