1.1 信号发生器 信号发生器又称信号源或振荡器,是一种能提供各种频率、波形和输出电平电信号的设备,在测量各种电信系统或电信设备的振幅特性、频率特性、传输特性及其它电参数时,以及测量元器件的特性与参数时,用作测试的信号源或激励源,在生产实践和科技领域中有着广泛的应用。 直接数字式频率合成器(DDS)是将先进的数字处理理论与方法引入频率合成的一项新技术,它把一系列数字量形式的信号通过数/模转换器转换成模拟量形式的信号。 上图是一个典型的DDS工程。DDS一般可分为相位累加器、信号转换器和DAC。 DDS的输入是频率控制字,它用来控制相位累加器每次增加的相位值,相当于一个步进值。 相位累加器:每来一个时钟脉冲,就会在原来相位值的基础上,加上频率控制字的值,得到最新的相位值,将相位值将输出给信号转换器。 信号转换器:一般转换器内部有一片ROM,事先保存了要产生波形的幅度值。根据输入的的相位值,就能输出该相位值所对应的信号幅度值。例如将一个完整周期的正弦波等距离分成128份,并保存到转换器的ROM当中。当相位值为0时,就输出相位为0所应对的幅度值;当相位为100时,就输出相位为100所对应的幅度值。 的具体工作过程是由N位相位累加器、N位加法器和N位累加寄存器组成。每来一个时钟脉冲,N位加法器将频率控制字K与N位累加寄存器输出的累加相位数据相加,并把相加后的结果送至累加寄存器的输入端。累加寄存器一方面将上一时钟周期作用后所产生的新的相位数据反馈到加法器的输入端,使加法器在下一时钟的作用下继续与频率控制字K相加;另一方面将这个值作为取样地址送入幅度/相位转换电路,幅度/相位转换电路根据这个地址输出相应的波形数据。最后经D/A转换器和 LPF将波形数据转换成所需要的模拟波形。 1.2 DA转换 明德扬教学板板载双通道、125MHz 转换速率、8bi的高速DA芯片,满足常用信号发生器、滤波信号输出等需求。实际位置如下所示: 芯片型号是AD9709,AD9709是一款双端口、高速、双通道、8位CMOS DAC,其中集成两个高品质8位TxDAC+®内核、一个基准电压源和数字接口电路,采用48引脚小型LQFP封装。它提供出色的交流和直流性能,同时支持最高125 MSPS的更新速率。 与FPGA相连的信号有:DA_CLKA、DA_CLKB、DAC_DB7~0、DAC_DA7~0,DAC_MODE、DAC_SLEEP、DA_WRA和DA_WRB。1.3 AD9709的时序 AD9709的控制时序如下图 在双通道模式中,通道A和通道B就如两个独立的DA芯片。其中DA_CLKA、DAC_DA7~0、DAC_WR_A用于控制通道A,DA_CLKB、DA_DB7~0、DA_WRB用于控制通道B。 以控制通道A为例,时序图要求,要先将数据输出到DAC_DA7~0,然后经过ts时间后,将DAC_WRA和DA_CLKA变高,此时DAC就将数据锁住,经过一段时间后,就会输出数据所对应的电流,经过电路转换后就变成对应电压了。 时序图中要注意几点(数据手册有详细说明) 1. DA_CLKA并且超前于或者同时与DA_WRA由0变1。 2. 图中tS(DAC_WRA上升沿前数据保持不变的时间)、tH(DAC_WRA上升沿后数据保值不变的时间)、tLPW(DAC_WRA的高电平时间)、tCPW(DAC_CLKA的高电平时间)等参数,查询数据手册,可以得到如下参数表。从表中可以看到tS的时间至少是2ns;tH时间至少是1.5ns;tLPW、tCPW时间至少是3.5ns。图中规定了至少,只要大于要求都是可以的。 通道B的时序要求和通道A是相同的,仅是控制信号不同。 明德扬教学板的AD9709的两个通道,均支持0.48~2.2V的电压输出,这个输出电压与输入数据的关系,可用下面的公式表示: 通道A的输出电压 = -1.72 * (DAC_DA /255) + 2.2 V 通道B的输出电压 = -1.72 * (DAC_DB/255) + 2.2 V 由公式可见,输出电压与DAC_DA/B的值是成线性反比例关系,最低电压为0.48V,最高为2.2V。需要指出的是,由于电路原理图的原因才导致电压在此范围,不同电路实现是不相同的。2 设计目标 本次案例将使用到采样率大于100M的示波器。将示波器和教学板上的通道1连接,如下图所 本案例是要让DA输出不同频率的正弦波。共输出方式如下: 1. 连续输出2个周期为6.25MHz的正弦波,其中每个正弦波输出16个采样点; 2. 连续输出2个周期为3.125MHz的正弦波,其中每个正弦波输出32个采样点; 3. 连续输出2个周期为1.5625MHz的正弦波,其中每个正弦波输出128个采样点; 4. 连续输出2个周期为781250Hz的正弦波,其中每个正弦波输出128个采样点; 5. 连续输出2个周期为390625Hz的正弦波,其中每个正弦波输出128个采样点; 6. 连续输出2个周期为195312.5Hz的正弦波,其中每个正弦波输出128个采样点。 重复以上的1~7的步骤。 正弦波的最高电压是2.2V,最低电压是0.48V 示波器的显示结果如下图上图是整体效果图,每种频率的正弦波连续出现2次,并且正弦波的周期越来越大。下图是捕捉到的,频率为6.25MHz的正弦波,最高电压是2.2V,最低电压是0.48V。下图是捕捉到的,频率为3.125MHz的正弦波,最高电压是2.2V,最低电压是0.48V。下图是捕捉到的,频率为1.5625MHz的正弦波,最高电压是2.2V,最低电压是0.48V。下图是捕捉到的,频率为390625Hz的正弦波,最高电压是2.2V,最低电压是0.48V。下图是捕捉到的,频率为195312.5Hz的正弦波,最高电压是2.2V,最低电压是0.48V。3 设计实现3.1 顶层接口 新建目录:D:mdy_bookdds_da。在该目录中,新建一个名为dds_da.v的文件,并用GVIM打开,开始编写代码。 我们要实现的功能,概括起来就是FPGA产生控制AD9709,让其中的通道A产生正弦波所对应的电压。为了控制AD9709的通道A,就需要控制AD9709的MODE、SLEEP、CLK1、WRT1、DB7~0P1管脚。根据设计目标的要求,整个工程需要以下信号:1. 使用clk连接到晶振,表示50M时钟的输入。2. 使用rst_n连接到按键,表示复位信号。3. 使用dac_mode信号连接到AD9709的MODE管脚,用来控制其工作模式。4. 使用dac_sleep信号连接到AD9709的SLEEP管脚,用来控制其睡眠模式。5. 使用dac_clka信号连接到AD9709的CLK1管脚,用来控制通道A的时钟。6. 使用dac_wra信号连接到AD9709的WRT1管脚,用来控制通道A的写使能。7. 使用8位信号dac_da连接到AD9709的DB7~0P1管脚,用来控制通道A的写数据。 综上所述,我们这个工程需要7个信号,时钟clk,复位rst_n,dac_mode、dac_sleep、dac_clka、dac_wra和dac_da,其中dac_da是8位信号,其他都是1位信号。 下面表格表示了硬件电路图的连接关系。将module的名称定义为dds_da,代码如下: 其中clk、rst_n是1位的输入信号,dac_da是8位的输出信号,dac_mode,dac_clka,dac_wra,dac_sleep是一位输出信号。3.2 信号设计 我们先分析下DAC的输出。以频率为195312.5Hz的正弦波为例,如下图。频率为195312.5Hz,也就是一个正弦波的周期是5120ns。案例要求一个周期要输出128个点,那就是每隔5120/128=40ns要输出一个点。考虑到工程输入的时钟是50MHz,周期是20ns,那就意味着每隔2个时钟就要输出一个点。 综上所述,产生频率频率为195312.5Hz的正弦波,就是每隔2个时钟输出一个电压值,一共输出128个点,组成一个正弦波。我们要连续产生2个正弦波。 现在进一步分析下,这128个点所对应电压值是多少?由于教学板的输出电压在0.48~2.2V之间,最低值是0.48V,最高值是2.2V。 先将一个标准的正弦波向上平稳1个单位,使得范围变成0~2。然后等间隔取128个点(间隔为2*pi/128),获取其幅度值。我们再用8位信号sin_data表示这些幅度值,其表示方式为: sin_data = (sin(2*pi/128) + 1) * (255/2),i为0~127 (公式1) 通道A的输出电压 = -1.72 * (DAC /255) + 2.2 V 公式中可以看到,通道A的输出电压是与DAC_DA成线性反比例关系。为了让通道A的电压正确地展现出正弦波,我们还需要做如下调整。 DAC_DA = 255 - sin_data 上面的DAC_DA就是最终输出给DA芯片的数据值,即dac_da信号。 综上所述,产生频率为195312.5Hz的正弦波,就是每隔2个时钟输出一个电压值dac_da。先按表XX每隔1个选出sin_data,再用(255-sin_data)得到dac_da。一共输出128个点,组成一个正弦波,并且连续输出2个正弦波。 以相同的分析方法,分析频率为6.25MHz的正弦波。 频率为6.25MHz,也就是一个正弦波的周期是160ns。案例要求一个周期要输出8个点,那就是每隔160/8=20ns要输出一个点。考虑到工程输入的时钟是50MHz,周期是20ns,那就意味着每隔1个时钟就要输出一个点。 先将一个标准的正弦波向上平稳1个单位,使得范围变成0~2。然后等间隔取8个点(间隔为2*pi/8),获取其幅度值。我们再用8位信号sin_data表示这些幅度值,其表示方式为:sin_data = (sin(2*pi/8) + 1) * (255/2),i为0~7 = (sin(2*pi*16/128) + 1) * (255/2),i为0~7 (公式2) 对比公式1和公式2,发现同样可以由表XX得到相应的sin_data,只是此时间隔16个点取一个值,一共取8个。 综上所述,产生频率为6.25MHz的正弦波,就是每隔1个时钟输出一个电压值dac_da,按表XX中每隔16个点输出一个值,再用(255-sin_data)得到dac_da。一共输出8个点,组成一个正弦波,并且连续产生2个正弦波 . 按同样的分析方法,分析其他频率。最终总结如下: 1. 连续输出2个周期为6.25MHz的正弦波,其中每个正弦波输出8个采样点。 等价于:每隔1个时钟输出一个电压值dac_da,一共输出8个点,组成一个正弦波,连续产生2个正弦波。dac_da的产生方式:表XXX每隔16个选出得到sin_data,通过(255-sin_data)得到dac_da。 2. 连续输出2个周期为3.125MHz的正弦波,其中每个正弦波输出16个采样点。等价于:每隔1个时钟输出一个电压值dac_da,一共输出16个,组成一个正弦波,连续产生2个正弦波。dac_da的产生方式:表XXX每隔8个选出得到sin_data,通过(255-sin_data)得到dac_da。 3. 连续输出2个周期为1.5625MHz的正弦波,其中每个正弦波输出32个采样点。等价于:每隔1个时钟输出一个电压值dac_da,一共输出32个,组成一个正弦波,连续产生2个正弦波。 dac_da的产生方式:表XXX每隔4个选出得到sin_data,通过(255-sin_data)得到dac_da。 4. 连续输出2个周期为781250Hz的正弦波,其中每个正弦波输出64个采样点。等价于:每隔1个时钟输出一个电压值dac_da,一共输出64个点,组成一个正弦波,连续产生2个正弦波。dac_da的产生方式:表XXX每隔2个选出得到sin_data,通过(255-sin_data)得到dac_da。5. 连续输出2个周期为390625Hz的正弦波,其中每个正弦波输出128个采样点。等价于:每隔1个时钟输出一个电压值dac_da,一共输出128个点,组成一个正弦波,连续产生2个正弦波。dac_da的产生方式:表XXX每隔1个选出得到sin_data,通过(255-sin_data)得到dac_da。 6. 连续输出2个周期为195312.5Hz的正弦波,其中每个正弦波输出128个采样点。等价于:每隔2个时钟输出一个电压值dac_da,一共输出128个点,组成一个正弦波,连续产生2个正弦波。dac_da的产生方式:表XXX每隔1个选出得到sin_data,通过(255-sin_data)得到dac_da。 按照至简设计法中的变量法思想,那么可以概括上面的功能:每隔x个时钟输出一个电压值,一共输出y个点,组成一个正弦波,每个要产生要连续产生2个正弦波。由于一共要产生6种不同频率的正弦波,所以还需要一个计数器来数6个。 总结出上面的内容后,我们开始设计代码。“每隔x个时钟输出一个电压值”,所以这需要一个计数器cnt0,加1条件是“1”,结束条件是数到x个,可以得到cnt0的代码。 “一共输出y个点”,这同样需要一个计数器cnt1。注意的是,由于每个点维持x个时钟,也就是cnt1的加1条件是“数到x个时钟”,即end_cnt0。结束条件是:数到y下。可以得到cnt1的代码。 “每个要产生要连续产生2个正弦波”,这也需要一个计数器cnt2。一个正弦波由y个点组成,所以cnt2的加1条件是“数到y个”,即end_cnt1,结束条件是“数到2个”。可以得到cnt2的代码: 由于一共要产生6种不同频率的正弦波,所以还需要一个计数器cnt3来数6个。这个cnt3的加1条件是“产生完2个正弦波”,即end_cnt2,结束条件是“数到6个”。可以得到cnt3的代码。 我们定义了变量x和y,其中x表示相隔的时钟数,y表示一个正弦波的采样点数。具体的x和y是与正弦波的不同频率相关的,也就是与cnt3相关。根据题意和至简设计法中的变量设计方法,可以得到x和y的代码。 有了计数器之后,其他信号就可以根据计数器设计出来了。 首先看信号dac_da。dac_da都是按(255-sin_data)得到。那么可以写出dac_da的代码 接下来看sin_data信号。sin_data是从表XX中选择出来的值,不同的频率,选择的方式不同。那么很自然是定义一个选择信号addr。我们只要控制好addr,就能方便得到sin_data。 接下来设计信号addr。addr是用来控制选择数据的地址,不同频率的正弦波要求地址控制方式不同。频率为6.25MHz(cnt3=0)是每隔16个选择一个;频率为3.125MHz(cnt3=1)是每隔8个点选择一个;频率为1.5625MHz(cnt3=2)是每隔4个点选择一个;频率为781250Hz(cnt3=3)是每隔2个选择一个;频率为390625Hz(cnt3=4)是每隔1个点选择一个;频率为195312.5Hz(cnt3=5)是每隔1个选择一个,一共发送128个。 我们用cnt1表示发送的第几个数。 cnt3==0 时,addr = cnt1*16; cnt3==1时,addr = cnt1*8; cnt3==2时,addr = cnt1*4; cnt3==3时,addr = cnt1*2; cnt3==4时,addr = cnt1*1; cnt3==5时,addr = cnt1*1。 因此,可以写得addr的代码 接下来是信号dac_sleep,AD是一直工作的,所以要让dac_sleep一直为0。 dac_clka为了满足tS的时间要求,可以让dac_clka = ~clk。 dac_wra可以与dac_clka相同。 dac_mode是控制AD9709的模式,当为高电平时,表示双通道模式,此时通过DA、DB两组信号分别独立控制两个通道。在能实现功能的前提下,越简单越好,就使用双通道模式,因此令dac_mode一直为1。至此,主体程序已经完成。接下来是将module补充完整。3.3 信号定义 接下来定义信号类型。 cnt0是用always产生的信号,因此类型为reg。cnt0计数的最大值为15,需要用5根线表示,即位宽是5位。add_cnt0和end_cnt0都是用assign方式设计的,因此类型为wire。并且其值是0或者1,1个线表示即可。因此代码如下: cnt1是用always产生的信号,因此类型为reg。cnt1计数的最大值为127,需要用8根线表示,即位宽是8位。add_cnt1和end_cnt1都是用assign方式设计的,因此类型为wire。并且其值是0或者1,1根线表示即可。因此代码如下: cnt2是用always产生的信号,因此类型为reg。cnt2计数的最大值为7,需要用3根线表示,即位宽是8位。add_cnt2和end_cnt2都是用assign方式设计的,因此类型为wire。并且其值是0或者1,1根线表示即可。因此代码如下: cnt3是用always产生的信号,因此类型为reg。cnt3计数的最大值为5,需要用3根线表示,即位宽是3位。add_cnt3和end_cnt3都是用assign方式设计的,因此类型为wire。并且其值是0或者1,1根线表示即可。因此代码如下: 变量x,y是用always方式设计的,因此类型为reg,x最大值为2,要有2位来表示,y最大值为128,要有8根线表示,即位宽为8,因此代码如下, addr是用always设计的,因此类型为reg。其值最大为127,一共有7根线,位宽为7,故而代码如下 sin_data是用always设计的,因此类型为reg。其最大值为255,要有8根线表示,位宽为8,故而代码如下: dac_da是用always设计的,因此类型为reg。其位宽为8;dac_sleep是用assign设计的,因此类型为wire,位宽为1;dac_wra是用assign设计的,因此类型为wire,位宽为1;dac_clka是用assign设计的,因此类型为wire,位宽为1;dac_mode是用assign设计的,因此类型为wire,位宽为1。故而代码如下: 在代码的最后一行写下endmodule.4 综合工程和上板4.1 新建工程 1.)打开quartus,点击File 在File菜单中选择New ProjectWizard.... 。 2.弹出Introduction界面选择Next。 (3)设置工程目录,工程名,顶层模块名 工程目录设置为:D:mdy_bookdds_da 工程名:dds_da 顶层模块名:dds_da 填写完毕后,点击next之后进入下一界面。 工程类型界面,Project Type选择Empty project,选择空白工程。点Next进入下一个界面。 (3.)在文件添加界面,点击右上角的,在弹出来的窗口中,双击选择D:mdy_bookdds_da目录下的dds_da.v文件。 点击右上角的add按键,将文件添加进工程。 在主窗口中会显示将dds_da.v加入了工程。点击Next,进入下一个界面。4.2 综合 在菜单栏中,选中Processing,然后选择Start Compilation,开始对整个工程进行编译和综合。 出现上面的界面,就说明编译综合成功。4.3 配置管脚 在菜单栏中,选中Assignments,然后选择Pin Planner,就会弹出配置管脚的窗口。 在配置窗口中的location一列,可以填写每个管脚所对应的FPGA管脚号。 按上面配置好每个信号的管脚,其最终效果如下图。4.4 再次综合 在菜单栏中,选中Processing,然后选择Start Compilation,开始对整个工程进行编译和综合。 出现上面的界面,就说明编译综合成功.4.5 连接开发板 连接示意如上图所示。将电源接上开发板;USBBLASTER一端连接到JTAG插口,另一端连到PC的USB接口;将开发板上的P7接口与示波器相连。最后再将电源打开。4.6 上板 在quartus的Task窗口中,右键Program Device 选择Open 进入烧录界面。在上面的界面中,默认会选中文件output/dds_da.sof,如果没有生成请看XXXX。点击statr,在progress这一条显示100%即表示成功,此时可以看FPGA输出效果了。<p>如果你觉得有用的话,就请你回个贴或者赞,证明我的付出没有白费,大家都不容易,如果想要一些关于FPGA的资料,可以加我QQ:328908175,让们共同学习。号发生器和DA转换 FPGA案例教程

1.1 信号发生器

信号发生器又称信号源或振荡器,是一种能提供各种频率、波形和输出电平电信号的设备,在测量各种电信系统或电信设备的振幅特性、频率特性、传输特性及其它电参数时,以及测量元器件的特性与参数时,用作测试的信号源或激励源,在生产实践和科技领域中有着广泛的应用。

直接数字式频率合成器(DDS)是将先进的数字处理理论与方法引入频率合成的一项新技术,它把一系列数字量形式的信号通过数/模转换器转换成模拟量形式的信号。

上图是一个典型的DDS工程。DDS一般可分为相位累加器、信号转换器和DAC。

DDS的输入是频率控制字,它用来控制相位累加器每次增加的相位值,相当于一个步进值。

相位累加器:每来一个时钟脉冲,就会在原来相位值的基础上,加上频率控制字的值,得到最新的相位值,将相位值将输出给信号转换器。

信号转换器:一般转换器内部有一片ROM,事先保存了要产生波形的幅度值。根据输入的的相位值,就能输出该相位值所对应的信号幅度值。例如将一个完整周期的正弦波等距离分成128份,并保存到转换器的ROM当中。当相位值为0时,就输出相位为0所应对的幅度值;当相位为100时,就输出相位为100所对应的幅度值。

的具体工作过程是由N位相位累加器、N位加法器和N位累加寄存器组成。每来一个时钟脉冲,N位加法器将频率控制字K与N位累加寄存器输出的累加相位数据相加,并把相加后的结果送至累加寄存器的输入端。累加寄存器一方面将上一时钟周期作用后所产生的新的相位数据反馈到加法器的输入端,使加法器在下一时钟的作用下继续与频率控制字K相加;另一方面将这个值作为取样地址送入幅度/相位转换电路,幅度/相位转换电路根据这个地址输出相应的波形数据。最后经D/A转换器和 LPF将波形数据转换成所需要的模拟波形。

1.2 DA转换

明德扬教学板板载双通道、125MHz 转换速率、8bi的高速DA芯片,满足常用信号发生器、滤波信号输出等需求。实际位置如下所示:

芯片型号是AD9709,AD9709是一款双端口、高速、双通道、8位CMOS DAC,其中集成两个高品质8位TxDAC+®内核、一个基准电压源和数字接口电路,采用48引脚小型LQFP封装。它提供出色的交流和直流性能,同时支持最高125 MSPS的更新速率。

与FPGA相连的信号有:DA_CLKA、DA_CLKB、DAC_DB7~0、DAC_DA7~0,DAC_MODE、DAC_SLEEP、DA_WRA和DA_WRB。

1.3 AD9709的时序

AD9709的控制时序如下图

在双通道模式中,通道A和通道B就如两个独立的DA芯片。其中DA_CLKA、DAC_DA7~0、DAC_WR_A用于控制通道A,DA_CLKB、DA_DB7~0、DA_WRB用于控制通道B。

以控制通道A为例,时序图要求,要先将数据输出到DAC_DA7~0,然后经过ts时间后,将DAC_WRA和DA_CLKA变高,此时DAC就将数据锁住,经过一段时间后,就会输出数据所对应的电流,经过电路转换后就变成对应电压了。

时序图中要注意几点(数据手册有详细说明)

1. DA_CLKA并且超前于或者同时与DA_WRA由0变1。

2. 图中tS(DAC_WRA上升沿前数据保持不变的时间)、tH(DAC_WRA上升沿后数据保值不变的时间)、tLPW(DAC_WRA的高电平时间)、tCPW(DAC_CLKA的高电平时间)等参数,查询数据手册,可以得到如下参数表。从表中可以看到tS的时间至少是2ns;tH时间至少是1.5ns;tLPW、tCPW时间至少是3.5ns。图中规定了至少,只要大于要求都是可以的。

通道B的时序要求和通道A是相同的,仅是控制信号不同。

明德扬教学板的AD9709的两个通道,均支持0.48~2.2V的电压输出,这个输出电压与输入数据的关系,可用下面的公式表示:

通道A的输出电压 = -1.72 * (DAC_DA /255) + 2.2 V

通道B的输出电压 = -1.72 * (DAC_DB/255) + 2.2 V

由公式可见,输出电压与DAC_DA/B的值是成线性反比例关系,最低电压为0.48V,最高为2.2V。需要指出的是,由于电路原理图的原因才导致电压在此范围,不同电路实现是不相同的。

2 设计目标

本次案例将使用到采样率大于100M的示波器。将示波器和教学板上的通道1连接,如下图所

本案例是要让DA输出不同频率的正弦波。共输出方式如下:

1. 连续输出2个周期为6.25MHz的正弦波,其中每个正弦波输出16个采样点;

2. 连续输出2个周期为3.125MHz的正弦波,其中每个正弦波输出32个采样点;

3. 连续输出2个周期为1.5625MHz的正弦波,其中每个正弦波输出128个采样点;

4. 连续输出2个周期为781250Hz的正弦波,其中每个正弦波输出128个采样点;

5. 连续输出2个周期为390625Hz的正弦波,其中每个正弦波输出128个采样点;

6. 连续输出2个周期为195312.5Hz的正弦波,其中每个正弦波输出128个采样点。

重复以上的1~7的步骤。

正弦波的最高电压是2.2V,最低电压是0.48V

示波器的显示结果如下图

上图是整体效果图,每种频率的正弦波连续出现2次,并且正弦波的周期越来越大。

下图是捕捉到的,频率为6.25MHz的正弦波,最高电压是2.2V,最低电压是0.48V。

下图是捕捉到的,频率为3.125MHz的正弦波,最高电压是2.2V,最低电压是0.48V。

下图是捕捉到的,频率为1.5625MHz的正弦波,最高电压是2.2V,最低电压是0.48V。

下图是捕捉到的,频率为390625Hz的正弦波,最高电压是2.2V,最低电压是0.48V。

下图是捕捉到的,频率为195312.5Hz的正弦波,最高电压是2.2V,最低电压是0.48V。

3 设计实现

3.1 顶层接口

新建目录:D:mdy_bookdds_da。在该目录中,新建一个名为dds_da.v的文件,并用GVIM打开,开始编写代码。

我们要实现的功能,概括起来就是FPGA产生控制AD9709,让其中的通道A产生正弦波所对应的电压。为了控制AD9709的通道A,就需要控制AD9709的MODE、SLEEP、CLK1、WRT1、DB7~0P1管脚。根据设计目标的要求,整个工程需要以下信号:

1. 使用clk连接到晶振,表示50M时钟的输入。

2. 使用rst_n连接到按键,表示复位信号。

3. 使用dac_mode信号连接到AD9709的MODE管脚,用来控制其工作模式。

4. 使用dac_sleep信号连接到AD9709的SLEEP管脚,用来控制其睡眠模式。

5. 使用dac_clka信号连接到AD9709的CLK1管脚,用来控制通道A的时钟。

6. 使用dac_wra信号连接到AD9709的WRT1管脚,用来控制通道A的写使能。

7. 使用8位信号dac_da连接到AD9709的DB7~0P1管脚,用来控制通道A的写数据。

综上所述,我们这个工程需要7个信号,时钟clk,复位rst_n,dac_mode、dac_sleep、dac_clka、dac_wra和dac_da,其中dac_da是8位信号,其他都是1位信号。 下面表格表示了硬件电路图的连接关系。

将module的名称定义为dds_da,代码如下:

其中clk、rst_n是1位的输入信号,dac_da是8位的输出信号,dac_mode,dac_clka,dac_wra,dac_sleep是一位输出信号。

3.2 信号设计

我们先分析下DAC的输出。以频率为195312.5Hz的正弦波为例,如下图。频率为195312.5Hz,也就是一个正弦波的周期是5120ns。案例要求一个周期要输出128个点,那就是每隔5120/128=40ns要输出一个点。考虑到工程输入的时钟是50MHz,周期是20ns,那就意味着每隔2个时钟就要输出一个点。

综上所述,产生频率频率为195312.5Hz的正弦波,就是每隔2个时钟输出一个电压值,一共输出128个点,组成一个正弦波。我们要连续产生2个正弦波。

现在进一步分析下,这128个点所对应电压值是多少?由于教学板的输出电压在0.48~2.2V之间,最低值是0.48V,最高值是2.2V。

先将一个标准的正弦波向上平稳1个单位,使得范围变成0~2。然后等间隔取128个点(间隔为2*pi/128),获取其幅度值。我们再用8位信号sin_data表示这些幅度值,其表示方式为:

sin_data = (sin(2*pi/128) + 1) * (255/2),i为0~127 (公式1)

通道A的输出电压 = -1.72 * (DAC /255) + 2.2 V

公式中可以看到,通道A的输出电压是与DAC_DA成线性反比例关系。为了让通道A的电压正确地展现出正弦波,我们还需要做如下调整。

DAC_DA = 255 - sin_data

上面的DAC_DA就是最终输出给DA芯片的数据值,即dac_da信号。

综上所述,产生频率为195312.5Hz的正弦波,就是每隔2个时钟输出一个电压值dac_da。先按表XX每隔1个选出sin_data,再用(255-sin_data)得到dac_da。一共输出128个点,组成一个正弦波,并且连续输出2个正弦波。

以相同的分析方法,分析频率为6.25MHz的正弦波。

频率为6.25MHz,也就是一个正弦波的周期是160ns。案例要求一个周期要输出8个点,那就是每隔160/8=20ns要输出一个点。考虑到工程输入的时钟是50MHz,周期是20ns,那就意味着每隔1个时钟就要输出一个点。

先将一个标准的正弦波向上平稳1个单位,使得范围变成0~2。然后等间隔取8个点(间隔为2*pi/8),获取其幅度值。我们再用8位信号sin_data表示这些幅度值,其表示方式为:

sin_data = (sin(2*pi/8) + 1) * (255/2),i为0~7

= (sin(2*pi*16/128) + 1) * (255/2),i为0~7 (公式2)

对比公式1和公式2,发现同样可以由表XX得到相应的sin_data,只是此时间隔16个点取一个值,一共取8个。

综上所述,产生频率为6.25MHz的正弦波,就是每隔1个时钟输出一个电压值dac_da,按表XX中每隔16个点输出一个值,再用(255-sin_data)得到dac_da。一共输出8个点,组成一个正弦波,并且连续产生2个正弦波 .

按同样的分析方法,分析其他频率。最终总结如下:

1. 连续输出2个周期为6.25MHz的正弦波,其中每个正弦波输出8个采样点。

等价于:每隔1个时钟输出一个电压值dac_da,一共输出8个点,组成一个正弦波,连续产生2个正弦波。

dac_da的产生方式:表XXX每隔16个选出得到sin_data,通过(255-sin_data)得到dac_da。

2. 连续输出2个周期为3.125MHz的正弦波,其中每个正弦波输出16个采样点。

等价于:每隔1个时钟输出一个电压值dac_da,一共输出16个,组成一个正弦波,连续产生2个正弦波。

dac_da的产生方式:表XXX每隔8个选出得到sin_data,通过(255-sin_data)得到dac_da。

3. 连续输出2个周期为1.5625MHz的正弦波,其中每个正弦波输出32个采样点。

等价于:每隔1个时钟输出一个电压值dac_da,一共输出32个,组成一个正弦波,连续产生2个正弦波。

dac_da的产生方式:表XXX每隔4个选出得到sin_data,通过(255-sin_data)得到dac_da。

4. 连续输出2个周期为781250Hz的正弦波,其中每个正弦波输出64个采样点。

等价于:每隔1个时钟输出一个电压值dac_da,一共输出64个点,组成一个正弦波,连续产生2个正弦波。

dac_da的产生方式:表XXX每隔2个选出得到sin_data,通过(255-sin_data)得到dac_da。

5. 连续输出2个周期为390625Hz的正弦波,其中每个正弦波输出128个采样点。

等价于:每隔1个时钟输出一个电压值dac_da,一共输出128个点,组成一个正弦波,连续产生2个正弦波。

dac_da的产生方式:表XXX每隔1个选出得到sin_data,通过(255-sin_data)得到dac_da。

6. 连续输出2个周期为195312.5Hz的正弦波,其中每个正弦波输出128个采样点。

等价于:每隔2个时钟输出一个电压值dac_da,一共输出128个点,组成一个正弦波,连续产生2个正弦波。

dac_da的产生方式:表XXX每隔1个选出得到sin_data,通过(255-sin_data)得到dac_da。

按照至简设计法中的变量法思想,那么可以概括上面的功能:每隔x个时钟输出一个电压值,一共输出y个点,组成一个正弦波,每个要产生要连续产生2个正弦波。由于一共要产生6种不同频率的正弦波,所以还需要一个计数器来数6个。

总结出上面的内容后,我们开始设计代码。

“每隔x个时钟输出一个电压值”,所以这需要一个计数器cnt0,加1条件是“1”,结束条件是数到x个,可以得到cnt0的代码。

“一共输出y个点”,这同样需要一个计数器cnt1。注意的是,由于每个点维持x个时钟,也就是cnt1的加1条件是“数到x个时钟”,即end_cnt0。结束条件是:数到y下。可以得到cnt1的代码。

“每个要产生要连续产生2个正弦波”,这也需要一个计数器cnt2。一个正弦波由y个点组成,所以cnt2的加1条件是“数到y个”,即end_cnt1,结束条件是“数到2个”。可以得到cnt2的代码:

由于一共要产生6种不同频率的正弦波,所以还需要一个计数器cnt3来数6个。这个cnt3的加1条件是“产生完2个正弦波”,即end_cnt2,结束条件是“数到6个”。可以得到cnt3的代码。

我们定义了变量x和y,其中x表示相隔的时钟数,y表示一个正弦波的采样点数。具体的x和y是与正弦波的不同频率相关的,也就是与cnt3相关。根据题意和至简设计法中的变量设计方法,可以得到x和y的代码。

有了计数器之后,其他信号就可以根据计数器设计出来了。

首先看信号dac_da。dac_da都是按(255-sin_data)得到。那么可以写出dac_da的代码

接下来看sin_data信号。sin_data是从表XX中选择出来的值,不同的频率,选择的方式不同。那么很自然是定义一个选择信号addr。我们只要控制好addr,就能方便得到sin_data。

接下来设计信号addr。addr是用来控制选择数据的地址,不同频率的正弦波要求地址控制方式不同。频率为6.25MHz(cnt3=0)是每隔16个选择一个;频率为3.125MHz(cnt3=1)是每隔8个点选择一个;频率为1.5625MHz(cnt3=2)是每隔4个点选择一个;频率为781250Hz(cnt3=3)是每隔2个选择一个;频率为390625Hz(cnt3=4)是每隔1个点选择一个;频率为195312.5Hz(cnt3=5)是每隔1个选择一个,一共发送128个。

我们用cnt1表示发送的第几个数。

cnt3==0 时,addr = cnt1*16;

cnt3==1时,addr = cnt1*8;

cnt3==2时,addr = cnt1*4;

cnt3==3时,addr = cnt1*2;

cnt3==4时,addr = cnt1*1;

cnt3==5时,addr = cnt1*1。

因此,可以写得addr的代码

接下来是信号dac_sleep,AD是一直工作的,所以要让dac_sleep一直为0。

dac_clka为了满足tS的时间要求,可以让dac_clka = ~clk。

dac_wra可以与dac_clka相同。

dac_mode是控制AD9709的模式,当为高电平时,表示双通道模式,此时通过DA、DB两组信号分别独立控制两个通道。在能实现功能的前提下,越简单越好,就使用双通道模式,因此令dac_mode一直为1。

至此,主体程序已经完成。接下来是将module补充完整。

3.3 信号定义

接下来定义信号类型。

cnt0是用always产生的信号,因此类型为reg。cnt0计数的最大值为15,需要用5根线表示,即位宽是5位。add_cnt0和end_cnt0都是用assign方式设计的,因此类型为wire。并且其值是0或者1,1个线表示即可。因此代码如下:

cnt1是用always产生的信号,因此类型为reg。cnt1计数的最大值为127,需要用8根线表示,即位宽是8位。add_cnt1和end_cnt1都是用assign方式设计的,因此类型为wire。并且其值是0或者1,1根线表示即可。因此代码如下:

cnt2是用always产生的信号,因此类型为reg。cnt2计数的最大值为7,需要用3根线表示,即位宽是8位。add_cnt2和end_cnt2都是用assign方式设计的,因此类型为wire。并且其值是0或者1,1根线表示即可。因此代码如下:

cnt3是用always产生的信号,因此类型为reg。cnt3计数的最大值为5,需要用3根线表示,即位宽是3位。add_cnt3和end_cnt3都是用assign方式设计的,因此类型为wire。并且其值是0或者1,1根线表示即可。因此代码如下:

变量x,y是用always方式设计的,因此类型为reg,x最大值为2,要有2位来表示,y最大值为128,要有8根线表示,即位宽为8,因此代码如下,

addr是用always设计的,因此类型为reg。其值最大为127,一共有7根线,位宽为7,故而代码如下

sin_data是用always设计的,因此类型为reg。其最大值为255,要有8根线表示,位宽为8,故而代码如下:

dac_da是用always设计的,因此类型为reg。其位宽为8;dac_sleep是用assign设计的,因此类型为wire,位宽为1;dac_wra是用assign设计的,因此类型为wire,位宽为1;dac_clka是用assign设计的,因此类型为wire,位宽为1;dac_mode是用assign设计的,因此类型为wire,位宽为1。故而代码如下:

在代码的最后一行写下endmodule.

4 综合工程和上板

4.1 新建工程

1.)打开quartus,点击File 在File菜单中选择New ProjectWizard.... 。

2.弹出Introduction界面选择Next。

(3)设置工程目录,工程名,顶层模块名

工程目录设置为:D:mdy_bookdds_da

工程名:dds_da

顶层模块名:dds_da

填写完毕后,点击next之后进入下一界面。

工程类型界面,Project Type选择Empty project,选择空白工程。点Next进入下一个界面。

(3.)在文件添加界面,点击右上角的,在弹出来的窗口中,双击选择D:mdy_bookdds_da目录下的dds_da.v文件。

点击右上角的add按键,将文件添加进工程。

在主窗口中会显示将dds_da.v加入了工程。点击Next,进入下一个界面。

4.2 综合

在菜单栏中,选中Processing,然后选择Start Compilation,开始对整个工程进行编译和综合。

出现上面的界面,就说明编译综合成功。

4.3 配置管脚

在菜单栏中,选中Assignments,然后选择Pin Planner,就会弹出配置管脚的窗口。

在配置窗口中的location一列,可以填写每个管脚所对应的FPGA管脚号。

按上面配置好每个信号的管脚,其最终效果如下图。

4.4 再次综合

在菜单栏中,选中Processing,然后选择Start Compilation,开始对整个工程进行编译和综合。

出现上面的界面,就说明编译综合成功.

4.5 连接开发板

连接示意如上图所示。将电源接上开发板;USBBLASTER一端连接到JTAG插口,另一端连到PC的USB接口;将开发板上的P7接口与示波器相连。最后再将电源打开。

4.6 上板

在quartus的Task窗口中,右键Program Device 选择Open 进入烧录界面。

在上面的界面中,默认会选中文件output/dds_da.sof,如果没有生成请看XXXX。

点击statr,在progress这一条显示100%即表示成功,此时可以看FPGA输出效果了。

<p>

如果你觉得有用的话,就请你回个贴或者赞,证明我的付出没有白费,大家都不容易,如果想要一些关于FPGA的资料,可以加我QQ:328908175,让们共同学习。

dac生成信号频率取决于_信号发生器和DA转换 FPGA案例教程相关推荐

  1. dac生成信号频率取决于_基于DAC芯片的信号源生成系统的制作方法

    本发明涉及干扰机技术领域,特别是基于DAC芯片的信号源生成系统. 背景技术: 随着现在通信技术的高速发展,对于装备的小型化.集成化.成本控制要求越来越高,如何设计出低成本.高集成度.小型化的装备是现阶 ...

  2. dac生成信号频率取决于_DAC和AOC,谁将是数据通信领域最终赢家?

    如今竞争激烈的通信行业,大家都期望获得竞争优势,无论是在性能方面.效率方面还是成本方面.虽然许多数据中心的整改侧重于网络适配器和交换机配置,但有一种极其基础.却同样有效的方法可以改进部署的数据中心,那 ...

  3. 使用matlab生成高斯滤波模板_高斯滤波matlab及FPGA实现

    高斯滤波是一种线性平滑滤波,适用于消除高斯噪声,广泛应用于图像处理的减噪过程.通俗的讲,高斯滤波就是对整幅图像进行加权平均的过程,每一个像素点的值,都由其本身和邻域内的其他像素值经过加权平均后得到. ...

  4. 【ArcGIS风暴】ArcGIS自动生成标识码(BSM)的两种方法案例教程

    1. 标识码编制规则 按照每个图层要素的标识码应具有唯一代码的基本要求,根据<GB/T 7027-2002 信息分类和编码的基本原则与方法>规定的信息分类原则和方法,要素标识码采用二层 2 ...

  5. python3程序设计基础答案刘德山_北京大学出版社《Java程序设计案例教程》答案【python程序设计案例教程微课版答案】...

    北京大学出版社<Java程序设计案例教程>答案 哎,我也在找不过时北京交通大学出版的 求大学python3程序设计基础答案 刘德山主编 网上找不到 希望大家帮帮忙 答案我也没有,如果你是计 ...

  6. hm55主板支持最大内存_内存频率取决于CPU还是主板?内存频率看主板支持还是看CPU支持?...

    内存频率取决于CPU还是主板还是内存自身?高频内存在日常使用确实感受不到性能差异,不过在部分游戏中,确实对游戏帧数有一定的提升.对于准备新装机用户,不少用户发现CPU和主板都有内存支持频率参数,可能有 ...

  7. 怎么更改wifi频段_【wifi信号频率】wifi频率怎么设置 wifi2.4g和5g哪个更好

    wifi频率怎么设置 1.打开浏览器,输入192.168.1.1,进入路由设置界面. 2.单击左侧的设置向导,然后单击下一步. 3.一般情况,选择让路由器自动选择上网方式. 4.输入你从运营商那里获得 ...

  8. verilog设计简易正弦波信号发生器_信号发生器入门手册-白皮书 (上)

    一提到电子测量,可能进入人们脑海的第一个东西是采集仪器,其通常是示波器或逻辑分析仪.但是,只有在能够采集某类信号时,这些工具才能进行测量.在许多情况下,这些信号是没有的,除非在外部提供信号. 例如,应 ...

  9. matlab 采样点数,信号频率、采样频率、频率分辨率以及FFT信号补零

    采样点数,信号频率.采样频率.采样点数的区分 包含matlab代码讲解示例 清晰明了 采样点数,信号频率.采样频率.采样点数 首先,频率指的是物质在单位时间内完成周期性变化的次数叫做频率,常用f表示. ...

最新文章

  1. python测试开发自学教程-2019第一期《python测试开发》课程,10月13号开学
  2. MyBatis 插件原理与自定义插件
  3. android chrome iframe设置src属性无法启动app
  4. 程序人生:摆脱情绪低潮的10种方法
  5. 在Windows XP中对系统文件(页面文件和注册表)进行碎片整理
  6. VC创建DLL动态链接库及其调用
  7. 数据库高可用实战案例-------架构优化之清爽一夏
  8. 发票查验系统帮你轻松解决发票管理各种问题
  9. 贱人工具箱使用技巧2——多重复制命令
  10. hdu 1598 find the most comfortable road 枚举+最小成生树 kruskal 解题报告
  11. STM32 LL库延时函数 LL_mDelay解析
  12. 串的子串(模式串)匹配算法
  13. ubuntu相关软件安装
  14. 笔记本电脑开启热点后电脑无法上网问题——亲测可行【06-17】
  15. c语言实现定积分运算
  16. Android背景和音乐
  17. 人工智能专家系统c语言,人工智能实验4三-专家系统.doc
  18. 科大讯飞语音离线命令识别
  19. seo是什么意思?干什么的啊?
  20. Windows系统路径中的C:/WINDOWS/Explorer.exe是什么?

热门文章

  1. 在DataGrid中选择,确认,删除多行复选框列表
  2. NBA过上中国年 用五福福卡为球迷送祝福
  3. 英特尔世界公开赛总决赛落幕 三只优胜战队分享30万美元奖金
  4. 诺基亚贝尔完成5G毫米波NR-DC和200MHz载波带宽测试
  5. 新浪微博澄清“花钱撤热搜”、“花钱压热搜”等不实传言
  6. 字节跳动和腾讯不正当竞争案将于深圳开庭 抖音:我们也是看新闻才知道本月24日要开庭...
  7. 万物新生招股书:每股发行价格区间为13-15美元
  8. 特斯拉回应提车考试:仅作为丰富交付体验的“选修”活动
  9. 黄光裕回应与京东、拼多多竞争:谁也灭不了谁 不排除合作的可能性
  10. 苹果正在训练Siri 未来或将更好理解口吃用户