学会Zynq(22)XADC测量片内温度与电源电压

本文将介绍如何在PS中调用Zynq内部的XADC模块进行片内温度和电源电压测量。先了解XADC的相关知识,再通过实例体会XADC的用法,学习XADC API函数的使用。

XADC介绍

XADC中文全称应该是“Xilinx模拟混合信号模块”,是FPGA中的一个硬核。在7系列FPGA中,XADC提供了DRP和JTAG接口,用于访问XADC的状态和控制寄存器。Zynq中添加了第三个接口,称作PS-XADC接口,PS通过此接口来控制XADC。使用XADC可以满足一定的模拟数据采集和设备监控需求。

XADC有组成部分有:

  • 两个12位、1MSPS的ADC,每个ADC有独立的跟踪和保持放大器;支持单极、双极、查分等多种模拟信号输入类型;1ms采样率,最高支持500kHz信号带宽。
  • 一个模拟多路复用器,最高支持17个外部模拟输入通道;在不需要额外封装引脚的情况下增加支持的外部通道的数量
  • 片上热传感器和电压传感器

XADC可以采用片内参考电路,监测片内温度和电源电压时可以无需外部有源器件。如果要实现ADC的全12位性能,还是需要外部加一个1.25V的参考电压IC。

XADC把最近的测量结果、最大值、最小值分别存储在专用寄存器中。我们可以自定义报警阈值,当温度或电源电压超过这个值时便会发出信号。据此,我们可以在程序中控制系统断电来保护芯片。

XADC的系统模块框图如下:


Zynq设计

Vivado中建立工程,配置好Zynq的MIO电压、DDR、串口。XADC模块位于PL部分,需要使用PL中的时钟。因此配置Zynq时钟时要将FCLK_CLK0视作XADC的工作时钟,我这里设置为100MHz。


添加XADC Wizard IP核,点击上方出现的run connection automation,Vivado会自动添加其它辅助模块,并完成连线。设计整体框图如下:


自动添加了两个子模块,Processor System Reset主要负责为整个处理器系统提供复位功能,包括处理器、互联网络和外设。AXI Interconnect主要完成AXI接口间的位宽、时钟或协议的转换。一般这两个模块都是根据系统自动添加的,只要大致了解其功能即可。

SDK程序设计

配置完成后导入到SDK中。使用XADC监测Zynq内部温度和电源电压,以串口方式输出。user_xadc.h文件代码如下:

#ifndef SRC_USER_XADC_H_
#define SRC_USER_XADC_H_

#include 
#include "sleep.h"
#include "xil_printf.h"
#include "xadcps.h"       //XADC设备的支持驱动程序

void XADC_Init(XAdcPs* XADCMonInst);
void XADC_Printf(XAdcPs* XADCInstPtr);

#endif /* SRC_USER_XADC_H_ */

user_xadc.c文件的代码如下:

main.c文件的代码如下:

#include "user_xadc.h"

static XAdcPs XADCInst;  //XADC

int main()
{
		XADC_Init(&XADCInst);

		while(1)
		{
			xil_printf("-------------XADC result-------------\r\n");
			XADC_Printf(&XADCInst);
			sleep(5);
		}
}

SDK Terminal中添加串口,运行程序,将看到每隔5s便打印一次Zynq内部温度和各种电压信息,包括原始数据“raw”和转换后的实际数据“real”。


相关API函数

1. XADC初始化

对XADC设备初始化操作和前面GPIO设备、中断设备、定时器设备的初始化过程一样,不再赘述。

接着使用XAdcPs_SelfTest函数对XADC设备进行自检,该函数先将XADC复位,向报警门限寄存器写一个值再读取进行比较,然后再次复位XADC。如果比较结果相同则返回XST_SUCCESS,否则返回XST_FAILURE,程序中可以根据自检函数的返回值判断XADC工作是否正常。

int XAdcPs_SelfTest(XAdcPs *InstancePtr)  //函数原型

2. XADC配置

之后使用4个函数依次设置XADC的工作模式。首先用XAdcPs_SetSequencerMode函数,设置通道序列器模式,一次只能选择一个模式。各模式的宏定义在xadcps.h文件中,这里设置为“单通道”模式。

void XAdcPs_SetSequencerMode(XAdcPs *InstancePtr, u8 SequencerMode)

使用XAdcPs_SetAlarmEnables函数设置是否使能报警输出,第二个参数为1表示启用,为0表示禁用。

void XAdcPs_SetAlarmEnables(XAdcPs *InstancePtr, u16 AlmEnableMask)

使用XAdcPs_SetSeqInputMode函数设置模拟输入模式,设置成功返回XST_SUCCESS,否则返回XST_FAILURE。

int XAdcPs_SetSeqInputMode(XAdcPs *InstancePtr, u32 InputModeChMask)

使用XAdcPs_ SetSeqChEnables函数设置启用哪些通道,设置成功返回XST_SUCCESS,否则返回XST_FAILURE。各通道的宏定义在xadcps.h文件中。

int XAdcPs_SetSeqChEnables(XAdcPs *InstancePtr, u32 ChEnableMask)

3. 数据采集与转换

使用XAdcPs_GetAdcData函数获取指定通道的ADC转换数据。设置的通道应该是0-6和13-31。通道7-9用于校准设备,无法获得与这三个通道相关的数据。

u16 XAdcPs_GetAdcData(XAdcPs *InstancePtr, u8 Channel)

使用两个宏定义XAdcPs_RawToVoltage和XAdcPs_RawToTemperature可以将XADC采集到的原始数据转换为电压(V)和温度(℃)。其等效的C语言函数接口为:

float XAdcPs_RawToTemperature(u32 AdcData);
float XAdcPs_RawToVoltage(u32 AdcData);

总结

XADC的使用算是比较复杂,本文只是简单的使用其测量了Zynq内部的温度和电源电压。XADC也是SPI中的一个中断源,还可以采集外部信号。熟练掌握XADC的使用,不仅需要编程能力,还要对其结构和工作原理有一定了解。

---------------------


文章来源:FPGADesigner的博客
*本文由作者授权转发,如需转载请联系作者本人

最新文章

最新文章