基于FPGA的DDS信号发生器汇总文档格式.docx
《基于FPGA的DDS信号发生器汇总文档格式.docx》由会员分享,可在线阅读,更多相关《基于FPGA的DDS信号发生器汇总文档格式.docx(15页珍藏版)》请在冰豆网上搜索。
其基本框图如下。
(1)相位累加器是DDS的核心部分。
一般是由数字全加器和数字寄存器组成,
实现相位累加。
如下图所示。
一般DDS的累加器都采用二进制,线性数字信号通过相位累加器实现逐级
的累加。
假设累加器字长为N,频率控制字为K,控制时钟频率为fc,系统在同
一个时钟下工作,每个时钟周期加法器做一次累加计算。
因为累加器的满偏是2^N,所以累加一次,相当于做一次2Ⅳ模的运算。
得到的和作为相位值。
(2)波形函数存储在ROM中。
根据累加器输出的相位值,作为地址,寻找存储在ROM中的波形函数的幅度量化值,完成相位到幅值的转换,输出相对应的序列。
(3)数模转换器DAC是DDS中的重要部分。
经过查表以后得到的是离散的脉冲信号,通过数模转换器将转换成为连续平滑的信号。
DDS输出的最高频率主要跟DAC的性能有关。
因为一个正弦周期内采样点越少,越容易发生失真现象。
为了获得较为理想的信号,一般DAC之后都会接一平滑滤波器。
下图可以直观的显示出各部件在波形输出过程中的效果。
可以以正弦波为例阐述DDS的基本原理。
设正弦信号S(≠)的表达式为:
其中,A为振幅,f为频率,丸为初始相位。
一个正弦波的参数由此三项决
定。
在实际应用过程中,信号的频率与初始相位无关,简单分析,令A为1,那
么s(t)可以变换为:
可以推出:
相同单位时间T内,不同频率与相对应的相位增量不同,因此
由此可知,相位在时域内随时间均匀变化时,生成频率为
的正弦波。
这是DDS技术的基本理论。
因为正弦波与DDS中的相位累加器都是周期性的,那么相位值与正弦信号
的线性特征也是一致。
相位累加器做K的模数运算,因此频率控制字越长,最
后合成的信号频率也就越高。
同样设:
K为频率控制字,正为时钟频率,N为相位累加器的长度。
那么,合成的信号频率为:
改变频率控制字K,输出的频率会随之连续变化,增大K,信号频率会随之
增大;
增大N,信号频率也会随之增大。
一般最低的输出频率为:
由奈奎斯特抽样定理知,为了保证信号不发生重叠,最高频率应为:
而实际应用中,为了避免相位抖动造成的失真现象,输出频率一般不超过时钟频
率的40%,也即是:
正弦波查询表ROM也是制作的重点。
在FPGA中ROM表的尺寸随着地址位数或数据位数的增加呈指数递增,如何在满足性能的前提下节省资源开销。
一方面通过相位累加器的输出截断方式,例如从32位的相位累加器结果中提取高16位作为ROM的查询地址,由此而产生的误差会对频谱纯度有影响,但是对波形的精度的影响是可以忽略的;
另一方面可以根据信号周期对称性来压缩ROM的尺寸,这时系统硬件设计复杂度会有所增加。
因此,需要选取合适的参数和ROM压缩技术,在满足系统性能的前提下使得系统尽量优化。
3.2DAC0832原理
DAC0832是8分辨率的D/A转换集成芯片。
与微处理器完全兼容。
这个DA芯片以其价格低廉、接口简单、转换控制容易等优点,在单片机应用系统中得到广泛的应用。
D/A转换器由8位输入锁存器、8位DAC寄存器、8位D/A转换电路及转换控制电路构成。
主要参数如下所示
*分辨率为8位;
*电流稳定时间1us;
*可单缓冲、双缓冲或直接数字输入;
*只需在满量程下调整其线性度;
*单一电源供电(+5V~+15V);
各个引脚作用功能如下所示:
*D0~D7:
8位数据输入线,TTL电平,有效时间应大于90ns(否则锁存器的数据会出错);
*ILE:
数据锁存允许控制信号输入线,高电平有效;
*CS:
片选信号输入线(选通数据锁存器),低电平有效;
*WR1:
数据锁存器写选通输入线,负脉冲(脉宽应大于500ns)有效。
由ILE、CS、WR1的逻辑组合产生LE1,当LE1为高电平时,数据锁存器状态随输入数据线变换,LE1的负跳变时将输入数据锁存;
*XFER:
数据传输控制信号输入线,低电平有效,负脉冲(脉宽应大于500ns)有效;
*WR2:
DAC寄存器选通输入线,负脉冲(脉宽应大于500ns)有效。
由WR2、XFER的逻辑组合产生LE2,当LE2为高电平时,DAC寄存器的输出随寄存器的输入而变化,LE2的负跳变时将数据锁存器的内容打入DAC寄存器并开始D/A转换。
*IOUT1:
电流输出端1,其值随DAC寄存器的内容线性变化;
*IOUT2:
电流输出端2,其值与IOUT1值之和为一常数;
*Rfb:
反馈信号输入线,改变Rfb端外接电阻值可调整转换满量程精度;
*Vcc:
电源输入端,Vcc的范围为+5V~+15V;
*VREF:
基准电压输入线,VREF的范围为-10V~+10V;
*AGND:
模拟信号地;
*DGND:
数字信号地。
图3-1DAC0832原理图
3.2.1.DAC0832的操作时序:
图3-2DAC0832操作时序
DAC0832为电流型输出芯片,一般而言,若要将输出转化为模拟电压,还需要在输出端加电流--电压转换电路。
在本试验箱中,为了简化电路,直接将DAC0832设计成如下如下的形式,该电路形式虽然不是标准的电路形式,但该电路可以直接输出模拟电压,从而简化了电路形式。
图3-3.矩阵键盘电路图
图3-4.DAC0832电路图
3.3实验设计步骤
1.新建工程
新建工程文件夹,在该文件夹下新建工程DAC0832。
2.编写顶层VerilogHDL文件
很据原理实验的内容,编写各个功能模块的VerilogHDL文件
3.锁定管脚
给各个管脚按照嵌入式系统实验箱的管脚对照表进行管脚分配
4.下载。
下载后,用示波器检测DAC0832的输出端,观察示波器上的波形。
四、解决的关键或难点问题
本次设计中各功能模块利用VerilogHDL语言设计,在FPGA中实现,因此硬件编程语言的使用是关键和难点。
同时通过FPGA控制DAC将数字信号转化为模拟信号也是设计关键。
五、性能测试与分析
5.1累加器程序及其仿真
moduleACC(rst,acc_clk,data_fre,data_pha,result);
inputacc_clk;
inputrst;
//写使能信号,低有效
input[19:
0]data_fre,data_pha;
output[19:
0]result;
reg[19:
0]N;
always@(posedgeacc_clk,negedgerst)
begin
if(!
rst)
result<
=0;
else
N<
=data_fre+N;
=data_pha+N;
end
end
Endmodule
图5-1累加器输出仿真
在本设计中,我采用的ROM存储深度为1024,地址为10位,因此需要将累加器的输出截断高10位,具体程序代码如下:
//---------------------------------------
//累加器输出截断高10位,连续赋给rom
wire[19:
0]A;
wire[9:
0]address1;
0]address2;
0]address3;
0]address4;
assignaddress1=A[19:
10];
assignaddress2=A[19:
assignaddress3=A[19:
assignaddress4=A[19:
5.2ROM设计及其仿真
本实验我设定的输出波形总共有四种,分别是正弦波,三角波,方波和锯齿波。
因此在累加器的输出端,需要对四个ROM进行选择,我的实现方法是利用ROM的时钟使能控制端来对ROM进行选择,chose由波形选择按键控制。
ROM的输出由嵌套的三目运算符来实现选择。
具体的程序代码如下:
//ROM选择
wire[3:
0]chose;
wireclken1;
wireclken2;
wireclken3;
wireclken4;
assignclken1=chose[0];
assignclken2=chose[1];
assignclken3=chose[2];
assignclken4=chose[3];
//ROM输出
wire[7:
0]dac_in;
0]sin_out;
0]saw_out;
0]squ_out;
0]tri_out;
assigndac_in=(chose[0]==1)?
sin_out:
(chose[1]==1)?
saw_out:
(chose[2]==1)?
squ_out:
(chose[3]==1)?
tri_out:
8'
b0;
图5-2ROM输出正弦波仿真
5.3DAC0832状态机
由图3-2的操作时序,可以写出DAC0832的状态机,程序源码如下:
moduledac_0832(
dac_clk,rst,
data_in,data_out,
CS,WR
);
inputdac_clk;
//复位
input[7:
0]data_in;
//8位数据输入
outputregCS;
//DA0832片选信号
outputregWR;
//读入信号
outputreg[7:
0]data_out;
//8位数据输出
reg[7:
0]data_in_reg;
always@(posedgedac_clkornegedgerst)//与ROM时钟同步,让数据稳定传输
if(!
rst)
data_in_reg<
else
=data_in;
reg[3:
0]cnt2;
always@(posedgedac_clkornegedgerst)
cnt2<
=4'
if(cnt2==4'
d9)
=cnt2+1'
b1;
rst)
CS<
=1'
WR<
data_out<
=8'
end
case(cnt2)//经过300ns的保持时间,CS首先拉低,拉低时间为1000ns
1,2,3,4,5,6,7,8,9,:
//1000NS计数
CS<
=1'
default:
endcase
case(cnt2)//CS拉低后200ns,WR拉低900ns
2,3,4,5,6,7,8,9,:
//900NS计数
begin
case(cnt2)
1,2,3,4,5,6,7,8,:
//CS拉低后100ns,将数据送出,时间持续900ns
data_out<
=data_in_reg;
;
endmodule
图5-3DAC0832控制器仿真
六、结论
该实验是一个完整的设计实验,从方案的确定到最终的测试,让我们收获颇多。
完成该工程,不仅要对结构级建模的思想有很深的了解,而且要学习ROM的使用方法,这一系列都会使我的编程能力大大提高。
通过该实验,我们学会了如何去完整的设计一个FPGA项目,获益匪浅。
在完成设计的过程中,需要不断的查找资料,进行方案的论证;
调试程序阶段,先进行仿真,再在实验板上运行,根据实验现象,对程序作出修改,最终使实验结果与预期一致。
通过该实验,我们学习并掌握了DDS原理,ROM读取数据,矩阵键盘的使用方法等一系列知识。
增强了自己理论与实际结合的能力,对FPGA的功能以及verilog的用法有了更深一步的了解。