一、DAC简介
DAC全称Digital to Analog Converter,即数模转换器。它用于将主控芯片产生的数字值(0和1)转换为模拟值(电压值)。
1、DAC参数指标
2、DAC类型
常用的DAC可大致分为权电阻网络DAC、T型电阻网络DAC、倒T型电阻网络DAC以及权电流型DAC。
3、AD9708/3PD9708芯片
AD9708是ADI公司(Analog Devices,Inc.,亚德诺半导体技术有限公司)生产的TxDAC系列数模转换器,具有高性能、低功耗的特点。AD9708的数模转换位数为8位,最大转换速度为125MSPS(每秒采样百万次Million Samples per Second)。
(1)引脚说明
(2)芯片参数
(3)AD9708芯片内部结构图
DB7-DB0为数字输入端(0-255),当REFLO连接到ACOM端以后,REFIO参考电压作为输出使用(输出内部参考电压1.2V),此时尤其关注RSET电阻,计算此时输出电流
此输出电流不可直接使用,需结合数字DB7-DB0输入端。计算此时输出电流
此输出电流经过外接电阻得到需要的电压值!并不是直接输出电压值!!!
(4)AD9708时序图
(5)AD9708数字模拟转换关系
二、硬件设计
1、电源设计
外部输入VCC_5V先经过LC滤波电路(精度要求高)得到VCC_IN,经过SGM3204得到反相电压,经过RT9193-3.3得到DVCC_3V3和AVCC_3V3。
2、DA端口设计
数字端直连FPGA(FPGA输出),FSADJ端外接电阻为2K,下面计算芯片输出电流:
当外部输入数据为256时,
当外部输入数据为000时,
输出电流经过5阶滤波尽可能减小波动使输出变得平滑,下面计算U7B正向输入电压(欧姆定律):
(近似去0.9或1V)
即可得知V1电压范围为0~1V,V2电压范围1~0V,下面计算减法器输出:
因为再虚短时V+ = V-
因此运放输出电压为-1V~1V,继续计算后级反向放大器输出:
因为再虚短时V+ = V- = 0V 因此得到输出为:
(-1V<=V1<=1V)
受限于运放芯片供电为±5V,因此最大只能放大到±5V,无法继续放大!!!
三、程序设计
1、设计目标
使用FPGA产生正弦波信号输出。
2、思维导图
3、系统框图
4、DA时序分析
注意一点rd_data会比rd_addr晚一拍!!!地址每6个周期跳变一次
5、代码设计
(1)顶层模块原理图
FPGA 顶层模块(hs_dual_da) 例化了以下三个模块: DA 数据发送模块(da_wave_send)、 ROM 波形存储模块(rom_1024x10b)和时钟模块(clk_wiz_0)
DA 数据发送模块(da_wave_send) : DA 数据发送模块输出读 ROM 地址, 将输入的 ROM 数据发送至DA 转换芯片的数据端口。
ROM 波形存储模块(rom_1024x10b): ROM 波形存储模块由 Vivado 软件自带的 Block Memory Generator IP 核实现, 其存储的波形数据可以使用波形转存储文件的上位机来生成.coe 文件。
(2)顶层代码
module hs_dual_da(input sys_clk , //系统时钟input sys_rst_n , //系统复位,低电平有效//DA接口output da_clk , //DA采样时钟output [9:0] da_data , //DA采样数据output da_clk1 , //DA采样时钟output [9:0] da_data1 //DA采样数据
);//wire define
wire [9:0] rd_addr; //ROM地址?
wire [9:0] rd_data; //ROM数据//*****************************************************
//** main code
//*****************************************************assign da_clk1 = da_clk;
assign da_data1 = da_data;//时钟模块
clk_wiz_0 u_clk_wiz_0(.clk_in1 (sys_clk),.clk_out1 (clk)
);//DA发送模块
da_wave_send u_da_wave_send(.clk (clk), .rst_n (sys_rst_n),.rd_data (rd_data),.rd_addr (rd_addr),.da_clk (da_clk), .da_data (da_data));//ROM模块
rom_1024x10b u_rom_1024x10b(.addra (rd_addr),.clka (clk),.douta (rd_data)
);endmodule
(3)COE文件生成
使用正点原子提供的上位机波形转 COE 软件,WaveToMem_V1.2.exe,
正点原子资料下载中心http://47.111.11.73/docs/index.html
位宽:波形数据的位宽。由于 ATK_DUAL_HS_DA 模块的 DA 芯片数据位宽为 10 位,因此这里将位宽设成 10 位。
深度:一个波形周期包含了多少个数据量。这里将深度设置成 1024。需要说明的是,在用 Block Memory Generator IP 核生成 ROM 时,配置 ROM 的宽度和深度和上位机设置的位宽和深度保持一致。
波形频率设置:对波形倍频,倍数值越大,最终生成的波形频率越快(频率太高,可能导致波形失真),这里保持默认,即设置成 1 位。
波形类型:软件支持将正弦波、方波、锯齿波和三角波的波形转换成存储波形格式的文件。
生成文件:软件支持将波形转换成 COE(Vivado 软件支持的存储格式)和 MIF(Quartus 软件支持的存储格式)格式文件,这里保持默认,即选中 COE 文件格式。
存储路径参考:::D:\FPGA\hs_dual_da\hs_dual_da.srcs\sources_1\new
(4)rom ip核配置
配置使用Block Memory Generator IP核,使用单端口RAM模式
配置读写深度以及位宽,勾选Always Enabled,使ROM一直处于使能状态。
添加刚刚生成的的COE文件
点击OK完成配置。
(5)DA发送数据模块
module da_wave_send(input clk , //系统时钟input rst_n , //系统复位,低电平有效input [9:0] rd_data , //ROM读出的数据output reg [9:0] rd_addr , //读ROM地址//DA接口output da_clk , //DA驱动时钟output [9:0] da_data //输出给DA的数据 );//parameter
//频率调节控制
parameter FREQ_ADJ = 10'd5; //频率调节,FREQ_ADJ的越大,最终输出的频率越低,范围0~255//reg define
reg [9:0] freq_cnt ; //频率调节计数器//*****************************************************
//** main code
//*****************************************************//数据rd_data是在clk的上升沿更新的,所以DA芯片在clk的下降沿锁存数据是稳定的时刻
//而DA实际上在da_clk的上升沿锁存数据,所以时钟取反,这样clk的下降沿相当于da_clk的上升沿
assign da_clk = ~clk;
assign da_data = rd_data; //将读到的ROM数据赋值给DA数据端口//频率调节计数器
always @(posedge clk or negedge rst_n) beginif(rst_n == 1'b0)freq_cnt <= 10'd0;else if(freq_cnt == FREQ_ADJ) freq_cnt <= 10'd0;else freq_cnt <= freq_cnt + 10'd1;
end//读ROM地址
always @(posedge clk or negedge rst_n) beginif(rst_n == 1'b0)rd_addr <= 10'd0;else beginif(freq_cnt == FREQ_ADJ) beginrd_addr <= rd_addr + 10'd1;end end
endendmodule
在代码的第 14 行定义了一个参数 FREQ_ADJ(频率调节),可以通过控制频率调节参数的大小来控制最终输出正弦波的频率大小, 频率调节参数的值越小, 正弦波频率越大。频率调节参数调节正弦波频率的方法是通过控制读 ROM 的速度实现的, 频率调节参数越小, freq_cnt 计数到频率调节参数值的时间越短,读 ROM 数据的速度越快,那么正弦波输出频率也就越高;反过来, 频率调节参数越大, freq_cnt 计数到频率调节参数值的时间越长,读 ROM 数据的速度越慢,那么正弦波输出频率也就越低。由于 freq_cnt 计数器的位宽为 10 位,计数范围是 0~1023, 所以频率调节参数 FREQ_ADJ 支持的调节范围是 0~1023, 可通过修改 freq_cnt 计数器的位宽来修改 FREQ_ADJ 支持的调节范围。
WaveToMem 软件设置 ROM 深度为 1024, 倍频系数为 1,而输入时钟为 125Mhz,那么一个完整的正弦波周期长度为 1024*8ns = 8192ns, 当 FREQ_ADJ 的值为 0 时, 即正弦波的最快输出频率为 1s/8192ns(1s =1000000000ns) ≈ 122.0Khz。 当我们把 FREQ_ADJ 的值设置为 5 时, 一个完整的正弦波周期长度为5120ns*(5+1) =49152ns,频率约为 20.35KHz。 也可以在 WaveToMem 软件设置中增加倍频系数或者增加 DA的驱动时钟来提高正弦波输出频率。