本次介绍ADI公司的数字频率合成(DDS)芯片——AD9850以及如何使用FPGA控制其输出正弦波。
本文分三个部分讲解:一是AD9850芯片介绍,包括基本引脚功能、驱动时序以及相关注意事项;二是基于FPGA的AD9850的驱动的建模;三是仿真和调试结果。
PART1:AD9850认知
1、模式选择:并行和串行两种。
2、通信协议:实际上属于SPI协议的变种。串行时很好理解,并行时可以理解为在时钟的上升沿将整个字节的数据并行采集,这里将这种spi模式定义为并行spi。
3、寄存器配置:内部包含两个两个寄存器,相位控制寄存器(8bit)和频率控制寄存器(32bit,可分成4个8bit寄存器),总40bit,分为5个控制字写入,从高位到低位每8bit为一个控制字寄存器,分别为W0、W1、W2、W3、W4。相位寄存器(命为W0),其中W0_bit2-bit0=000(无论串并模式,手册中其他组合定义为厂家模式,慎用),实际上,配置W0=8’h00(0°相位)即可,高5位为初相位配置数据位。
W1-W4共4个控制字组成32bit的频率寄存器。故fo=reg_dds*f_osc/2^32.(单位为MHz)
3、并行模式,先后写入的控制字顺序为W0-W1----W4。
4、极限输出:
理论上,fo_max=1/2*f_osc,取f_osc=125MHz时,fo_max=62.5MHz,实际上输出40MHz(芯片手册说的输出f不超过0.33*fosc,125MHz时约41.25MHz)是没有问题的。频率越高,输出的信号幅值越低(正常的,这是因为输出呈sinc(Sa函数)规律)。
4、芯片正常工作时,5V、125MHz晶振,Pidss=380mW(典型值),实际上这个时候芯片是比较烫的,属于正常现象,也符合电流型输出特点(并不像芯片吹的低功耗)。
5、方波输出(可以调节占空比)功能,正常时需要调节模块的滑动变阻器(修改比较器的门限值),虽然手册上声称内部含有高速比较器,但实际上最高输出方波的频率理论上不超过1MHz(内部比较器的输出带宽有限,导致方波的告辞谐波丢失严重,进而出现失真),如果想获得高频的方波,可以采用TLV3502代替内部比较器,这块片子输出50MHz方波是没有问题的。
NOTE:方波测量时最好不开启带宽限制(特别是有些示波器具有数字滤波功能);dds的测量最好使用频谱分析仪等仪器测试(有条件的选手)。
6、通信协议的时序要求(见下图)
【1】主电路复位
【2】数据写入(并行)
【3】总体时序参数
以上是AD9850的相关介绍,下面介绍FPGA建模。
PART2:fpga建模
Step1:spi主体建模
由前所述,特提出并行spi,值得是在时钟边沿写入一个字节数据,谓之并行,很明显这种形式的spi具有较高的传输效率和速率。这样,结合之前写过的spi时序,进行简单的修改便可完成主体通信时序的建模。具体修改如下:定义并行接口(只需要将sda设置成并行的端口,位数为8)。
//AD9850并行数据
always @ (posedge clk, negedge rst_n) begin
if (!rst_n)
sda <= {D0_WID{1'b0}};
else if ((state == WRITE || state == START) && sclk_cnt == 4'd0)
sda <= sda_buf;
end
always @ (*) begin
case (bit_cnt)
5'd0: sda_buf = sda_buf1[7 : 0];
5'd4: sda_buf = sda_buf1[15 : 8];
5'd3: sda_buf = sda_buf1[23 : 16];
5'd2: sda_buf = sda_buf1[31 : 24];
5'd1: sda_buf = sda_buf1[39 : 32];
default: sda_buf = {D0_WID{1'b0}};
endcase
end
NOTE:本次设计中的40bit的寄存器数据,其中第一个自己数据W0放在了sda_buf1的低8位,实际上,最好将其放在最高位,那么,上述代码的cade语句中,bit_cnt==5'd0时,就应该赋值39:32,其余的按照规律输出即可。
此外,还需要加上一个复位输出功能,如上,模块含有整体复位功能,实际上可以使用fpga主板的复位引脚给之复位(注意,模块复位是高电平,fpga是低电平)。这里,简单的采用一个计数器完成该部分功能,具体不做展示。
Step2:数据供给模块建模
简单说,就是给AD9850的40bit的寄存器的值,即遗传01代码,作为验证程序,这里从简即可。具体的思路是,通过fpga主板上的按键外设作为系统输入,判断按键的输入键值,进行相应译码,得到对应的寄存器目标配置值。本次设计设定了5中输出频率,对应关系如下:
表1 频率值对应16进制数值
频率输出(MHz) |
1KHz |
1 |
10 |
20 |
40 |
50 |
16进制值 |
00008637 |
020c49ba |
147ae147 |
28f5c28f |
51eb851e |
66666666 |
由于采用了按键,最好加上按键消抖,此模块之前已经做了介绍(代码资料可在我的主页下载,博客中有相关模块的说明)。
Step3:仿真和调试结果
简单仿真,得到的仿真结果基本符合时序要求。以下直接给出调试结果:
图1:1KHz输出
图2:1MHz输出
图3:10MHz输出
图4:20MHz输出
图5:40MHz输出
图6:50MHz输出
通过简单的按键输入,即可使得输出在以上几个频点值之间进行切换输出,且在示波器观察到的波形效果较好,知本次建模完成了相应功能。
最后,习惯给出整体的RTL功能视图:
代码的下载连接如下:https://download.csdn.net/download/huigeyu/11306373