ZYNQ-XADC使用

article/2025/9/24 18:53:47

学习内容

本文首先介绍了ZYNQ的XADC的相关内容,并学习使用ZYNQ芯片中的XADC测量芯片内部的温度电压等参数,然后进行串口打印输出。

开发环境

vivado 18.3&SDK,PYNQ-Z2开发板。

XADC介绍

简介

Xilinx模拟信号转换模块,称为XADC,是一个硬核。它具有JTAG和DRP接口用于访问7系列FPGA中的XADC状态和控制寄存器。Zynq-7000 SoC器件添加了第三个接口,即PS-XADC接口,用于PS软件进行控制XADC。 ZYNQ器件将XADC与可编程逻辑融合,解决了对模拟数据采集和监视要求。

XADC具有两个12位的ADC,具有独立的跟踪和保持放大器,模拟多路复用器(最多17个外部模拟输入通道)以及片上散热和片上电压传感器。可以将两个ADC配置为同时采样两个外部输入模拟通道。采样保持放大器支持一系列模拟输入信号类型,包括单端输入,双端输入和差分输入。模拟输入可以支持信号带宽在1M SPS的采样率下为500 KHz。可以使用外部模拟多路复用器来增加支持的外部通道数量,无需额外的封装引脚。XADC可选地使用片上参考电路,从而无需外部有源元件,用于温度和电源轨的基本片上监控。实现12位的ADC的全部性能,建议使用外部1.25V作为参考电压。最新的测量结果(连同最大和最小读数)存储在专用寄存器。用户可以根据自己的需要进行自定义的警报阈值(例如80°C),可以自动指示温度过高事件和不可接受的电源变化,并启动软件控制的系统掉电。

控制方式

PS端可以通过以下两种方式之一与XADC通信:

  1. PS-XADC接口:PS互连上的32位APB从接口,该接口使用FIFO,并进行了串行化。
  2. 通过PS to PL AXI的主接口,此时要使用AXI XADC Logic IP核来控制XADC。

需要注意的是,对PS端控制ADC对性能要求较高的程序,要使用相关连接的逻辑IP连接到M_AXI_GP接口(并行数据路径)。使用PS_XADC接口时,FIFO用于命令和读取数据,以允许软件快速排队命令,而不必等待序列化,但是对于PS to PL AXI主接口访问,数据像PL-JTAG一样被序列化到XADC 中(串行数据路径),相对来说速度慢得多。

系统框图

PL-JTAG接口和内部PS-XADC接口不能同时使用。 这些接口之间的选择由devcfg.XADCIF_CFG [ENABLE]位控制。 XADC可以进行接口选择,即对(PL-JTAG或PS-XADC)和DRP接口之间进行仲裁选择。下图为XADC的系统框图。
在这里插入图片描述
由上图可知,XADC是通过硬逻辑实现的,并且位于PL电源域中。 PS-XADC接口是PS的一部分,所以无需编程PL就可以由PS APU访问。 但是必须打开PL的电源以配置PS-XADC接口,使用PL-JTAG或DRP接口以及操作XADC。同时由图上可以清楚看出对于PL-JTAG或PS-XADC这两个接口经过了一个二选一选择器,所以这两个不能同时进行驱动。

接口说明

XADC在DRP接口与PS-XADC或PL-JTAG接口之间进行仲裁。

PS-XADC Interface: PS-XADC接口是PS中运行的软件使用devcfg寄存器配置接口。 软件将命令写入接口,然后将其推入命令FIFO。 这些由DRP命令,地址和数据组成的32位写入被串行化,并以回送路径发送到XADC,该回送路径填充了软件读取的返回读取数据FIFO。

DRP Interface: DRP接口是一个并行的16位双向接口,可以使用AXI4-Lite接口通过AXI XADC IP核连接到主机上,以使处理器能够控制XADC。IP内核通过每个AXI4-Lite读/写事务接收16位数据。

PL JTAG Interface: XADC使用完整的JTAG接口扩展到DRP接口。 这允许通过现有的片上JTAG基础结构对XADC DRP进行读/写访问。 通过JTAG访问DRP接口不需要实例化。 边界扫描指令(6位指令= 110111)称为XADC_DRP,已添加到7系列FPGA中,允许通过JTAG TAP访问DRP。 所有XADC JTAG指令均为32位宽。

PS-XADC接口编程指南

本文主要使用的是PS-XADC接口对XADC进行编程控制,下面给出相关操作的编程指导步骤。

通过PS-XADC接口初始化XADC

对通道和XADC进行复位操作,并刷新FIFO,操作顺序如下:

  1. 复位串行通讯通道。 先后把1和0到devcfg.XADCIF_MCTL[RESET]寄存器位中;
  2. 复位XADC。 把16位任意值写入DRP地址0x03(复位寄存器)。接着写08030000h到devcfg.XADCIF_CMDFIFO寄存器中;
  3. 刷新FIFO。 这里刷新FIFO没有复位信号,而是将15个NOOP写入到FIFO;然后等待命令FIFO清空。 最后一个命令应该是NOOP(虚拟写入),最后读取读取数据FIFO,直到为空。

命令准备

准备要写入XADC寄存器的数据配置顺序:
本示例格式化了用于写入XADC配置寄存器1的数据,以将XADC设置为独立模式。

  1. DRP数据。 将XADC设置为独立模式的数据为8000h。
  2. DRP地址。 XADC配置寄存器1的地址为0x41。
  3. 编写命令。 写入操作的命令为0010b。 在XADC配置寄存器1(0x41)中写入8000h的命令为08418000h。

准备从XADC寄存器读取的数据配置顺序:
本示例格式化了用于读取XADC VCCPAUX状态寄存器0x0E的数据。

  1. DRP数据。 数据可以是用于读取操作(0)的任何任意数据。
  2. DRP地址。 XADC VCCPAUX状态寄存器的地址为0x0E。
  3. 编写命令。 读取操作的命令为0001b。 读取XADC VCCPAUX状态寄存器0x0E的命令为040E0000h。

读写FIFO数据

向XADC写入命令
以下编程顺序为写入XADC 电压警报上限阈值寄存器。

  1. 准备命令。 执行上面的命令准备的部分,写入具有所需阈值的XADC VCCPAUX警报上限阈值寄存器(0x5A)。
  2. 用数据填充命令FIFO。 将步骤1中格式化的数据写入devcfg.XADCIF_CMDFIFO寄存器。
  3. 等待命令FIFO变空。 等待,直到devcfg.XADCIF_MSTS [CFIFOE] = 1。

从XADC读取VCCPAUX值:
从XADC VCCPAUX状态寄存器读取当前VCCPAUX值顺序如下:

  1. 准备命令。执行上面的命令准备的部分,读取XADC VCCPAUX状态寄存器(0x0E)。
  2. 将数据写入命令FIFO。将步骤1中格式化的数据写入devcfg.XADCIF_CMDFIFO寄存器。
  3. 等待命令FIFO变空。等待,直到devcfg.XADCIF_MSTS [CFIFOE] = 1。
  4. 从读取数据FIFO读取伪数据。读取devcfg.XADCIF_RDFIFO寄存器。
  5. 格式化数据。执行上面的命令准备的部分,以使其不进行任何操作。
  6. 将数据写入命令FIFO。将步骤5中的格式化数据写入devcfg.XADCIF_CMDFIFO寄存器。
  7. 读取读取数据FIFO。读取devcfg.XADCIF_RDFIFO寄存器。

中断

配置和管理Alarm5(VCCPAUX)
本示例将XADC寄存器配置为设置警报阈值,操作模式并启用
PS-XADC接口中的警报5(VCCPAUX)中断。

  1. 准备命令。执行上面的命令准备的部分,写入XADC硬宏警报阈值寄存器(VCCPAUX Upper-0x5A和VCCPAUX具有所需阈值的低0x5E)和XADC Config_Reg1(0x41)来将XADC设置为独立模式。
  2. 将命令写入命令​​FIFO。将步骤1中准备的命令写到devcfg.XADCIF_CMDFIFO寄存器。
  3. 在PS-XADC接口中启用Alarm5中断。写devcfg.XADCIF_INT_MASK[M_ALM] = 7Eh。
  4. 检查是否触发了Alarm5。 devcfg.XADCIF_INT_STS [M_ALM] = 1的轮询。
  5. 清除Alarm5中断。写入devcfg.XADCIF_INT_STS [M_ALM] = 1。
  6. 禁用Alarm0中断。写入devcfg.XADCIF_INT_MASK [M_ALM] = 7Fh

通过PS-XADC接口的启动顺序

通过PS-XADC接口的启动并设置各种接口参数,并包括中断和数据传输的步骤如下。

  1. 完成初始化XADC;
  2. 配置PS-XADC接口:
    对配置寄存器进行编程。将80001114h写入devcfg.XADCIF_CFG寄存器:
    使用默认的最小空闲间隙,[IGAP] = 14h(20个串行时钟)。
    使用默认的XADC串行时钟频率为PCAP_2x时钟频率的1/4,[TCKRATE] = 01。
    使用默认的FIFO串行读取捕获边沿(上升),[REDGE] = 1。
    使用默认的FIFO串行写启动边沿(下降),[WEDGE] = 0。
    使用默认的读取数据FIFO阈值级别,[DFIFOTH] = 0x0。
    使用默认的命令FIFO阈值级别,[CFIFOTH] = 0。
    启用XADC的PS访问。将0x1写入devcfg.XADCIF_CFG [ENABLE]。
  3. 配置中断:中断用于管理来自XADC和操作FIFO/读取FIFO数据;
  4. 数据传输到XADC。

系统框图

根据本次工程,画出相应的系统框图,如下图所示:
在这里插入图片描述
本次工程,使用了UART和XADC部分,使用XADC对芯片内部的电压和温度进行检测,并用串口打印输出。

硬件平台搭建

因为不需要使用其他资源,可以在原来的UART测试工程下进行开发搭建,直接保存即可。
新建步骤如下,首先新建工程,创建 block design。添加ZYNQ7 ip,根据本次工程需要对IP进行配置。勾选本次工程使用的资源。
在这里插入图片描述
这里只要勾选UART资源即可,取消多余资源,然后点击OK。
硬件系统构建完成如下:
在这里插入图片描述
然后我们进行generate output product 然后生成HDL封装。这里用到了UART,是MIO引脚,所以不需要进行管脚分配,XADC测量是内部的电压信息,并且使用的是PS_XADC接口。点击导出硬件资源(可以不包含bit流文件,因为只用到了PS资源),接着launch SDK。

SDK软件部分

打开SDK后,新建application project。
在system.mss中可以打开相关参考文档辅助设计。
在这里插入图片描述
参考给出的示例,在main.c中写入以下代码:

#include "xparameters.h"
#include "xadcps.h"
#include "stdio.h"
#include "xil_printf.h"
#include "sleep.h"
#define XADC_DEVICE_ID	XPAR_XADCPS_0_DEVICE_ID
static XAdcPs XAdc_Inst;
u32 Temp_RawData;
//芯片温度、最大、最小温度
float TempData;
float TempmaxData;
float TempminData;
//内核各部分电压值
float VccPintData;
float VccPauxData;
float VccPdroData;
float VccBramData;
void Xadc_init();
void Xadc_test();
int main(){//初始化XADCXadc_init();while(1){Xadc_test();sleep(2);}return 0;
}void Xadc_init(){int status;XAdcPs_Config *ConfigPtr;ConfigPtr = XAdcPs_LookupConfig(XADC_DEVICE_ID);XAdcPs_CfgInitialize(&XAdc_Inst, ConfigPtr,ConfigPtr->BaseAddress);//自测status = XAdcPs_SelfTest(&XAdc_Inst);if (status != XST_SUCCESS) {xil_printf("xadc selftest failed!\n");}//设置启动模式XAdcPs_SetSequencerMode(&XAdc_Inst, XADCPS_SEQ_MODE_SAFE);
}
void Xadc_test(){Temp_RawData = XAdcPs_GetAdcData(&XAdc_Inst, XADCPS_CH_TEMP);TempData = XAdcPs_RawToTemperature(Temp_RawData);Temp_RawData = XAdcPs_GetMinMaxMeasurement(&XAdc_Inst, XADCPS_MAX_TEMP);TempmaxData = XAdcPs_RawToTemperature(Temp_RawData);Temp_RawData = XAdcPs_GetMinMaxMeasurement(&XAdc_Inst, XADCPS_MIN_TEMP);TempminData = XAdcPs_RawToTemperature(Temp_RawData);Temp_RawData = XAdcPs_GetAdcData(&XAdc_Inst, XADCPS_CH_VCCPINT);VccPintData = XAdcPs_RawToVoltage(Temp_RawData);Temp_RawData = XAdcPs_GetAdcData(&XAdc_Inst, XADCPS_CH_VCCPAUX);VccPauxData = XAdcPs_RawToVoltage(Temp_RawData);Temp_RawData = XAdcPs_GetAdcData(&XAdc_Inst, XADCPS_CH_VCCPDRO);VccPdroData = XAdcPs_RawToVoltage(Temp_RawData);Temp_RawData = XAdcPs_GetAdcData(&XAdc_Inst, XADCPS_CH_VBRAM);VccBramData = XAdcPs_RawToVoltage(Temp_RawData);printf("============================\n");printf("Current Temperature:%0.4fC\n",TempData);printf("Maximum Temperature:%0.4fC\n",TempmaxData);printf("Minimum Temperature:%0.4fC\n",TempminData);printf("           VccPSint:%0.4fV\n",VccPintData);printf("           VccPSaux:%0.4fV\n",VccPauxData);printf("           VccPSdro:%0.4fV\n",VccPdroData);printf("          VccPSBram:%0.4fV\n",VccBramData);printf("============================\n");
}

整体代码比较简单,主要还是使用相关的函数进行开发设计,这里打印了相关温度和电压信息。

运行效果

在SDK的串口终端中正确显示各个参数信息。
在这里插入图片描述

Reference

  1. UG585
  2. 正点原子开发视频教程

http://chatgpt.dhexx.cn/article/xQE3xkKO.shtml

相关文章

ZYNQ SDK开发调试踩坑指南

关注星标公众号,及时获取更多技术分享~ 作者 | 冰茶奥利奥 微信公众号 | 嵌入式电子创客街 目录 坑1:裸机Ps串口收数问题 坑2:多个中断不能同时使用问题 坑3:block design中DDR3的选择 坑4:新板子能够检测到芯片&…

万变不离其宗之ZYNQ启动介绍

1、概述 ZYNQ 的详细介绍参考 XILINX 官方文档 UG585,在了解了 ZYNQ 的基本架构组成和丰富的资源后,下一步便是分析他的启动流程,以便更好的认识 ZYNQ 并开始开发工作; 关于 ZYNQ 启动方面的描述,这里我觉得涉及到几个…

ZYNQ入门

目录 一、ZYNQ简介 二、vivado工程 ①创建工程 ②添加设计文件 ③生产顶层HDL模块 ④生成 Bitstream 文件并导 三、vitis工程 ①启动vitis ②创建工程 ③编译与下载 一、ZYNQ简介 ZYNQ 是赛灵思公司(Xilinx)推出的新一代全可编程片上系统&#x…

ZYNQ架构

ZYNQ 首先,我们来了解传统的SOC架构,一般使用 ARM 作为主控,通过 ARM 的外设并行 RAM 类总线外挂 FPGA ,使用 FPGA 来做高速的数据采集或者运算,因为FPGA 有灵活性好,资源丰富,可反复编程&#…

zynqmp soc 移植vxWorks 7

1.使用worksbench4创建vsb工程; 2.使用worksbench4创建vip工程; 3.修改设备树文件,根据硬件电路选择对应的UART; 4.tftp引导启动;

ZYNQ开发系列——ZYNQ系统的搭建

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 ZYNQ开发系列——ZYNQ系统的搭建 DDR设置FLASH设置UART设置网口设置当我们有一个要用ZYNQ做的项目时,首先当然是把其最小系统搭建起来。这个最小系统可以交付给开发PS的同事开发裸机程序/RTOS实时操作系统/…

ZYNQ之高速AD/DA验证实验

文章目录 前言一、ADDA模块介绍二、添加ROM IP核三、添加ILA IP核四、编写测试程序五、管脚分配六、连接开发板测试总结 前言 本实验是高速AD/DA验证实验,将使用高速DA芯片实现数模转换,产生正弦波模拟电压信号,并通过高速AD芯片将模拟信号转…

ZYNQ - 嵌入式Linux开发 -10- ZYNQ启动流程分析

FSBL启动准备工作 在静态情况下,Boot.BIN启动文件存放在SD卡或QSPI等存储介质中,然后Boot.BIN文件中已经包含了FSBL代码,也就是说FSBL代码已经集成在了Boot.BIN文件中,所以FSBL代码也是存放在Boot .BIN文件中。 如果要启动FSBL代…

初识ZYNQ结构

本文介绍了zynq的结构,简述了PS中的APU。 处理器系统 所有的 Zynq 芯片都有相同的基本架构。作为处理器系统的基础,所有的芯片都包含了一颗双核 ARM Cortex-A9 处理器。这是一颗 “ 硬 ” 处理器 —— 它是芯片上专用而且优化过的硅片元件。 作为比较…

zynq中断

在zynq中选择中断信号后: 只能看到一个[0:0]的向量,完全无法对应中断号: 且属性栏目没有配置选项,一般可以看到有些连接图如下: 如果看成最低位的话就是61,那么其它中断号怎么使用呢:查到的资料如下&#x…

ZYNQ基础知识

1.ZYNQ介绍 全称为Zynq-7000 All Programmable Soc 1.Zynq是赛灵思(Xilinx)推出的新一代全可编程片上系统,将处理器的软件可编程性和FPGA的硬件可编程性完美结合。具有较强的系统性能、灵活性与可扩展性。 2.旨在为视频监控、汽车驾驶员辅助…

一、ZYNQ简介

1 ZYNQ简介 (1)ZYNQ简介 ​ ZYNQ全称Zynq-7000 All Programmable SoC,是赛灵思公司(Xilinx)推出的新一代全可编程片上系统((APSoC)(全可编程指的是硬件和软件都可以编程…

ZYNQ简介

目录 1.ZYNQ简介 2.片上系统,板上系统,可编程片上系统,全可编程上系统 (1)板上系统 (2)片上系统(SOC) (3)可编程片上系统(SOPC&a…

【ZYNQ】从入门到秃头01 初识ZYNQ(PS和PL之间连接)

文章目录 从嵌入式Linux到ZYNQZYNQ简介PL简介常用的可编程逻辑器件:PL结构 PS简介AXIAXI4 StreamAXI4 ZYNQ芯片开发流程的简介学习ZYNQ要具备哪些技能 从嵌入式Linux到ZYNQ 之前的学习领域一直是ARM,从STM32到NXP iMX6, 从裸机开发到Linux操…

css-输入框和文本域样式调整

输入框去掉选中后的边框变化效果 选中后边框变化: 去掉变化效果方法:添加css属性- - - outline: none; 文本域去掉右下角拖拽图样 默认文本域右下角有个拖拽的图样,将鼠标移动到右下角可以进行拖拽实现放大缩小: 代码示例&#x…

HTML5-列表框、文本域和文件域

<!--下拉框&#xff0c;列表框selected 默认选择--><p>国家&#xff1a;<select name"列表名称" ><option value"china">中国</option><option value"us">美国</option><option value"eth&qu…

【多行文本输入框--文本域】(html,css)

<style>textarea{width: 300px;height: 300px;resize: none;/* resize:重新设置大小&#xff0c;vertical,horizontal,both,none */} </style> <body><div>多行文本输入框--文本域</div><div><!-- placeholder--提示文字 --><!--…

JTextArea:文本域组件

文本域与文本框的最大区别就是文本域允许用户输入多行文本信息。在 Swing 中使用 JTextArea 类实现一个文本域&#xff0c;其常用构造方法如下。 JTextArea()&#xff1a;创建一个默认的文本域。JTextArea(int rows,int columns)&#xff1a;创建一个具有指定行数和列数的文本…

html文本域

<!DOCTYPE <!DOCTYPE html><html><head><meta charset"utf-8"/><title>文本域</title></head><body>用户留言:<br/><form action"mailto:minriqq.com" name"invest" method"p…

文本域textarea

文本域 CreateTime--2017年5月23日15:12:08Author:Marydon 二、文本域 &#xff08;一&#xff09;语法 <textarea></textarea> &#xff08;二&#xff09;用法介绍 2.2.1 页面展示 内容一定要写在标签体内&#xff0c;即&#xff1a; <textarea>页面要展示…