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

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

举报
开通vip

基于FPGA的DDS信号发生器的设计 电工电子实验报告 课程名称 EDA技术基础 实验名称 综合实验总结 选题性质 基于 FPGA 的 DDS 信号发生器的设计 湖北师范学院电工电子实验教学示范中心·《EDA 技术基础》实验 2 基于 FPGA 的 DDS 信号发生器的设计 1 DDS 的基本原理 DDS 技术是一种把一系列数字量形式的信号通过 DAC 转换成模拟量形式的信号的 合成技术,它是将输出波形的一个完整的周期、幅...

基于FPGA的DDS信号发生器的设计
电工电子实验报告 课程名称 EDA技术基础 实验名称 综合实验总结 选题性质 基于 FPGA 的 DDS 信号发生器的设计 湖北师范学院电工电子实验教学示范中心·《EDA 技术基础》实验 2 基于 FPGA 的 DDS 信号发生器的设计 1 DDS 的基本原理 DDS 技术是一种把一系列数字量形式的信号通过 DAC 转换成模拟量形式的信号的 合成技术,它是将输出波形的一个完整的周期、幅度值都顺序地存放在波形存储器中, 通过控制相位增量产生频率、相位可控制的波形。DDS 电路一般包括基准时钟、相位增 量寄存器、相位累加器、波形存储器、D/A 转换器和低通滤波器(LPF)等模块,如图 1.1 所示。 相位增量寄存器寄存频率控制数据,相位累加器完成相位累加的功能,波形存储器 存储波形数据的单周期幅值数据,D/A 转换器将数字量形式的波形幅值数据转化为所要 求合成频率的模拟量形式信号,低通滤波器滤除谐波分量。 整个系统在统一的时钟下工作,从而保证所合成信号的精确。每来一个时钟脉冲, 相位增量寄存器频率控制数据与累加寄存器的累加相位数据相加,把相加后的结果送至 累加寄存器的数据输出端。这样,相位累加器在参考时钟的作用下,进行线性相位累加, 当相位累加器累加满量时就会产生一次溢出,完成一个周期性的动作,这个周期就是 DDS 合成信号的一个频率周期,累加器的溢出频率就是 DDS 输出的信号频率。 相位累加器输出的数据的高位地址作为波形存储器的地址,从而进行相位到幅值的 转换,即可在给定的时间上确定输出的波形幅值。 相位增量寄存器 相位累加器 地址寄存器 D/A转换顺波形存储器 时钟 滤波器 波形输出 控制数据 图 1-1:DDS 原理图 波形存储器产生的所需波形的幅值的数字数据通过 D/A转换器转换成模拟信号,经 过低通滤波器滤除不需要的分量以便输出频谱纯净的所需信号。信号发生器的输出频率 fo可表示为: N sfMfMf 2..0  ( 1.1) 式中 s f 为系统时钟, f 为系统分辨率,N为相位累加器位数,M为相位累加器的增量。 参数确定及误差分析. 2 参数确定 首先确定系统的分辨率 f ,最高频率 maxf ,及最高频率 maxf 下的最少采样点数 湖北师范学院电工电子实验教学示范中心·《EDA 技术基础》实验 3 minN 根据需要产生的最高频率 maxf 以及该频率下的最少采样点数 minN ,由公式 minmax .Nff s  (1.2) 确定系统时钟 s f 的下限值。同时又要满足分辨率计算公式 f f N s  2 (1.3) 综合考虑决定 s f 的值。 选定了 s f 的值后,则由公式(1.3)可 得 N2 = f f s  ,据此可确定相位累加器位 数 N。 然后由最高输出频率 Mffo  (1.4) 推出 M= S2 ,得出相位增量寄存器为 S位。 确定波形存储器的地址位数 W,本系统中决定寄存 Z2 个数据值,因此 RAM 地址为 Z位。 一般选用 FPGA/CPLD器件作为 DDS的实现器件,对于 D/A转换器的选择,首先要考 虑到 D/A转换器的转换速率。要实现所需的频率,D/A的转换速度要大于 minmax .Nf , 然后根据 D/A转换器字长所带来的误差,决定 D/A的位数。由此选择 D/A转换器的型号。 3 DDS 的 FPGA 实现设计 本设计要求 DDS实现的性能指标为:当系统时钟频率为 24MHz时,分辨率为 1.43Hz, 当相位增量寄存器为 19 位时,最高输出频率是 749731Hz。(理论上完全可以达到,甚至 更高,但是由于受到 DA 器件及运算放大器的影响,实际中的频率不可能达到)。 根据上面所列公式可以得出:累加器位数 N= 24;相位增量寄存器为 19位。 如图 3.1所示,DDS系统包括相位增量寄存器、相位累加器、地址寄存器、波形存 储器、时钟倍频器及地址发生部分等几个模块。内部所有模块均用 Verilog语言编写或 调用 maxplus2中的已有的 lpm库文件,其顶层设计用原理图的方式进行模块间的连接。 相位增量寄存器 相位累加器 地址寄存器 D/A转换顺波形存储器 单片机 键盘矩阵 时钟 滤波器 波形输出 图 3.1 DDS系统框图 下面就上面向个模块的结构进行论述: 湖北师范学院电工电子实验教学示范中心·《EDA 技术基础》实验 4 3.1 相位累加器 相位累加器在参考时钟的作用下,进行线性相位累加,当相位累加器累加满量时就 会产生一次溢出,完成一个周期性的动作,这个周期就是 DDS合成信号的一个频率周期, 累加器的溢出频率就是 DDS 输出的信号频率。相位增量分段寄存器的端口如图 3.1.1 所 示。根据前面的计算可知,相位增量寄存器需要 24位。 图 3.1.1 相位增量寄存器 图 3.1.2 是相位增量分段寄存器仿真图,从图中可以看出,在时钟的激励下,累加器 的仿真结果是正确的. 图 3.1.2累加器的仿真结果 3.2 波形存储器 波形存储器实际上就是一个 ROM,波形存储器存储的是所生成波形一周期采样 256 点的数据值,通过地址的改变,所输出的值就会变化,因为,地址不一定是连续变化的, 所以所输出的值也不是连续的,在同样的时钟周期下,地址间隔的变化也就造成了生成 波形的频率的变化。地址值每溢出一次,便完成了一个周期的输出。 当改变波形存储器中波形数据时,也就改变了输出波形。 图 3.2.1 ROM模块 ROM的设计直接调用 LPM中的库生成,端口分别为:时钟输入端 clock,输出数据总 线 daout(7:0),输入数据总线 result[23:16]. 地址总线 address(7:0)是相位累加器输出高 8位的数据.输出数据总线 douta(7:0) 连接输出缓冲通过 FPGA的 I/O口输出,作为 D/A转换器的输入。 3.3相位增量寄存器及显示模块. 这个模块的功能是接收从单片中传来的数据.从单片机中传递过来的数据为分两部 分,第一是频率控制字,即给相位增量寄存器的控制字.第二是将当前的输出频率显示在 数码管上.这个模块的底层文件是基于 Verilog语言描述的,在顶层上生成相就的功能模 湖北师范学院电工电子实验教学示范中心·《EDA 技术基础》实验 5 块.其生成的原理图如图 3.3.1所示: 图 3.3.1相位增量寄存器及显示模块 上面的顶层模块简要描述如下:clock 是系统输入时钟,LED_SEG[7..0]是 8 段数码管 的段选,LED_WEI[2..0]是 8 个数码管的位选。(这里联接是 38 译码器的输入端)。其源程 序如下: module led_print( clock, //输入时钟 led_seg, //数码管段选 led_wei, //数码管位选 Code, data_clk, write_data, ); input data_clk; input clock ; //时钟输入 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 /*********************************************************/ wire clock,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; reg write_flag; reg[23:0] write_data; always @( posedge data_clk )//送给 FPGA 的数据改变时. 湖北师范学院电工电子实验教学示范中心·《EDA 技术基础》实验 6 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@(posedge clock ) begin if (count == 24'd1200000)// begin count = 0; end else begin count = count +1; // write_data = 24'd699; end end 湖北师范学院电工电子实验教学示范中心·《EDA 技术基础》实验 7 /******************数码管扫描程序*************************/ 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 湖北师范学院电工电子实验教学示范中心·《EDA 技术基础》实验 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.4 FPGA与单片机通信接口设计 单片机在读得矩阵键盘的控制字后,必须把相应的数据传递给 FPGA。本实验中单片机所 传递的数据有两大部分。第一是传递给相位增量寄存器的相位增量字。第二是数码管要 显示当前在频率控制字下面的频率输出值。因为 FPGA 只负责扫描 8 个数码管,故其显 示的频率值必须是单片机计算好后再将其值传递给 FPGA显示。如图 3.4.1所示: FPGA 单片机 Px[7..0] CLK 图 3.4.1 FPGA与单片机通信接口设计 单片机与 FPGA 接口总共用了 9 根线,一根时钟线外加 8 根数据线。如图 3.4.1 所示。 每一个时钟下降沿时,单片机传送一个 8 位的数据到 FPGA 中。其中 8 位宽度的数据线 中高四位的值表示的是 FPGA 内各寄存器内约定好的地址,低四位表示的数要传递过来 的数据。在 FPGA 内部有下面一段代码: always @( posedge data_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; 湖北师范学院电工电子实验教学示范中心·《EDA 技术基础》实验 9 //给控制寄存器中的数据 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 实验总结 湖北师范学院电工电子实验教学示范中心·《EDA 技术基础》实验 10 通过本次基于 FPGA 的设计实验,不仅使我熟悉 DDS 的原理,而且对于单片机与 FPGA 综合应用也是一次很好的尝试。本次实验中所到的实验箱中的实验模块有 FPGA 核心板,AD/DA 模块,4*4 键盘模块,51 单片机模块。在这次设计实验过程中碰到了很多困 难,但是最后都解决了,有缺陷地方就是还可以把键盘扫描部分利用 FPGA 在 Verilog 语言的描述下完成此功能,这样可以充分利用 FPGA 资源,单片机部分只是进行简单的 数据处理即可。关于硬件扫描键盘部分,用 Verilog 在 MaxpluII 中实验了很久,但是最 终还是没有效果。总的来说,这次设计实验使我熟悉单片机与 FPGA 的综合应用。如果 想要进一步提高,还有待于理论的进一步学习。
本文档为【基于FPGA的DDS信号发生器的设计】,请使用软件OFFICE或WPS软件打开。作品中的文字与图均可以修改和编辑, 图片更改请在作品中右键图片并更换,文字修改请直接点击文字进行修改,也可以新增和删除文档中的内容。
该文档来自用户分享,如有侵权行为请发邮件ishare@vip.sina.com联系网站客服,我们会及时删除。
[版权声明] 本站所有资料为用户分享产生,若发现您的权利被侵害,请联系客服邮件isharekefu@iask.cn,我们尽快处理。
本作品所展示的图片、画像、字体、音乐的版权可能需版权方额外授权,请谨慎使用。
网站提供的党政主题相关内容(国旗、国徽、党徽..)目的在于配合国家政策宣传,仅限个人学习分享使用,禁止用于任何广告和商用目的。
下载需要: 免费 已有0 人下载
最新资料
资料动态
专题动态
is_081801
暂无简介~
格式:pdf
大小:344KB
软件:PDF阅读器
页数:10
分类:工学
上传时间:2011-11-19
浏览量:95