DAC测试实验——FPGA学习比

news2025/2/26 21:18:57

一、DAC简介

DAC全称Digital to Analog Converter,即数模转换器。它用于将主控芯片产生的数字值(0和1)转换为模拟值(电压值)。

1、DAC参数指标

2、DAC类型

        常用的DAC可大致分为权电阻网络DACT型电阻网络DACT型电阻网络DAC以及权电流型DAC

3、AD9708/3PD9708芯片

        AD9708是ADI公司(Analog DevicesInc.,亚德诺半导体技术有限公司)生产的TxDAC系列数模转换器,具有高性能、低功耗的特点。AD9708的数模转换位数为8位,最大转换速度为125MSPS(每秒采样百万次Million Samples per Second)。

(1)引脚说明

(2)芯片参数

(3)AD9708芯片内部结构图

 DB7-DB0为数字输入端(0-255),当REFLO连接到ACOM端以后,REFIO参考电压作为输出使用(输出内部参考电压1.2V),此时尤其关注RSET电阻,计算此时输出电流

I{_{out}}^{}=\frac{1.2V}{R{_{REST}}^{}}*32

此输出电流不可直接使用,需结合数字DB7-DB0输入端。计算此时输出电流

I{_{A}}^{}=\frac{dadata}{256}*I_{out}

I{_{B}}^{}=\frac{256-da data}{256}*I_{out}

此输出电流经过外接电阻得到需要的电压值!并不是直接输出电压值!!!

(4)AD9708时序图

(5)AD9708数字模拟转换关系

二、硬件设计

1、电源设计

        外部输入VCC_5V先经过LC滤波电路(精度要求高)得到VCC_IN,经过SGM3204得到反相电压,经过RT9193-3.3得到DVCC_3V3和AVCC_3V3。

2、DA端口设计

数字端直连FPGA(FPGA输出),FSADJ端外接电阻为2K,下面计算芯片输出电流:

I_{_{outA}}=\frac{1.2V}{2K}*32*\frac{dadata}{256}

I_{_{outB}}=\frac{1.2V}{2K}*32*\frac{256-dadata}{256}

当外部输入数据为256时,I_{_{outA}}=19.2mA       I_{_{outB}}=0mA

当外部输入数据为000时,I_{_{outA}}=0mA       I_{_{outB}}=19.2mA

 输出电流经过5阶滤波尽可能减小波动使输出变得平滑,下面计算U7B正向输入电压(欧姆定律):

\frac{V1}{100//100}+\frac{V1}{2K} = 19.2mA         V1\approx0.936V(近似去0.9或1V)

即可得知V1电压范围为0~1V,V2电压范围1~0V,下面计算减法器输出:

\frac{V1-V+}{1K}=\frac{V+}{1K} => V1 = 2V+

    \frac{V2-V-}{1K}=\frac{V-Vo}{1K} => V2 -V-= V- -Vo

V2 = 2V- -Vo

因为再虚短时V+ = V-        V2 = V1-Vo      Vo = V1-V2

因此运放输出电压为-1V~1V,继续计算后级反向放大器输出:

\frac{V1-V-}{1K}=\frac{V--Vo}{RF1}

因为再虚短时V+ = V- = 0V   Vo=-\frac{RF1*V1}{1K}因此得到输出为:

Vo=-RF1*V1     (-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,

正点原子资料下载中心icon-default.png?t=N7T8http://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) begin
    if(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) begin
    if(rst_n == 1'b0)
        rd_addr <= 10'd0;
    else begin
        if(freq_cnt == FREQ_ADJ) begin
            rd_addr <= rd_addr + 10'd1;
        end    
    end            
end

endmodule

        在代码的第 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的驱动时钟来提高正弦波输出频率。

四、下载验证

(图先欠着)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1823702.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

html中a标签的多用性

在HTML中&#xff0c;<a> 标签&#xff08;通常称为锚标签或链接标签&#xff09;具有多种用途和强大的功能。以下是<a>标签的一些主要多用性&#xff1a; 网页间的导航&#xff1a; 这是<a>标签最常见的用途。通过href属性&#xff0c;可以指定一个URL&am…

【问题解决】国际化messages_zh_CN.properties中乱码问题

打开 messages_zh_CN.properties 文件 之前用中文写的现在都是各种各样的符号 解决方法&#xff1a; 打开idea 找到File>Settings>Editor>File Encodings 确定这三个地方是否都是utf-8&#xff0c;改好之后点确定&#xff0c;就能正常显示了

吴恩达深度学习笔记:机器学习(ML)策略(1)(ML strategy(1))1.9-1.10

这里写自定义目录标题 第三门课 结构化机器学习项目&#xff08;Structuring Machine Learning Projects&#xff09;第一周 机器学习&#xff08;ML&#xff09;策略&#xff08;1&#xff09;&#xff08;ML strategy&#xff08;1&#xff09;&#xff09;1.9 可避免偏差&am…

红队内网攻防渗透:内网渗透之Linux内网权限提升技术:udf提权Capability权限LD_PRELOAD环境变量

红队内网攻防渗透 1. 内网权限提升技术1.1 Linux系统提权-Web&用户-数据库udf提权1.1.1 信息收集1.1.2 Web权限获取1.1.3 MYSQL-UDF提权1.1.4 下载到目标上1.1.5 连接确认是否有条件进行导出调用1.1.6 开始进行写入导出调用1.2 Linux系统提权-Web&用户-Capability能力1…

高分论文密码---大尺度空间模拟预测与数字制图

大尺度空间模拟预测和数字制图技术和不确定性分析广泛应用于高分SCI论文之中&#xff0c;号称高分论文密码。大尺度模拟技术可以从不同时空尺度阐明农业生态环境领域的内在机理和时空变化规律&#xff0c;又可以为复杂的机理过程模型大尺度模拟提供技术基础。我们将结合一些经典…

JDK8时间类,时区,时间和格式化

一.时间类 二.获取所有的时区 1.获取所有的时区Set<String> zoneIds ZoneId.getAvailableZoneIds();System.out.println(zoneIds.size()); 根据打印的结果可以看到java类中一共有603个时区。 三.获取当前系统默认的时区 ZoneId zoneId ZoneId.systemDefault();Syste…

测试基础13:测试用例设计方法-错误推断、因果图判定表

课程大纲 1、错误推测法 靠主观经验和直觉来推测可能容易出现问题的功能或场景&#xff0c;设计相关测试用例进行验证。 2、因果图&判定表 2.1定义 因果图和判定表是分析和表达多逻辑条件下&#xff0c;执行不同操作的情况的工具。 &#xff08;因果图和判定表配合使用&a…

20.2 JSON-JSON解码、映射数据类型、处理JSON响应

1. JSON解码 JSON解码&#xff0c;即将JSON格式在字符串转换为Go语言数据类型的变量。 函数Unmarshal接受一个JSON字节切片和一个指定目标格式的接口。而这个借口即与JSON字符串中的结果相匹配的结构体类型的变量。 定义结构体类型 type Person struct { ... }创建结构体变量…

Internet Download Manager(IDM6.41)安装教程+软件安装包下载

IDM是一款多线程下载工具&#xff0c;全称InternetDownloadManager。IDM的多线程加速功能&#xff0c;能够充分利用宽带&#xff0c;所以下载速度会比较快&#xff0c;而且它支持断点续传。它的网站音视频捕获、站点抓取、静默下载等功能&#xff0c;也特别实用。 安 装 包 获 …

堆的实现及其应用

堆的概念 堆是完全二叉树&#xff0c;分为大堆和小堆。大堆&#xff1a;任何一个父亲都大于等于孩子&#xff0c;小堆&#xff1a;任何一个父亲都小于等于孩子。 堆的实现 目录 typedef int HPDataType;typedef struct Heap { HPDataType* a;int size;int capacity; }HP;//交…

java写一个验证码

生成验证码 内容&#xff1a;可以是小写字母&#xff0c;也可以是大写字母&#xff0c;还可以是数字 规则 长度为5 内容中是四位字母&#xff0c;1位数字。 其中数字只有1位&#xff0c;但是可以出现在任意的位置。 package User;import java.util.ArrayList; import jav…

MFC动态创建按钮

void CMFCApplication1Dlg::OnBnClickedOk() {for (int i 0; i < 100; i){for (int j 0; j < 100; j){CButton* pButton3 new CButton;pButton[i][j] pButton3;}}CRect rect;GetClientRect(&rect); // 获取对话框客户区的大小rect.top 10; // 设置按钮的位置rec…

【培训】企业档案管理专题(私货)

导读&#xff1a;通过该专题培训&#xff0c;可以系统了解企业档案管理是什么、为什么、怎么做。尤其是对档案的价值认知&#xff0c;如何构建与新质生产力发展相适应的企业档案工作体系将有力支撑企业新质生产力的发展&#xff0c;为企业高质量发展贡献档案力量&#xff0c;提…

02-adb的工作原理和常见命令

一、什么是adb&#xff1f; ADB 是 Android Debug Bridge 的简称&#xff0c;是 Android 平台的调试工具。通过 adb 命令可以去获取安卓设备上的一些信息&#xff0c;也可以直接操作管理 Android 模拟器或者真实的 Android 设备。 ADB 采用客户端-服务端程序架构&#xff0c;简…

12306 火车票价格解析 (PHP 解析)

1. 从接口拿数据 日期 出发站 终点站 都填上 xxx/otn/leftTicketPrice/queryAllPublicPrice?leftTicketDTO.train_date2024-06-15&leftTicketDTO.from_stationBJP&leftTicketDTO.to_stationSJP&purpose_codesADULT 返回的数据是这样的 {"validateMess…

格式工厂转换mp3失败,原因和解决方法来了

在使用格式工厂进行音频转换时&#xff0c;有时候可能会遇到转换为MP3失败的问题。这可能会让人感到困扰&#xff0c;但幸运的是&#xff0c;这样的问题通常有一些常见的原因&#xff0c;而且大多数情况下都能够轻松解决。在本文中&#xff0c;我们将探讨一些可能导致格式工厂转…

【Linux】高级IO——五种IO方式,select,poll,epoll

文章目录 一、简单了解什么是IO及五种IO模式五种IO同步IO和异步IO区别1.阻塞IO&#xff08;张三钓鱼方式&#xff09;2.非阻塞IO非阻塞轮询&#xff08;李四钓鱼方式&#xff09;使用fcntl函数实现SetNonBlock非阻塞 二、IO多路转接——select&#xff08;赵六钓鱼方式&#xf…

HTML静态网页成品作业(HTML+CSS)—— 家乡成都介绍网页(4个页面)

&#x1f389;不定期分享源码&#xff0c;关注不丢失哦 文章目录 一、作品介绍二、作品演示三、代码目录四、网站代码HTML部分代码 五、源码获取 一、作品介绍 &#x1f3f7;️本套采用HTMLCSS&#xff0c;未使用Javacsript代码&#xff0c;共有4个页面。 二、作品演示 三、代…

前端技术回顾系列 11|TS 中一些实用概念

在微信中阅读,关注公众号:CodeFit。 创作不易,如果你觉得这篇文章对您有帮助,请不要忘了 点赞、分享 和 关注 我的公众号:CodeFit,为我的持续创作提供动力。 上文回顾:泛型在类和接口中的应用 上一篇文章我们回顾了 泛型 在 类 和 接口 中的应用。 通过使用泛型,我们…

【NetTopologySuite类库】C#生成带约束(线、面)的Delaunay三角网

介绍 API地址&#xff1a;https://nettopologysuite.github.io/NetTopologySuite/api/NetTopologySuite.Triangulate.ConformingDelaunayTriangulationBuilder.html#NetTopologySuite_Triangulate_ConformingDelaunayTriangulationBuilder_Constraints 约束为线 效果图 红色…