基于FPGA的DDS信号发生器的设计.docx

上传人:b****6 文档编号:7439838 上传时间:2023-01-24 格式:DOCX 页数:11 大小:139.05KB
下载 相关 举报
基于FPGA的DDS信号发生器的设计.docx_第1页
第1页 / 共11页
基于FPGA的DDS信号发生器的设计.docx_第2页
第2页 / 共11页
基于FPGA的DDS信号发生器的设计.docx_第3页
第3页 / 共11页
基于FPGA的DDS信号发生器的设计.docx_第4页
第4页 / 共11页
基于FPGA的DDS信号发生器的设计.docx_第5页
第5页 / 共11页
点击查看更多>>
下载资源
资源描述

基于FPGA的DDS信号发生器的设计.docx

《基于FPGA的DDS信号发生器的设计.docx》由会员分享,可在线阅读,更多相关《基于FPGA的DDS信号发生器的设计.docx(11页珍藏版)》请在冰豆网上搜索。

基于FPGA的DDS信号发生器的设计.docx

基于FPGA的DDS信号发生器的设计

电工电子实验报告

课程名称

EDA技术基础

实验名称

综合实验总结

选题性质

基于FPGA的DDS信号发生器的设计

基于FPGA的DDS信号发生器的设计

1DDS的基本原理

DDS技术是一种把一系列数字量形式的信号通过DAC转换成模拟量形式的信号的合成技术,它是将输出波形的一个完整的周期、幅度值都顺序地存放在波形存储器中,通过控制相位增量产生频率、相位可控制的波形。

DDS电路一般包括基准时钟、相位增量寄存器、相位累加器、波形存储器、D/A转换器和低通滤波器(LPF)等模块,如图1.1所示。

相位增量寄存器寄存频率控制数据,相位累加器完成相位累加的功能,波形存储器存储波形数据的单周期幅值数据,D/A转换器将数字量形式的波形幅值数据转化为所要求合成频率的模拟量形式信号,低通滤波器滤除谐波分量。

整个系统在统一的时钟下工作,从而保证所合成信号的精确。

每来一个时钟脉冲,相位增量寄存器频率控制数据和累加寄存器的累加相位数据相加,把相加后的结果送至累加寄存器的数据输出端。

这样,相位累加器在参考时钟的作用下,进行线性相位累加,当相位累加器累加满量时就会产生一次溢出,完成一个周期性的动作,这个周期就是DDS合成信号的一个频率周期,累加器的溢出频率就是DDS输出的信号频率。

相位累加器输出的数据的高位地址作为波形存储器的地址,从而进行相位到幅值的转换,即可在给定的时间上确定输出的波形幅值。

图1-1:

DDS原理图

波形存储器产生的所需波形的幅值的数字数据通过D/A转换器转换成模拟信号,经过低通滤波器滤除不需要的分量以便输出频谱纯净的所需信号。

信号发生器的输出频率fo可表示为:

(1.1)

式中

为系统时钟,

为系统分辨率,N为相位累加器位数,M为相位累加器的增量。

参数确定及误差分析.

2参数确定

首先确定系统的分辨率

,最高频率

,及最高频率

下的最少采样点数

根据需要产生的最高频率

以及该频率下的最少采样点数

,由公式

(1.2)

确定系统时钟

的下限值。

同时又要满足分辨率计算公式

(1.3)

综合考虑决定

的值。

选定了

的值后,则由公式(1.3)可得

据此可确定相位累加器位数N。

然后由最高输出频率

(1.4)

推出M=

,得出相位增量寄存器为S位。

确定波形存储器的地址位数W,本系统中决定寄存

个数据值,因此RAM地址为Z位。

一般选用FPGA/CPLD器件作为DDS的实现器件,对于D/A转换器的选择,首先要考虑到D/A转换器的转换速率。

要实现所需的频率,D/A的转换速度要大于

,然后根据D/A转换器字长所带来的误差,决定D/A的位数。

由此选择D/A转换器的型号。

3DDS的FPGA实现设计

本设计要求DDS实现的性能指标为:

当系统时钟频率为24MHz时,分辨率为1.43Hz,当相位增量寄存器为19位时,最高输出频率是749731Hz。

(理论上完全可以达到,甚至更高,但是由于受到DA器件及运算放大器的影响,实际中的频率不可能达到)。

根据上面所列公式可以得出:

累加器位数N=24;相位增量寄存器为19位。

如图3.1所示,DDS系统包括相位增量寄存器、相位累加器、地址寄存器、波形存储器、时钟倍频器及地址发生部分等几个模块。

内部所有模块均用Verilog语言编写或调用maxplus2中的已有的lpm库文件,其顶层设计用原理图的方式进行模块间的连接。

图3.1DDS系统框图

下面就上面向个模块的结构进行论述:

3.1相位累加器

相位累加器在参考时钟的作用下,进行线性相位累加,当相位累加器累加满量时就会产生一次溢出,完成一个周期性的动作,这个周期就是DDS合成信号的一个频率周期,累加器的溢出频率就是DDS输出的信号频率。

相位增量分段寄存器的端口如图3.1.1所示。

根据前面的计算可知,相位增量寄存器需要24位。

图3.1.1相位增量寄存器

图3.1.2是相位增量分段寄存器仿真图,从图中可以看出,在时钟的激励下,累加器的仿真结果是正确的.

图3.1.2累加器的仿真结果

3.2波形存储器

波形存储器实际上就是一个ROM,波形存储器存储的是所生成波形一周期采样256点的数据值,通过地址的改变,所输出的值就会变化,因为,地址不一定是连续变化的,所以所输出的值也不是连续的,在同样的时钟周期下,地址间隔的变化也就造成了生成波形的频率的变化。

地址值每溢出一次,便完成了一个周期的输出。

当改变波形存储器中波形数据时,也就改变了输出波形。

图3.2.1ROM模块

ROM的设计直接调用LPM中的库生成,端口分别为:

时钟输入端clock,输出数据总线daout(7:

0),输入数据总线result[23:

16].

地址总线address(7:

0)是相位累加器输出高8位的数据.输出数据总线douta(7:

0)连接输出缓冲通过FPGA的I/O口输出,作为D/A转换器的输入。

3.3相位增量寄存器及显示模块.

这个模块的功能是接收从单片中传来的数据.从单片机中传递过来的数据为分两部分,第一是频率控制字,即给相位增量寄存器的控制字.第二是将当前的输出频率显示在数码管上.这个模块的底层文件是基于Verilog语言描述的,在顶层上生成相就的功能模块.其生成的原理图如图3.3.1所示:

图3.3.1相位增量寄存器及显示模块

上面的顶层模块简要描述如下:

clock是系统输入时钟,LED_SEG[7..0]是8段数码管的段选,LED_WEI[2..0]是8个数码管的位选。

(这里联接是38译码器的输入端)。

其源程序如下:

moduleled_print(

clock,//输入时钟

led_seg,//数码管段选

led_wei,//数码管位选

Code,

data_clk,

write_data,

);

inputdata_clk;

inputclock;//时钟输入

input[7:

0]Code;

output[23:

0]write_data;

output[2:

0]led_wei;//132,133,135

output[7:

0]led_seg;//131,130,128,122,121,120,119,118

/*********************************************************/

wireclock,rst;

reg[2:

0]led_wei;

reg[7:

0]led_seg;

reg[23:

0]count;//计数器单元

reg[3:

0]ledbuff;

reg[23:

0]times;//时分秒要分配的单元

reg[3:

0]seg_count;

reg[3:

0]seg_flag;

regwrite_flag;

reg[23:

0]write_data;

always@(posedgedata_clk)//送给FPGA的数据改变时.

begin

seg_count=Code[3:

0];//数据位

seg_flag=Code[7:

4];//标志位

case(seg_flag)

//在数码管中显示的数字

4'b0000:

times[3:

0]<=seg_count;

4'b0001:

times[7:

4]<=seg_count;

4'b0010:

times[11:

8]<=seg_count;

4'b0011:

times[15:

12]<=seg_count;

4'b0100:

times[19:

16]<=seg_count;

4'b0101:

times[23:

20]<=seg_count;

//给控制寄存器中的数据

4'b0110:

write_data[3:

0]<=seg_count;

4'b0111:

write_data[7:

4]<=seg_count;

4'b1000:

write_data[11:

8]<=seg_count;

4'b1001:

write_data[15:

12]<=seg_count;

4'b1010:

write_data[19:

16]<=seg_count;

4'b1011:

write_data[23:

20]<=seg_count;

default:

begin

times<=times;

write_data<=write_data;

end

endcase

end

always@(posedgeclock)

begin

if(count==24'd1200000)//

begin

count=0;

end

else

begin

count=count+1;

//write_data=24'd699;

end

end

/******************数码管扫描程序*************************/

always@(count[12:

10])

begin

case(count[12:

10])

3'h0:

led_wei=3'b000;

3'h1:

led_wei=3'b001;

3'h2:

led_wei=3'b010;

3'h3:

led_wei=3'b011;

3'h4:

led_wei=3'b100;

3'h5:

led_wei=3'b101;

3'h6:

led_wei=3'b110;

3'h7:

led_wei=3'b111;

default:

led_wei=3'bzzz;

endcase

case(count[12:

10])

3'h0:

ledbuff=4'ha;

3'h1:

ledbuff=4'hb;

3'h2:

ledbuff=times[3:

0];

3'h3:

ledbuff=times[7:

4];

3'h4:

ledbuff=times[11:

8];

3'h5:

ledbuff=times[15:

12];

3'h6:

ledbuff=times[19:

16];

3'h7:

ledbuff=times[23:

20];

default:

ledbuff=3'bzzz;

endcase

end

always@(ledbuff)

begin

case(ledbuff)

4'h0:

led_seg=8'h3f;//0

4'h1:

led_seg=8'h06;//1

4'h2:

led_seg=8'h5b;//2

4'h3:

led_seg=8'h4f;//3

4'h4:

led_seg=8'h66;//4

4'h5:

led_seg=8'h6d;//5

4'h6:

led_seg=8'h7d;//6

4'h7:

led_seg=8'h07;//7

4'h8:

led_seg=8'h7f;//8

4'h9:

led_seg=8'h6f;//9

4'hb:

led_seg=8'h76;//H

4'ha:

led_seg=8'h5b;//Z

4'hc:

led_seg=8'b00;

default:

led_seg=8'hzz;

endcase

end

endmodule

3.4FPGA和单片机通信接口设计

单片机在读得矩阵键盘的控制字后,必须把相应的数据传递给FPGA。

本实验中单片机所传递的数据有两大部分。

第一是传递给相位增量寄存器的相位增量字。

第二是数码管要显示当前在频率控制字下面的频率输出值。

因为FPGA只负责扫描8个数码管,故其显示的频率值必须是单片机计算好后再将其值传递给FPGA显示。

如图3.4.1所示:

图3.4.1FPGA和单片机通信接口设计

单片机和FPGA接口总共用了9根线,一根时钟线外加8根数据线。

如图3.4.1所示。

每一个时钟下降沿时,单片机传送一个8位的数据到FPGA中。

其中8位宽度的数据线中高四位的值表示的是FPGA内各寄存器内约定好的地址,低四位表示的数要传递过来的数据。

在FPGA内部有下面一段代码:

always@(posedgedata_clk)//送给FPGA的数据改变时.

begin

seg_count=Code[3:

0];//数据位

seg_flag=Code[7:

4];//标志位

case(seg_flag)

//在数码管中显示的数字

4'b0000:

times[3:

0]<=seg_count;

4'b0001:

times[7:

4]<=seg_count;

4'b0010:

times[11:

8]<=seg_count;

4'b0011:

times[15:

12]<=seg_count;

4'b0100:

times[19:

16]<=seg_count;

4'b0101:

times[23:

20]<=seg_count;

//给控制寄存器中的数据

4'b0110:

write_data[3:

0]<=seg_count;

4'b0111:

write_data[7:

4]<=seg_count;

4'b1000:

write_data[11:

8]<=seg_count;

4'b1001:

write_data[15:

12]<=seg_count;

4'b1010:

write_data[19:

16]<=seg_count;

4'b1011:

write_data[23:

20]<=seg_count;

default:

begin

times<=times;

write_data<=write_data;

end

endcase

end

在单片机每产生一个有下降的时钟信号时,会执行上面一块代码程序。

每次传送8位数据后,进行分离如下:

seg_count=Code[3:

0];//数据位

seg_flag=Code[7:

4];//标志位

再根据各个标志位的不同,传递给FPGA各个寄存器中不同的数据。

高四位作为标志位,最多可表示16种不同的情况,而本实验最多只用到其中的12种,因此是满足要求的。

3.4顶层框图

图3.4.1生成的顶层框图

4实验总结

通过本次基于FPGA的设计实验,不仅使我熟悉DDS的原理,而且对于单片机和FPGA综合使用也是一次很好的尝试。

本次实验中所到的实验箱中的实验模块有FPGA核心板,AD/DA模块,4*4键盘模块,51单片机模块。

在这次设计实验过程中碰到了很多困难,但是最后都解决了,有缺陷地方就是还可以把键盘扫描部分利用FPGA在Verilog语言的描述下完成此功能,这样可以充分利用FPGA资源,单片机部分只是进行简单的数据处理即可。

关于硬件扫描键盘部分,用Verilog在MaxpluII中实验了很久,但是最终还是没有效果。

总的来说,这次设计实验使我熟悉单片机和FPGA的综合使用。

如果想要进一步提高,还有待于理论的进一步学习。

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 小学教育 > 语文

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1