废话
总体方案论证与选择
方案一:采用模拟锁相环实现。模拟锁相环技术是一项比较成熟的技术。应用模拟锁相环,可将基准频率倍频,或分频得到所需的频率,且调节精度可以做到相当高、稳定性也比较好。但模拟锁相环模拟电路复杂,不易调节,成本较高,并且频率调节不便且调节范围小,输出波形的毛刺较多,得不到满意的效果。
方案二:采用直接数字频率合成,用单片机作为核心控制部件。能达到较高的要求,实现各种波形输出,但受限于运算位数和运算速度,产生的波形往往达不到满意效果,并且频率可调范围小,很难得到较高频率,并且单片机的引脚少,存储容量少,这就导致了外围电路复杂。
方案三:采用直接数字频率合成,用FPGA器件作为核心控制部件。精度高稳定性好,得到波形平滑,特别是由于FPGA的高速度,能实现较高频率的波形。控制上更方便,可得到较宽频率范围的波形输出,步进小,外围电路简单易实现。
经过上述分析,核心控制系统采用方案三。
DDS模块方案论证
方案一:采用高性能DDS单片电路的解决方案。
随着微电子技术的飞速发展,目前高超性能优良的DDS产品不断推出,主要有Qualcomm、AD、Sciteg和Stanford等公司单片电路(monolithic)。Qualcomm公司推出了DDS系列Q2220、Q2230、Q2334、Q2240、Q2368,其中Q2368的时钟频率为130MHz,分辨率为0.03Hz,变频时间为0.1μs;美国AD公司也相继推出了他们的DDS系列:AD9850、AD9851、可以实现线性调频的AD9852、两路正交输出的AD9854以及以DDS为核心的QPSK调制器AD9853、数字上变频器AD9856和AD9857。AD公司的DDS系列产品以其较高的性能价格比,目前取得了极为广泛的应用。
方案二:采用低频正弦波DDS单片电路的解决方案
此方案的典型电路有MicroLinear公司的电源管理事业部推出低频正弦波DDS单片电路ML2035以其价格低廉、使用简单得到广泛应用。ML2035特性:(1)输出频率为直流到25kHz,在时钟输入为12.352MHz以外频率分辨率可达到1.5Hz(-0.75~+0.75Hz),输出正弦波信号的峰-峰值为Vcc;(2)高度集成化,无需或仅需极少的外接元件支持,自带3~12MHz晶体振荡电路;(3)兼容的3线SPI串行输入口,带双缓冲,能方便地配合单片机使用;(4)增益误差和总谐波失真很低。ML2035生成的频率较低(0~25kHz),一般应用于一些需产生的频率为工频和音频的场合。如用2片ML2035产生多频互控信号,并与AMS3104(多频接收芯片)或ML2031/2032(音频检波器)配合,制作通信系统中的收发电路等。可编程正弦波发生器芯片ML2035设计巧妙,具有可编程、使用方便、价格低廉等优点,应用范围广泛。很适合需要低成本、高可靠性的低频正弦波信号的场合。
方案三:自行设计的基于CPLD/FPGA芯片的解决方案
DDS技术的实现依赖于高速、高性能的数字器件。可编程逻辑器件以其速度高、规模大、在线可编程,以及有强大EDA软件支持等特性,十分适合实现DDS技术。目前PLD器件(包括CPLD、FPGA)的生产厂商主要有Altera,Xilinx以及Lattoce等。Altera是著名的PLD生产厂商,多年来一直占据着行业领先的地位。Altera的PLD具有高性能、高集成度和高性价比的优点,此外它还提供了功能全面的开发工具和丰富的IP核、宏功能外它还提供了功能全面的开发工具和丰富的IP核、宏功能库等,因此Altera的产品获得了广泛的应用。虽然有的专用DDS芯片的功能也比较多,但控制方式却是固定的,因此不一定是我们所需要的。而利用FPGA则可以根据需要方便地实现各种比较复杂的调频、调相和调幅功能,具有良好的实用性。就合成信号质量而言,专用DDS芯片由于采用特定的集成工艺,内部数字信号抖动很小,可以输出高质量的模拟信号;利用FPGA也能输出较高质量的信号,虽然达不到专用DDS芯片的水平,但信号精度误差在允许范围之内。
基于以上优点我们采用了FPGA芯片来实现我们设计的DDS。
总体设计方框图
直接数字频率合成技术的基本原理
Verilog HDL代码实现与仿真
信号发生器模块
频率控制字和相位累加器
位累加器的位数N=32,Verilog HDL代码如下:
1.module F_word_set(
2. input clk ,
3. input rst_n ,
4. input key1_in ,
5.
6. output reg [25:0] f_word
7. );
8.
9. wire key_flag ;
10. wire key_state ;
11. reg [3:0] cnt ;
12.
13. key_filter fword_key (
14. .clk (clk),
15. .rst_n (rst_n),
16. .key_in (key1_in),
17. .key_flag (key_flag),
18. .key_state (key_state)
19. );
20.
21. always @(posedge clk or negedge rst_n) begin
22. if (!rst_n) begin
23. cnt <= 4'd0;
24. end
25. else if (key_flag) begin
26. if (cnt==4'd10) begin
27. cnt <= 4'd0;
28. end
29. else begin
30. cnt <= cnt + 1'b1;
31. end
32. end
33. end
34.
35. always @(posedge clk or negedge rst_n) begin
36. if (!rst_n) begin
37. f_word <= 0;
38. end
39. else begin
40. case(cnt)
41. 4'd0:f_word = 26'd86; //1Hz
42. 4'd1:f_word = 26'd859; //10Hz
43. 4'd2:f_word = 26'd8590; //100Hz
44. 4'd3:f_word = 26'd42950; //500Hz
45. 4'd4:f_word = 26'd85899; //1kHz
46. 4'd5:f_word = 26'd429497; //5kHz
47. 4'd6:f_word = 26'd858993; //10kHz
48. 4'd7:f_word = 26'd4294967; //50kHz
49. 4'd8:f_word = 26'd8589935; //100kHz
50. 4'd9:f_word = 26'd17179869; //200kHz
51. 4'd10:f_word = 26'd42949673;//500kHz
52. default:;
53. endcase
54. end
55. end
56.endmodule