【正点原子FPGA连载】 第二十二章 高速AD/DA实验 摘自【正点原子】DFZU2EG/4EV MPSoC 之FPGA开发指南V1.0

您所在的位置:网站首页 高速脉冲采集模块原理 【正点原子FPGA连载】 第二十二章 高速AD/DA实验 摘自【正点原子】DFZU2EG/4EV MPSoC 之FPGA开发指南V1.0

【正点原子FPGA连载】 第二十二章 高速AD/DA实验 摘自【正点原子】DFZU2EG/4EV MPSoC 之FPGA开发指南V1.0

2022-12-15 08:50| 来源: 网络整理| 查看: 265

1)实验平台:正点原子MPSoC开发板 2)平台购买地址:https://detail.tmall.com/item.htm?id=692450874670 3)全套实验源码+手册+视频下载地址: http://www.openedv.com/thread-340252-1-1.html

第二十二章 高速AD/DA实验

ADC/DAC(Analog to Digital Converter/ Digital to Analog Converter,即模数转换器/数模转换器)是大多数系统中必不可少的组成部件,用于将连续的模拟信号转换成离散的数字信号,或者将离散的数字信号转换成连续的模拟信号,它们是连接模电电路和数字电路必不可少的桥梁。在很多场合下,ADC/DAC的转换速度甚至直接决定了整个系统的运行速度。本章我们将使用高速DA芯片实现数模转换,产生正弦波模拟电压信号,并通过高速AD芯片将模拟信号转换成数字信号。 本章包括以下几个部分: 182222.1高速AD-DA简介 22.2实验任务 22.3硬件设计 22.4程序设计 22.5下载验证

22.1高速AD/DA简介

本章我们使用的AD-DA模块是正点原子推出的一款高速模数-数模转换模块(ATK_HS_AD_DA),高速AD转换芯片和高速DA转换芯片都是由ADI公司生产的,分别是AD9280/3PA9280(两款芯片兼容)和AD9708/ 3PD9708(两款芯片兼容)。 ATK_HS_AD_DA模块的硬件结构图如下图所示。 在这里插入图片描述

图 22.1.1 ATK_HS_AD_DA模块硬件结构图 由上可知,AD9708芯片输出的是一对差分电流信号,为了防止受到噪声干扰,电路中接入了低通滤波器,然后通过高性能和高带宽的运放电路,实现差分变单端以及幅度调节等功能,使整个电路性能得到了最大限度的提升,最终输出的模拟电压范围是-5V~+5V。 AD9280芯片的输入模拟电压转换范围是0V2V,所以电压输入端需要先经过电压衰减电路,使输入的-5V+5V之间的电压衰减到0V~2V之间,然后经过AD9280芯片将模拟电压信号转换成数字信号。 下面我们分别介绍下这两个芯片。 AD9708芯片 AD9708是ADI公司(Analog Devices,Inc.,亚德诺半导体技术有限公司)生产的TxDAC系列数模转换器,具有高性能、低功耗的特点。AD9708的数模转换位数为8位,最大转换速度为125MSPS(每秒采样百万次Million Samples per Second)。 AD9708的内部功能框图如下图所示: 在这里插入图片描述

图 22.1.2 AD9708内部功能框图 AD9708在时钟(CLOCK)的驱动下工作,内部集成了+1.2V参考电压(+1.20V REF)、运算放大器、电流源(CURRENT SOURCE ARRAY)和锁存器(LATCHES)。两个电流输出端IOUTA和IOUTB为一对差分电流,当输入数据为0(DB7DB0=8’h00)时,IOUTA的输出电流为0,而IOUTB的输出电流达到最大,最大值的大小跟参考电压有关;当输入数据全为高点平(DB7DB0=8’hff)时,IOUTA的输出电流达到最大,最大值的大小跟参考电压有关,而IOUTB的输出电流为0。 AD9708必须在时钟的驱动下才能把数据写入片内的锁存器中,其触发方式为上升沿触发,AD9708的时序图如下图所示: 在这里插入图片描述

图 22.1.3 AD9708时序图 上图中的DBO-DB7和CLOCK是AD9708的8位输入数据和输入时钟,IOUTA和IOUTB为AD9708输出的电流信号。由上图可知,数据在时钟的上升沿锁存,因此我们可以在时钟的下降沿发送数据。需要注意的是,CLOCK的时钟频率越快,AD9708的数模转换速度越快,AD9708的时钟频率最快为125Mhz。 IOUTA和IOUTB为AD9708输出的一对差分电流信号,通过外部电路低通滤波器与运放电路输出模拟电压信号,电压范围是-5V至+5V之间。当输入数据等于0时,AD9708输出的电压值为5V;当输入数据等于255(8’hff)时,AD9708输出的电压值为-5V。 AD9708是一款数字信号转模拟信号的器件,内部没有集成DDS(Direct Digital Synthesizer,直接数字式频率合成器)的功能,但是可以通过控制AD9708的输入数据,使其模拟DDS的功能。例如,我们使用AD9708输出一个正弦波模拟电压信号,那么我们只需要将AD9708的输入数据按照正弦波的波形变化即可,下图为AD9708的输入数据和输出电压值按照正弦波变化的波形图。 在这里插入图片描述

图 22.1.4 AD9708正弦波数据(左)、电压值(右) 由上图可知,数据在0至255之间按照正弦波的波形变化,最终得到的电压也会按照正弦波波形变化,当输入数据重复按照正弦波的波形数据变化时,那么AD9708就可以持续不断的输出正弦波的模拟电压波形。需要注意的是,最终得到的AD9708的输出电压变化范围由其外部电路决定的,当输入数据为0时,AD9708输出+5V的电压;当输入数据为255时,AD9708输出-5V的电压。 由此可以看出,只要输入的数据控制的得当,AD9708可以输出任意波形的模拟电压信号,包括正弦波、方波、锯齿波、三角波等波形。 在了解完高速DA转换芯片后,接下来我们介绍下高速AD转换芯片AD9280。 AD9280芯片 AD9280是ADI公司生产的一款单芯片、8位、32MSPS(Million Samples Per Second,每秒采样百万次)模数转换器,具有高性能、低功耗的特点。 AD9280的内部功能框图如下图所示: 在这里插入图片描述

图 22.1.5 AD9280内部功能框图 AD9280在时钟(CLK)的驱动下工作,用于控制所有内部转换的周期;AD9280内置片内采样保持放大器(SHA),同时采用多级差分流水线架构,保证了32MSPS的数据转换速率下全温度范围内无失码;AD9280内部集成了可编程的基准源,根据系统需要也可以选择外部高精度基准满足系统的要求。 AD9280输出的数据以二进制格式表示,当输入的模拟电压超出量程时,会拉高OTR(out-of-range)信号;当输入的模拟电压在量程范围内时,OTR信号为低电平,因此可以通过OTR信号来判断输入的模拟电压是否在测量范围内。 AD9280的时序图如下图所示: 在这里插入图片描述

图 22.1.6 AD9280时序图 模拟信号转换成数字信号并不是当前周期就能转换完成,从采集模拟信号开始到输出数据需要经过3个时钟周期。比如上图中在时钟CLK的上升沿沿采集的模拟电压信号S1,经过3个时钟周期后(实际上再加上25ns的时间延时),输出转换后的数据DATA1。需要注意的是,AD9280芯片的最大转换速度是32MSPS,即输入的时钟最大频率为32MHz。 AD9280支持输入的模拟电压范围是0V至2V,0V对应输出的数字信号为0,2V对应输出的数字信号为255。而AD9708经外部电路后,输出的电压范围是-5V+5V,因此在AD9280的模拟输入端增加电压衰减电路,使-5V+5V之间的电压转换成0V至2V之间。那么实际上对我们用户使用来说,当AD9280的模拟输入接口连接-5V电压时,AD输出的数据为0;当AD9280的模拟输入接口连接+5V电压时,AD输出的数据为255。 当AD9280模拟输入端接-5V至+5V之间变化的正弦波电压信号时,其转换后的数据也是成正弦波波形变化,转换波形如下图所示: 在这里插入图片描述

图 22.1.7 AD9280正弦波模拟电压值(左)、数据(右) 由上图可知,输入的模拟电压范围在-5V至5V之间,按照正弦波波形变化,最终得到的数据也是按照正弦波波形变化。 22.2实验任务 本节实验任务是使用DFZU2EG/4EV MPSoC开发板及高速AD-DA扩展模块(ATK_HS_AD_DA模块)实现数模及模数的转换。首先MPSoC PL产生正弦波变化的数字信号,经过DA芯片后转换成模拟信号,将DA的模拟电压输出端连接至AD的模拟电压输入端,AD芯片将模拟信号转换成数字信号,然后通过ILA观察数字信号的波形是否按照正弦波波形变化。 22.3硬件设计 ATK_HS_AD_DA模块由DA转换芯片(AD9708)和AD转换芯片(AD9280)组成。AD9708的原理图如下图所示。 在这里插入图片描述

图 22.3.1 AD9708原理图 由上图可知,AD9708输出的一对差分电流信号先经过滤波器,再经过运放电路得到一个单端的模拟电压信号。图中右侧的W1为滑动变阻器,可以调节输出的电压范围,推荐通过调节滑动变阻器,使输出的电压范围在-5V至+5V之间,从而达到AD转换芯片的最大转换范围。 AD9280的原理图如下图所示。 在这里插入图片描述

图 22.3.2 AD9280原理图 上图中输入的模拟信号SMA_IN(VI)经过衰减电路后得到AD_IN2(VO)信号,两个模拟电压信号之间的关系是VO=VI/5+1,即当VI=5V时,VO=2V;VI=-5V时,VO=0V。 ATK_HS_AD_DA模块的实物图如下图所示。 在这里插入图片描述

图 22.3.3 ATK-HS-AD-DA模块实物图 本实验中,各端口信号的管脚分配如下表所示。 表 22.3.1 高速AD-DA转换实验管脚分配 在这里插入图片描述

对应的XDC约束语句如下所示:

#IO管脚约束 #时钟周期约束 create_clock -name sys_clk_p -period 10.000 [get_ports sys_clk_p] #时钟 set_property IOSTANDARD DIFF_HSTL_I_12 [get_ports sys_clk_p] set_property IOSTANDARD DIFF_HSTL_I_12 [get_ports sys_clk_n] set_property PACKAGE_PIN AE5 [get_ports sys_clk_p] set_property PACKAGE_PIN AF5 [get_ports sys_clk_n] #复位 set_property -dict {PACKAGE_PIN AH11 IOSTANDARD LVCMOS33} [get_ports sys_rst_n] #ad_da管脚约束 set_property -dict {IOSTANDARD LVCMOS33 PACKAGE_PIN A14} [get_ports {da_data[7]}] set_property -dict {IOSTANDARD LVCMOS33 PACKAGE_PIN A15} [get_ports {da_data[6]}] set_property -dict {IOSTANDARD LVCMOS33 PACKAGE_PIN B14} [get_ports {da_data[5]}] set_property -dict {IOSTANDARD LVCMOS33 PACKAGE_PIN B15} [get_ports {da_data[4]}] set_property -dict {IOSTANDARD LVCMOS33 PACKAGE_PIN C13} [get_ports {da_data[3]}] set_property -dict {IOSTANDARD LVCMOS33 PACKAGE_PIN A13} [get_ports {da_data[2]}] set_property -dict {IOSTANDARD LVCMOS33 PACKAGE_PIN C14} [get_ports {da_data[1]}] set_property -dict {IOSTANDARD LVCMOS33 PACKAGE_PIN B13} [get_ports {da_data[0]}] set_property -dict {IOSTANDARD LVCMOS33 PACKAGE_PIN A12} [get_ports da_clk] set_property -dict {IOSTANDARD LVCMOS33 PACKAGE_PIN C11} [get_ports {ad_data[7]}] set_property -dict {IOSTANDARD LVCMOS33 PACKAGE_PIN B11} [get_ports {ad_data[6]}] set_property -dict {IOSTANDARD LVCMOS33 PACKAGE_PIN B10} [get_ports {ad_data[5]}] set_property -dict {IOSTANDARD LVCMOS33 PACKAGE_PIN A10} [get_ports {ad_data[4]}] set_property -dict {IOSTANDARD LVCMOS33 PACKAGE_PIN E10} [get_ports {ad_data[3]}] set_property -dict {IOSTANDARD LVCMOS33 PACKAGE_PIN E12} [get_ports {ad_data[2]}] set_property -dict {IOSTANDARD LVCMOS33 PACKAGE_PIN D10} [get_ports {ad_data[1]}] set_property -dict {IOSTANDARD LVCMOS33 PACKAGE_PIN D11} [get_ports {ad_data[0]}] set_property -dict {IOSTANDARD LVCMOS33 PACKAGE_PIN A11} [get_ports ad_clk] set_property -dict {IOSTANDARD LVCMOS33 PACKAGE_PIN C12} [get_ports ad_otr]

22.4程序设计 根据本章的实验任务,MPSoC需要连续输出正弦波波形的数据,才能使AD9708连续输出正弦波波形的模拟电压,如果通过编写代码使用三角函数公式运算的方式输出正弦波数据,那么程序设计会变得非常复杂。在工程应用中,一般将正弦波波形数据存储在RAM或者ROM中,由于本次实验并不需要写数据到RAM中,因此我们将正弦波波形数据存储在只读的ROM中,直接读取ROM中的数据发送给DA转换芯片即可。 图 22.4.1是根据本章实验任务画出的系统框图。ROM里面事先存储好了正弦波波形的数据,DA数据发送模块从ROM中读取数据,将数据和时钟送到AD9708的输入数据端口和输入时钟端口;AD数据接收模块给AD9280输出驱动时钟信号和使能信号,并采集AD9280输出模数转换完成的数据。 高速AD/DA实验的系统框图如图 22.4.1所示: 在这里插入图片描述

图 22.4.1 高速AD/DA系统框图 顶层模块的原理图如下图所示: 在这里插入图片描述

图 22.4.2 顶层模块原理图 FPGA顶层模块(hs_ad_da)例化了以下三个模块:DA数据发送模块(da_wave_send)、ROM波形存储模块(rom_256x8b)和AD数据接收模块(ad_wave_rec)。 DA数据发送模块(da_wave_send):DA数据发送模块输出读ROM地址,将输入的ROM数据发送至DA转换芯片的数据端口。 ROM波形存储模块(rom_256x8b):ROM波形存储模块由Vivado软件自带的Block Memory Generator IP核实现,其存储的波形数据可以使用波形转存储文件的上位机来生成.coe文件。 AD数据接收模块(ad_wave_rec):AD数据接收模块输出AD转换芯片的驱动时钟和使能信号,随后接收AD转换完成的数据。 顶层模块的代码如下:

1 module hs_ad_da( 2 input sys_clk_p , //系统差分输入时钟 3 input sys_clk_n , //系统差分输入时钟 4 input sys_rst_n , //系统复位,低电平有效 5 //DA芯片接口 6 output da_clk , 7 //DA(AD9708)驱动时钟,最大支持125Mhz时钟 8 output [7:0] da_data , //输出给DA的数据 9 //AD芯片接口 10 input [7:0] ad_data , //AD输入数据 11 //模拟输入电压超出量程标志(本次试验未用到) 12 input ad_otr , //0:在量程范围 1:超出量程 13 output ad_clk 14 //AD(AD9280)驱动时钟,最大支持32Mhz时钟 15 ); 16 17 //wire define 18 wire [7:0] rd_addr; //ROM读地址 19 wire [7:0] rd_data; //ROM读出的数据 20 //***************************************************** 21 //** main code 22 //***************************************************** 23 24 //转换差分信号 25 IBUFDS diff_clock 26 ( 27 .I (sys_clk_p), //系统差分输入时钟 28 .IB(sys_clk_n), //系统差分输入时钟 29 .O (sys_clk) //输出系统时钟 30 ); 31 32 //DA数据发送 33 da_wave_send u_da_wave_send( 34 .clk (sys_clk), 35 .rst_n (sys_rst_n), 36 .rd_data (rd_data), 37 .rd_addr (rd_addr), 38 .da_clk (da_clk), 39 .da_data (da_data) 40 ); 41 42 //ROM存储波形 43 rom_256x8b u_rom_256x8b ( 44 .clka (sys_clk), // input wire clka 45 .addra (rd_addr), // input wire [7 : 0] addra 46 .douta (rd_data) // output wire [7 : 0] douta 47 ); 48 49 //AD数据接收 50 ad_wave_rec u_ad_wave_rec( 51 .clk (sys_clk ), 52 .rst_n (sys_rst_n), 53 .ad_data (ad_data ), 54 .ad_otr (ad_otr ), 55 .ad_clk (ad_clk ) 56 ); 57 58 //ILA采集AD数据 59 ila_0 ila_0 ( 60 .clk (ad_clk ), // input wire clk 61 .probe0 (ad_otr ), // input wire [0:0] probe0 62 .probe1 (ad_data) // input wire [7:0] probe0 63 ); 64 65 endmodule

DA数据发送模块输出的读ROM地址(rd_addr)连接至ROM模块的地址输入端,ROM模块输出的数据(rd_data)连接至DA数据发送模块的数据输入端,从而完成了从ROM中读取数据的功能。 在代码的第42至47行例化了ROM模块,由Block Memory Generator IP核配置生成。 代码的第58行例化了一个ILA的IP核,用于捕获ad_otr和ad_data的数据。需要注意的是,ILA的采样时钟必须使用ad_clk,否则数据可能采集错误。ILA IP核的配置如下图所示: 在这里插入图片描述

图 22.4.3 ILA IP核的Genaral Options配置 我们把探针数量设置为2,并且把采样深度设置为4096。探针宽度的设置如下图所示: 在这里插入图片描述

图 22.4.4 ILA IP核的Probe_Ports配置 我们将两个探针的位宽设置成1和8,分别对应ad_otr和ad_data的位宽,设置完成后点击“OK”按钮即可。 我们在前面说过,ROM中存储的波形数据可以使用上位机波形转COE软件生成,在这里我们介绍一个简单易用的波形转COE工具的使用方法,该工具位于开发板所随附的资料“6_软件资料/1_软件/WaveToMem”目录下,双击“WaveToMem_V1.2.exe”运行软件。 接下来我们对软件进行设置,如图 22.4.5所示,这里对软件界面做个简单的介绍。 位宽:波形数据的位宽。由于ATK_HS_AD_DA模块的DA芯片数据位宽为8位,因此这里保持默认,即设置成8位。 深度:一个波形周期包含了多少个数据量。这里保持默认,即设置成256。需要说明的是,在用Block Memory Generator IP核生成ROM时,配置ROM的宽度和深度和上位机设置的位宽和深度保持一致。 波形频率设置:对波形倍频,倍数值越大,最终生成的波形频率越快(频率太高,可能导致波形失真),这里保持默认,即设置成1位。 波形类型:软件支持将正弦波、方波、锯齿波和三角波的波形转换成存储波形格式的文件。 生成文件:软件支持将波形转换成COE(Vivado软件支持的存储格式)和MIF(Quartus软件支持的存储格式)格式文件,这里保持默认,即选中COE文件格式。 然后点击“一键生成”按钮,在弹出的界面中选择COE文件的存放路径并输入文件名,这里将COE文件保存在工程的doc文件夹下。WaveToMem转换过程中的软件界面如下图所示: 在这里插入图片描述

图 22.4.5 WaveToMem软件界面 使用Notepad++代码编辑器打开生成的COE文件后如下图所示: 在这里插入图片描述

图 22.4.6 COE文件打开界面 工程中创建了一个单端口ROM,并命名为“rom_256x8b”,在调用Block Memory Generator IP核时,“Basic”选项也配置如下图所示: 在这里插入图片描述

图 22.4.7 Block Memory Generator IP核的Basic配置页面 我们将其接口类型设置为“Native”、Memory Type设置为“Single Port ROM”,即单端口ROM。 “Port A Options”选项页的配置页面如下图所示: 在这里插入图片描述

图 22.4.8 Block Memory Generator IP核的PortA Options配置页面 我们将PortA的位宽设置为8,深度设置为256,以存储上位机生成的256个数据。此外,将使能引脚的类型设置为“Always Enabled”,即ROM一直处于使能的状态。 接下来配置“Other Options”选项页,加载刚才生成的.coe文件,如下图所示: 在这里插入图片描述

图 22.4.9 Block Memory Generator IP核的Other Options配置页面 最后点击“OK”按钮完成IP核的配置。 DA数据发送模块的代码如下:

1 module da_wave_send( 2 input clk , //时钟 3 input rst_n , //复位信号,低电平有效 4 5 input [7:0] rd_data, //ROM读出的数据 6 output reg [7:0] rd_addr, //读ROM地址 7 //DA芯片接口 8 output da_clk , //DA(AD9708)驱动时钟,最大支持125Mhz时钟 9 output [7:0] da_data //输出给DA的数据 10 ); 11 12 //parameter 13 //频率调节控制 14 parameter FREQ_ADJ = 8'd5; //频率调节,FREQ_ADJ的值越大,最终输出的频率越低,范围0~255 15 16 //reg define 17 reg [7:0] freq_cnt ; //频率调节计数器 18 19 //***************************************************** 20 //** main code 21 //***************************************************** 22 23 //数据rd_data是在clk的上升沿更新的,所以DA芯片在clk的下降沿锁存数据是稳定的时刻 24 //而DA实际上在da_clk的上升沿锁存数据,所以时钟取反,这样clk的下降沿相当于da_clk的上升沿 25 assign da_clk = ~clk; 26 assign da_data = rd_data; //将读到的ROM数据赋值给DA数据端口 27 28 //频率调节计数器 29 always @(posedge clk or negedge rst_n) begin 30 if(rst_n == 1'b0) 31 freq_cnt


【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3