上图所示,XADC 属于 PL部分的资源
XADC是一种硬逻辑实现,位于PL功率域。PS- xadc接口是PS的一部分,可以被PS APU访问,而不需要对PL进行编程。PL必须上电才能配置PS-XADC接口、使用PL- jtag或DRP接口以及操作XADC。
上面的机构图能够很清楚的表达XADC的互联结构和接口。
PS有两个接口可以访问XADC,一个是CPU通过APB ARM 的高速外设总线访问PS-XADC接口通过串行数据访问XADC。一个是AXI GP,必须通过AXI XADC IP Core访问,MISC高速接口。
JTAG和ABP接口公用通道,对XADC进行访问。
XADC可以采集的信号有内部温度传感器,内部电压信号。通过PL PIN接入的外部电压信号,PL PIN的指定需要PL 侧的配置(引脚分配就会产生Bitstream文件)。
XADC内部框图,有两个ADC 转换器,通过多路复用器采集不同端口的电压。
芯片硅片温度传感器和内部电源都连接到了ADC A上。ADC A/B通过复用器连接到外部模拟输入。
转换结果都存储在 Status Registers 中,64*16bit,通过DRP接口只读。
控制寄存器是可读可写通过DRP接口访问。
所有XADC专用引脚都位于BANK 0中 _0后缀的引脚
只要是ADC就必须关注参考电压。
Vccadc 是ADC转换器内核的供电电源,使用Vccaux 1.8v供电。
参考电压的供给可以选择片外,1.25V供电,精度和温度偏移的性能可以做到很好。
右图是使用内部参考电压,需要把Vrefp接地。
UG480 P16 介绍了ADC相关引脚的说明
电源和地主要是ADC转换器的供电引脚,就算没有使用XADC也应该确保连接上1.8和地。
参考电压如上图所示
Xilinx 官方开发板ZC702
参考电压通过REF3012基准电压芯片提供。
模拟电压输入引脚如下所示
ZC702
采样模式 有很多种,大体和MCU 片载ADC一样。
在开发XADC前,梳理一偏基本思路
1.XADC同普通ADC一样只是具有特殊的接口
2.XADC供电电源和参考电压按照UG480 进行配置
3.了解硬件电路板上,XADC的电路连接情况。
然后开始XADC的软件开发
如前所述,不需要在设计中实例化XADC来访问片上监视功能。但是,如果XADC在设计中没有实例化,那么访问该信息的唯一方法是通过JTAG测试访问端口(TAP)。为了允许从FPGA逻辑访问状态寄存器(测量结果),必须实例化XADC
XADC 实验
main函数部分
int main(void)
{
int Status;
/*
* Run the polled example, specify the Device ID that is
* generated in xparameters.h.
*/
Status = XAdcPolledPrintfExample(XADC_DEVICE_ID);
if (Status != XST_SUCCESS) {
xil_printf("adcps polled printf Example Failed\r\n");
return XST_FAILURE;
}
xil_printf("Successfully ran adcps polled printf Example\r\n");
return XST_SUCCESS;
}
获取XADC实体地址 XAdcInstPtr
/*
* Initialize the XAdc driver.
*/
ConfigPtr = XAdcPs_LookupConfig(XAdcDeviceId);
if (ConfigPtr == NULL) {
return XST_FAILURE;
}
XAdcPs_CfgInitialize(XAdcInstPtr, ConfigPtr,
ConfigPtr->BaseAddress);
/*
* Self Test the XADC/ADC device
*/
Status = XAdcPs_SelfTest(XAdcInstPtr);
if (Status != XST_SUCCESS) {
return XST_FAILURE;
}
设置ADC的采样工作模式
/*
* Disable the Channel Sequencer before configuring the Sequence
* registers.
*/
XAdcPs_SetSequencerMode(XAdcInstPtr, XADCPS_SEQ_MODE_SAFE);
/**
* @name Channel Sequencer Modes of operation
* @{
*/
#define XADCPS_SEQ_MODE_SAFE 0 /**< Default Safe Mode */
#define XADCPS_SEQ_MODE_ONEPASS 1 /**< Onepass through Sequencer */
#define XADCPS_SEQ_MODE_CONTINPASS 2 /**< Continuous Cycling Sequencer */
#define XADCPS_SEQ_MODE_SINGCHAN 3 /**< Single channel -No Sequencing */
#define XADCPS_SEQ_MODE_SIMUL_SAMPLING 4 /**< Simultaneous sampling */
#define XADCPS_SEQ_MODE_INDEPENDENT 8 /**< Independent mode */
获取通道ADC值,下面看到有内部通道,还有外部16~31 通道
TempRawData = XAdcPs_GetAdcData(XAdcInstPtr, XADCPS_CH_TEMP);
/**
* @name Indexes for the different channels.
* @{
*/
#define XADCPS_CH_TEMP 0x0 /**< On Chip Temperature */
#define XADCPS_CH_VCCINT 0x1 /**< VCCINT */
#define XADCPS_CH_VCCAUX 0x2 /**< VCCAUX */
#define XADCPS_CH_VPVN 0x3 /**< VP/VN Dedicated analog inputs */
#define XADCPS_CH_VREFP 0x4 /**< VREFP */
#define XADCPS_CH_VREFN 0x5 /**< VREFN */
#define XADCPS_CH_VBRAM 0x6 /**< On-chip VBRAM Data Reg, 7 series */
#define XADCPS_CH_SUPPLY_CALIB 0x07 /**< Supply Calib Data Reg */
#define XADCPS_CH_ADC_CALIB 0x08 /**< ADC Offset Channel Reg */
#define XADCPS_CH_GAINERR_CALIB 0x09 /**< Gain Error Channel Reg */
#define XADCPS_CH_VCCPINT 0x0D /**< On-chip PS VCCPINT Channel , Zynq */
#define XADCPS_CH_VCCPAUX 0x0E /**< On-chip PS VCCPAUX Channel , Zynq */
#define XADCPS_CH_VCCPDRO 0x0F /**< On-chip PS VCCPDRO Channel , Zynq */
#define XADCPS_CH_AUX_MIN 16 /**< Channel number for 1st Aux Channel */
#define XADCPS_CH_AUX_MAX 31 /**< Channel number for Last Aux channel */
后面的部分没有什么好讲解的。