FPGA使用XADC测量外部模拟输入电压

一、XADC简介

1.1、特性

Xilinx系列的FPGA中都包含了一个内置的XADC,我们可以通过这个XADC进行一些精度不高的外部模拟信号采样以及FPGA片内传感器信号采集。XADC的分辨率为12位,采样率为1MSPS。

1.2、结构框图

  • 两片XADC,ADC A可用于片内传感器采集(温度、参考电源电压),也可用于外部模拟信号采集。ADC B只能用于外部模拟信号采集。
  • 1个专用模拟输入通道和16个复用模拟输入通道
  • 基准源可选:内部基准源和外部基准源
  • 对外接口DRP可通过JTAG或者FPGA内部逻辑进行控制
图1.1 XADC内部结构框图

1.3、XADC接口介绍

  • 初始化接口:
图1.2 XADC初始化接口图
信号名方向功能描述
di_in[15:0]inputDRP的输入数据总线。
daddr_in[6:0]inputDRP的地址总线。
den_ininputDPR的使能信号
dwe_ininputDRP的写使能信号
drdy_outoutputDRP的数据准备好信号
do_out[15:0]outputDRP的输出数据总线
dclk_ininputDRP的输入时钟
reset_ininputXADC的复位信号,高电平有效
vp_in/ vn_ininput专用模拟输入通道,可设计为差分模拟信号输入,当设计使用XADC功能但不用VP/VN时,应该将这两个引脚接地
VAUXP[15:0]/VAUXN[15:0]input16个复用的模拟输入通道,可设计为差分模拟信号输入
ot_outoutput过温报警输出信号
channel_out[4:0]input通道选择输出信号。当前ADC转换的输入MUX通道选择,由该接口输出提供给用户查看。
eoc_outoutputADC转换完成信号。当测量值被写入状态寄存器时,该信号在ADC完成转换之后拉高
eos_outoutput时序结束信号。自动通道序列中,当最后一个通道的数据被写入状态寄存器时,该信号转为高电平。
busy_outoutputADC忙信号。该信号在ADC转换时为一直为高电平。

寄存器接口:
XADC一共有128个寄存器,前64个(00H ~ 3FH)为只读寄存器,后64个(40H~7FH)为可读写的控制寄存器。一般我们用前32个只读寄存器比较多。

1.3 XADC寄存器接口图

ADC通道选择寄存器:
可以看到ADC模拟通道选择的值与对应通道存放数据的状态寄存器的地址相同。

二、硬件电路

2.1、基准电源

XADC的所需要的基本外围电路如图所示。XADC的基准源可使用外步基准源来实现,基准源的电压为1.25V;也可以选择使用内部基准源,外围电路直接将VREFP和VREFN接地即可。

图2.1 基准电源外围电路

2.2、模拟输入通道

XADC模拟信号输入方式有单极性和双极性两种。XADC默认的方式为单极性输入,fpga片上所有传感器的工作模式为单极性输入。

  • 单极性输入: 当使用单极性输入时,输入电压范围为0V ~ 1V,对应ADC编码范围为000h~FFFh,量化分辨率为1V / 212=244uV。
图2.2 单极性输入电压量化图

在单极性输入模式,Vp必须为正,Vn连接到模拟地或者共模信号。Vn连接到共模信号时,该信号电压范围应该为0V0.5V(即Vp与Vn的共模电压范围),由于Vp与Vn的差模电压范围为0V1V,所以在单极性输入模式下,Vp的输入电压最高可达1.5V。

图2.3 单极性输入电压范围图
  • 双极性输入: 当使用双极性输入时,差分输入电压范围为-0.5V ~ +0.5V,XADC编码采用补码格式,对应编码范围为800h ~ FFFh、000h ~ 7FFh。量化分辨率为1V/212=244uV。
图2.4 双极性输入电压量化图
在双极性输入模式,Vp-Vn差分模拟输入电压的范围±0.5V,Vn的共模电压应该不超过0.5V。
图2.5 双极性输入电压范围图

2.3、外部模拟输入电路

模拟通道输入为高输入,数据手册上推荐电路由分压电路和滤波电路组成,通过分压和滤波之后输入到XADC的模拟信号电压值应该不超过1V。

图2.6 外部模拟输入电路图

图2.6中 R1与R2为分压电阻,R5用于与R1与R2的并联电阻匹配。R3、R4与C1构成抗混叠滤波器,建立时间计算参考手册ug480。

在这里插入图片描述

三、时序图

3.1、连续采样模式的时序图

主要有电压采集和电压转换两个阶段。

图3.1 连续采样模式的时序图

DRP时序图

主要用于XADC寄存器的数据读写。

  • 当DEN为高电平时,信号DADDR[6:0]和信号DWE在DCLK的上升沿才会捕捉到,逻辑设计中通常将DEN仅维持一个DCLK时钟的高电平。
  • 当捕捉DWE为低电平时,表示读操作;捕捉DWE为高电平时,表示写操作。
  • 读操作时,DRDY拉高 表示DRP寄存器的数据已经放在总线DO[15:0]上了,用户可以直接读取;写操作时,DRDY拉高表示写的数据已经成功写入DRP寄存器里。
  • 在DRDY拉低之前,一个新的读写操作是不能进行的。
图3.2 DRP时序图

四、XADC的使用教程

4.1、目的

在ZYQN的pl端使用XADC,完成共6路模拟输入信号的电压采样。其中模拟输入通道包括1个Vp/Vn模拟输入通道和5个复用模拟输入通道VAUXP/VAUXN。

4.2、IP核设置

  • Basic界面
  1. 选择DRP接口,读写时序比较简单。
  2. continuous mode 意味着按照设定 ADC 采样率进行采样,event mode 意味着自行控制 ADC 采样率,但是不可超过设定的最大 ADC 采样率;通道选择为 channel sequencer,即多通道采样时按照指定的通道顺序进行扫描采样,通道号定义参考上文通道选择。
  3. 通道序列
  4. 时钟设置
  • ADC Setup界面
    1.序列器模式选择 continuous 模式,会一直循环采样,通道平均次数可按实际情况来,实际采样率=ADC 设定采样率/平均次数。
    2.采样数据平均次数。
  • Alarms界面
    若不是用检测警告功能,该界面可以全部取消勾选。

  • Channel Sequencer界面
    选择需要初始化的通道即可。这里使用的模拟通道为Vp/Vn、vauxp0/vauxn0、vauxp2/vauxn2、vauxp3/vauxn3、vauxp10/vauxn10、vauxp11/vauxn11。

  • Summary界面

4.3、逻辑设计

  • top.v ------顶层文件
`timescale 1ns / 1ps
///
// Create Date: 2023/07/18 16:36:43module top(//时钟input pl_clk,   //模拟输入input vp_in,input vn_in,input vauxp0,input vauxn0,input vauxp2,input vauxn2,input vauxp3,input vauxn3,input vauxp10,input vauxn10,input vauxp11,input vauxn11);wire den_in;
wire dwe_in;
wire drdy_out;              //数据有效输出
wire [15:0] di_in, do_out;  //数据输入 数据输出
wire [6:0] daddr_in;        //寄存器地址
wire [4:0] channel_out;     // 通道选择输出
wire eoc_out;               // 转换完成信号
wire eos_out;               // 时序结束信号
wire alarm_out;
wire busy_out;
wire rst_n;
//模拟通道读取的ADC值
wire [11:0] vpvnData;
wire [11:0] vaux0Data, vaux2Data,vaux3Data,vaux10Data,vaux11Data;//XADC IP例化
xadc_wiz_0 inst_xadc_wiz_0 (.dclk_in(pl_clk),           // input wire dclk_in.di_in(di_in),              // input wire [15 : 0] di_in.daddr_in(daddr_in),        // input wire [6 : 0] daddr_in.den_in(den_in),            // input wire den_in.dwe_in(0),                 // input wire dwe_in     仅用到读操作,故一直设置为零.drdy_out(drdy_out),        // output wire drdy_out.do_out(do_out),            // output wire [15 : 0] do_out.reset_in(0),               // input wire reset_in  不用复位功能.vp_in(vp_in),              // input wire vp_in.vn_in(vn_in),              // input wire vn_in.vauxp0(vauxp0),            // input wire vauxp0.vauxn0(vauxn0),            // input wire vauxn0.vauxp2(vauxp2),            // input wire vauxp2.vauxn2(vauxn2),            // input wire vauxn2.vauxp3(vauxp3),            // input wire vauxp3.vauxn3(vauxn3),            // input wire vauxn3.vauxp10(vauxp10),          // input wire vauxp10.vauxn10(vauxn10),          // input wire vauxn10.vauxp11(vauxp11),          // input wire vauxp11.vauxn11(vauxn11),          // input wire vauxn11.channel_out(channel_out),  // output wire [4 : 0] channel_out.eoc_out(eoc_out),          // output wire eoc_out.alarm_out(alarm_out),      // output wire alarm_out.eos_out(eos_out),          // output wire eos_out.busy_out(busy_out)         // output wire busy_out
);    //对DRP接口操作,完成XADC寄存器数据的读取  
xadc_capture inst_xadc_capture(.dclk(pl_clk),.rst_n(1),                  //不用复位功能.di_in(di_in),.daddr_in(daddr_in),.den_in(den_in),.dwe_in(dwe_in),.drdy_out(drdy_out),.eoc_out(eoc_out),.do_out(do_out),.channel_out(channel_out),.xadc_vpvn_data(vpvnData),.xadc_vaux0_data(vaux0Data),.xadc_vaux2_data(vaux2Data),.xadc_vaux3_data(vaux3Data),.xadc_vaux10_data(vaux10Data),.xadc_vaux11_data(vaux11Data));endmodule
  • xadc_capture.v ------XADC的寄存器数据读取操作
`timescale 1ns / 1ps
///
// Create Date: 2023/07/18 16:36:13module xadc_capture(input           dclk, input           rst_n, //XADC IP 接口 output reg[15:0]di_in,          // 写入xadc总线上的数据output reg[6:0] daddr_in,       // 读取xadc寄存器地址output reg      den_in,         // 控制使能output reg      dwe_in,         // 写使能input           drdy_out,       // 数据有效输出input           eoc_out,input   [15:0]  do_out,         // 读取xadc总线上的数据input   [4:0]   channel_out,    // 通道选择输出//内部逻辑接口 output reg[11:0] xadc_vpvn_data,    //XADC 读出的 Vp/Vn 采样数据 output reg[11:0] xadc_vaux0_data,   //XADC 读出的 vaux0 采样数据    output reg[11:0] xadc_vaux2_data,   //XADC 读出的 vaux2 采样数据output reg[11:0] xadc_vaux3_data,   //XADC 读出的 vaux3 采样数据output reg[11:0] xadc_vaux10_data,  //XADC 读出的 vaux10 采样数据output reg[11:0] xadc_vaux11_data   //XADC 读出的 vaux11 采样数据);///
//产生 XADC 读时序  
always @(posedge dclk or negedge rst_n) beginif(!rst_n) begin den_in <= 1'b0; dwe_in <= 1'b0;        daddr_in <= 7'd0;di_in <= 7'd0;endelse if(eoc_out) begindaddr_in <= {2'b00, channel_out}; //XADC 数据读取寄存器地址 直接连接到通道选择输出channel_out[4:0]den_in <= 1'b1;                   //产生den_in一个时钟周期的高电平     endelse begindaddr_in <= 7'd0;den_in <= 1'b0;endend  ///  
//读 XADC 输出数据   
always @(posedge dclk or negedge rst_n) beginif(!rst_n) begin xadc_vpvn_data  <= 0;xadc_vaux0_data <= 0;       xadc_vaux2_data <= 0;xadc_vaux3_data <= 0;xadc_vaux10_data <= 0;xadc_vaux11_data <= 0;end   else if(drdy_out) begincase(channel_out[4:0])5'h03: beginxadc_vpvn_data <= do_out[15:4];               end5'h10: beginxadc_vaux0_data <= do_out[15:4];               end5'h12: beginxadc_vaux2_data <= do_out[15:4];               end5'h13: beginxadc_vaux3_data <= do_out[15:4];               end5'h1a: beginxadc_vaux10_data <= do_out[15:4];               end5'h1b: beginxadc_vaux11_data <= do_out[15:4];               enddefault: beginendendcaseendendendmodule
  • xadc.xdc ------约束文件
#时钟物理约束
set_property PACKAGE_PIN AD20 [get_ports pl_clk]
set_property IOSTANDARD LVCMOS33 [get_ports pl_clk]#时钟周期约束
create_clock -name clk -period 10 [get_ports pl_clk ]

提示: 当使用复用模拟通道时(VAUXP[15:0]和VAUXN[15:0]),在fpga逻辑设计中不需要对相应的引脚进行约束,只用在顶层模块中调用IP例化模块,并连接到顶层的信号输入即可,这样该引脚就可以作为模拟输入通道。在约束文件中仅对时钟进行了约束。

  • 为方便大家下载官方参考文档,已将这两个文档上传 供大家免费下载。至此,希望能够帮助路过的你。若文章对大家有帮助,也希望能够赏个赞,你们的点赞是我写文章的动力(比心)。欢迎交流学习~

参考文档

  • ug480_7Series_XADC;

  • XADC Wizard v3.3;

  • 百度网盘连接:
    https://pan.baidu.com/s/1GgqPdtemoABWpRRT-owCpQ
    提取码:216p

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

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

相关文章

SpringJPA 做分页条件查询

前言: 相信小伙伴们的项目很多都用到SpringJPA框架的吧,对于单表的增删改查利用jpa是很方便的,但是对于条件查询并且分页 是不是很多小伙伴不经常写到. 今天我整理了一下在这里分享一下. 话不多说直接上代码: Controller: RestController public class ProductInstanceContr…

Apache HTTP服务器(Linux离线编译安装)

Apache HTTP服务器&#xff08;Linux离线编译安装&#xff09; Apache是普通服务器&#xff0c;本身只支持html即普通网页。可以通过插件支持PHP,还可以与Tomcat连通(单向Apache连接Tomcat,就是说通过Apache可以访问Tomcat资源。反之不然)。 Apache和Tomcat都可以做为独立的w…

8个常见的数据可视化错误以及如何避免它们

在当今以数据驱动为主导的世界里&#xff0c;清晰且具有洞察力的数据可视化至关重要。然而&#xff0c;在创建数据可视化时很容易犯错误&#xff0c;这可能导致对数据的错误解读。本文将探讨一些常见的糟糕数据可视化示例&#xff0c;并提供如何避免这些错误的建议。 本文总结了…

如何使用PHP和RabbitMQ实现消息队列?

前言 今天我们来做个小试验&#xff0c;用PHP和RabbitMQ实现消息队列功能。 前期准备&#xff0c;需要安装好docker、docker-compose的运行环境。 如何使用docker部署php服务_php如何使用docker发布-CSDN博客 一、安装RabbitMQ 1、创建相关目录&#xff0c;执行如下命令。…

计算机网络⑦ —— 网络层协议

1. ARP协议 在传输⼀个 IP 数据报的时候&#xff0c;确定了源 IP 地址和⽬标 IP 地址后&#xff0c;就会通过主机路由表确定 IP 数据包下⼀跳。然⽽&#xff0c;⽹络层的下⼀层是数据链路层&#xff0c;所以我们还要知道下⼀跳的 MAC 地址。由于主机的路由表中可以找到下⼀跳的…

手撕算法-接雨水

描述 分析 i位置能积累的雨水量&#xff0c;等于其左右两边最大高度的最小值。为了能获取i位置左右两边的最大高度。使用动态规划。两个dp数组&#xff1a; leftMaxrightMax 其中 leftMax[i] 代表i位置左边的最大高度rightMax[i] 代表i位置右边的最大高度 初始状态&#x…

Python Flask 自定义过滤器

{{ data.list | li2 }} li2就是自定义的 from flask import Flask, render_templateapp Flask(__name__)app.route("/index") def index():data {name: "张三","age": 18,list: [123123, 41, 123]}return render_template("index2.html…

Redis中RDB中的文件写入

RDB文件的创建与载入。 有两个Redis命令可以用于生成RDB文件&#xff0c;一个是SAVE&#xff0c;另一个是BGSAVE. SAVE命令会阻塞Redis服务器进程&#xff0c;直到RDB文件创建完毕为止&#xff0c;在服务器进程阻塞期间&#xff0c;服务器 不能处理任何命令请求: 127.0.0.1:6…

枚举的详解

枚举的讲解 在C语言中&#xff0c;没有内置的枚举&#xff08;enum&#xff09;数据类型&#xff0c;但我们可以使用整数类型来模拟枚举的行为。C99标准之前&#xff0c;C语言使用#define指令来定义枚举&#xff0c;但这种方式并不安全&#xff0c;因为如果枚举值发生变化&…

【matlab程序】海洋资料的获取与分析--AO/NAO

海洋资料的获取与分析 相关数据代码等资料已上传入群中 海洋资料下载和介绍 AO和NAO指数均取自美国气候预测中心&#xff08;Climate Prediction Center, CPC&#xff09;发布的月平均指数&#xff0c;时间跨度为1950-2022年。由于AO和NAO在冬季最强&#xff0c;因此本文选取…

406. 根据身高重建队列(力扣LeetCode)

文章目录 406. 根据身高重建队列题目描述贪心算法代码 406. 根据身高重建队列 题目描述 假设有打乱顺序的一群人站成一个队列&#xff0c;数组 people 表示队列中一些人的属性&#xff08;不一定按顺序&#xff09;。每个 people[i] [hi, ki] 表示第 i 个人的身高为 hi &…

阿里云倚天云服务器怎么样?如何收费?

阿里云倚天云服务器CPU采用倚天710处理器&#xff0c;租用倚天服务器c8y、g8y和r8y可以享受优惠价格&#xff0c;阿里云服务器网aliyunfuwuqi.com整理倚天云服务器详细介绍、倚天710处理器性能测评、CIPU架构优势、倚天服务器使用场景及生态支持&#xff1a; 阿里云倚天云服务…

macOS访问samba文件夹的正确姿势,在哪里更改“macOS的连接身份“?还真不好找!

环境&#xff1a;路由器上需要身份认证的Mini NAS macOS Sonoma 14 这是一个非常简单的问题&#xff0c;但解决方法却藏得比较深&#xff0c;不够直观&#xff0c;GPT也没有给出明确的解决提示&#xff0c;特意记录一下。 macOS很多地方都很自动&#xff0c;有时候让人找不到设…

高中信息技术教资刷题笔记_大题篇

1.选择排序 2. SMTP属于TCP/IP协议体系结构中的哪一层&#xff1f;请列出其通信的三个阶段。 3.高中信息技术课程的基本理念/意义 4.视频作品制作和发布的主要环节 5.信息社会责任内涵及学生表现 6.教学活动意图 ①突出学生的主体地位。材料中&#xff0c;王老师设计的“扮演谍…

代码随想录算法训练营Day56 ||leetCode 583. 两个字符串的删除操作 || 72. 编辑距离

647. 回文子串 dp[i][j]表示第i位开始&#xff0c;第j位结束的字符串是否为回文串 class Solution { public:int countSubstrings(string s) {vector<vector<bool>> dp(s.size(), vector<bool>(s.size(), false));int result 0;for (int i s.size() - 1…

分类预测 | Matlab实现CNN-LSTM-Mutilhead-Attention卷积神经网络-长短期记忆网络融合多头注意力机制多特征分类预测

分类预测 | Matlab实现CNN-LSTM-Mutilhead-Attention卷积神经网络-长短期记忆网络融合多头注意力机制多特征分类预测 目录 分类预测 | Matlab实现CNN-LSTM-Mutilhead-Attention卷积神经网络-长短期记忆网络融合多头注意力机制多特征分类预测分类效果基本介绍模型描述程序设计参…

c#矩阵求逆

目录 一、矩阵求逆的数学方法 1、伴随矩阵法 2、初等变换法 3、分块矩阵法 4、定义法 二、矩阵求逆C#代码 1、伴随矩阵法求指定3*3阶数矩阵的逆矩阵 &#xff08;1&#xff09;伴随矩阵数学方法 &#xff08;2&#xff09;代码 &#xff08;3&#xff09;计算 2、对…

政安晨:【深度学习实践】【使用 TensorFlow 和 Keras 为结构化数据构建和训练神经网络】(五)—— Dropout和批归一化

政安晨的个人主页&#xff1a;政安晨 欢迎 &#x1f44d;点赞✍评论⭐收藏 收录专栏: TensorFlow与Keras实战演绎 希望政安晨的博客能够对您有所裨益&#xff0c;如有不足之处&#xff0c;欢迎在评论区提出指正&#xff01; Dropout和批归一化是深度学习领域中常用的正则化技术…

stm32之GPIO寄存器

文章目录 1 背景2 GPIO寄存器的类型2.1 端口配置寄存器2.2 设置/清除寄存器和位清除寄存器 3 总结 1 背景 C51单片机在进行数据的输入输出时&#xff0c;是直接操作与外部引脚关联的内部寄存器&#xff0c;例如&#xff0c;当设置P2_1为0时&#xff0c;就是将外部引脚的P21引脚…

YOLOV5 部署:TensorRT的安装和使用

1、介绍 TensorRT 可以加速神经网络的推理时间,常常在工业生产中使用 因为TensorRT需要使用到cuda和cudnn加速,所以需要安装这两个,安装的具体步骤参考前文: YOLOV5 部署:cuda和cuDNN安装-CSDN博客 2、TensorRT 下载 TensorRT下载地址:NVIDIA TensorRT Download | NV…