本文将介绍如何在PS中调用Zynq内部的XADC模块进行片内温度和电源电压测量。先了解XADC的相关知识,再通过实例体会XADC的用法,学习XADC API函数的使用。
<font style="line-height: 40px;" color="red"><strong>XADC介绍</strong></font>
XADC中文全称应该是“Xilinx模拟混合信号模块”,是FPGA中的一个硬核。在7系列FPGA中,XADC提供了DRP和JTAG接口,用于访问XADC的状态和控制寄存器。Zynq中添加了第三个接口,称作PS-XADC接口,PS通过此接口来控制XADC。使用XADC可以满足一定的模拟数据采集和设备监控需求。
XADC有组成部分有:
<ul><li>两个12位、1MSPS的ADC,每个ADC有独立的跟踪和保持放大器;支持单极、双极、查分等多种模拟信号输入类型;1ms采样率,最高支持500kHz信号带宽。
<li>一个模拟多路复用器,最高支持17个外部模拟输入通道;在不需要额外封装引脚的情况下增加支持的外部通道的数量</li>
<li>片上热传感器和电压传感器</li></ul>
XADC可以采用片内参考电路,监测片内温度和电源电压时可以无需外部有源器件。如果要实现ADC的全12位性能,还是需要外部加一个1.25V的参考电压IC。
XADC把最近的测量结果、最大值、最小值分别存储在专用寄存器中。我们可以自定义报警阈值,当温度或电源电压超过这个值时便会发出信号。据此,我们可以在程序中控制系统断电来保护芯片。
XADC的系统模块框图如下:
<center><img src="http://xilinx.eetrend.com/files/2019-09/%E5%8D%9A%E5%AE%A2/100044985-79…; alt=""></center><br>
<font style="line-height: 40px;" color="red"><strong>Zynq设计</strong></font>
Vivado中建立工程,配置好Zynq的MIO电压、DDR、串口。XADC模块位于PL部分,需要使用PL中的时钟。因此配置Zynq时钟时要将FCLK_CLK0视作XADC的工作时钟,我这里设置为100MHz。
<center><img src="http://xilinx.eetrend.com/files/2019-09/%E5%8D%9A%E5%AE%A2/100044985-79…; alt=""></center><br>
添加XADC Wizard IP核,点击上方出现的run connection automation,Vivado会自动添加其它辅助模块,并完成连线。设计整体框图如下:
<center><img src="http://xilinx.eetrend.com/files/2019-09/%E5%8D%9A%E5%AE%A2/100044985-79…; alt=""></center><br>
自动添加了两个子模块,Processor System Reset主要负责为整个处理器系统提供复位功能,包括处理器、互联网络和外设。AXI Interconnect主要完成AXI接口间的位宽、时钟或协议的转换。一般这两个模块都是根据系统自动添加的,只要大致了解其功能即可。
<font style="line-height: 40px;" color="red"><strong>SDK程序设计</strong></font>
配置完成后导入到SDK中。使用XADC监测Zynq内部温度和电源电压,以串口方式输出。user_xadc.h文件代码如下:
<pre>#ifndef SRC_USER_XADC_H_
#define SRC_USER_XADC_H_
#include <stdio.h>
#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_ */</pre>
user_xadc.c文件的代码如下:
<embed src="http://xilinx.eetrend.com/files/2019-09/%E5%8D%9A%E5%AE%A2/100044985-79…; width="600" height="480" />
main.c文件的代码如下:
<pre>#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);
}
}</pre>
SDK Terminal中添加串口,运行程序,将看到每隔5s便打印一次Zynq内部温度和各种电压信息,包括原始数据“raw”和转换后的实际数据“real”。
<center><img src="http://xilinx.eetrend.com/files/2019-09/%E5%8D%9A%E5%AE%A2/100044985-79…; alt=""></center><br>
<font style="line-height: 40px;" color="red"><strong>相关API函数</strong></font>
<font color="#FD8900">1. XADC初始化</font>
对XADC设备初始化操作和前面GPIO设备、中断设备、定时器设备的初始化过程一样,不再赘述。
接着使用XAdcPs_SelfTest函数对XADC设备进行自检,该函数先将XADC复位,向报警门限寄存器写一个值再读取进行比较,然后再次复位XADC。如果比较结果相同则返回XST_SUCCESS,否则返回XST_FAILURE,程序中可以根据自检函数的返回值判断XADC工作是否正常。
<pre>int XAdcPs_SelfTest(XAdcPs *InstancePtr) //函数原型</pre>
<font color="#FD8900">2. XADC配置</font>
之后使用4个函数依次设置XADC的工作模式。首先用XAdcPs_SetSequencerMode函数,设置通道序列器模式,一次只能选择一个模式。各模式的宏定义在xadcps.h文件中,这里设置为“单通道”模式。
<pre>void XAdcPs_SetSequencerMode(XAdcPs *InstancePtr, u8 SequencerMode)</pre>
使用XAdcPs_SetAlarmEnables函数设置是否使能报警输出,第二个参数为1表示启用,为0表示禁用。
<pre>void XAdcPs_SetAlarmEnables(XAdcPs *InstancePtr, u16 AlmEnableMask)</pre>
使用XAdcPs_SetSeqInputMode函数设置模拟输入模式,设置成功返回XST_SUCCESS,否则返回XST_FAILURE。
<pre>int XAdcPs_SetSeqInputMode(XAdcPs *InstancePtr, u32 InputModeChMask)</pre>
使用XAdcPs_ SetSeqChEnables函数设置启用哪些通道,设置成功返回XST_SUCCESS,否则返回XST_FAILURE。各通道的宏定义在xadcps.h文件中。
<pre>int XAdcPs_SetSeqChEnables(XAdcPs *InstancePtr, u32 ChEnableMask)</pre>
<font color="#FD8900">3. 数据采集与转换</font>
使用XAdcPs_GetAdcData函数获取指定通道的ADC转换数据。设置的通道应该是0-6和13-31。通道7-9用于校准设备,无法获得与这三个通道相关的数据。
<pre>u16 XAdcPs_GetAdcData(XAdcPs *InstancePtr, u8 Channel)</pre>
使用两个宏定义XAdcPs_RawToVoltage和XAdcPs_RawToTemperature可以将XADC采集到的原始数据转换为电压(V)和温度(℃)。其等效的C语言函数接口为:
<pre>float XAdcPs_RawToTemperature(u32 AdcData);
float XAdcPs_RawToVoltage(u32 AdcData);</pre>
<font style="line-height: 40px;"><strong>总结</strong></font>
XADC的使用算是比较复杂,本文只是简单的使用其测量了Zynq内部的温度和电源电压。XADC也是SPI中的一个中断源,还可以采集外部信号。熟练掌握XADC的使用,不仅需要编程能力,还要对其结构和工作原理有一定了解。
---------------------
<h3><font color="red"><body>
文章来源:<a href="https://blog.csdn.net/FPGADesigner">FPGADesigner</a>的博客 <br />
*本文由作者授权转发,如需转载请联系作者本人
</body>
</font></h3>