xilinx IP核提供了XADC核,XADC包含两个模数转换器(ADC)、一个模拟多路复用器、片内温度传感器和片内电源电压传感器和多个片外ADC模拟电压输入通道。我们可以利用这个模块监测芯片的温度、供电电压,也可以用来测量外部的模拟输入电压信号。
7系列的XADC IP核包括两个12位的模数转换器,转换速率可以达到1MSPS(每秒一百万次采样)。它带有片内温度和电源电压传感器,可以测量芯片工作时的温度和供电电压。用户可以设置报警阈值,用来检测温度过高或者供电电压异常等事件。除此之外,通过XADC IP核内部的模拟多路复用器,它支持最多17路外部模拟输入信号的测量,可配置为单极、双极和差分等信号类型。
1)左边红框圈1的,共十七组差分信号,这些端口也可接收单端信号,其中VP_0/N_0为一对专用的模拟差分输入,其他16对为复用的(不使用时可作为普通的数字IO管脚)。
2)最上边红框2,表明XADC模块也可采集片内传感器测量的芯片温度、供电电压等信息;
3)右边红框圈3,是两个12位的模数转换器。
XADC采集转换后的数据存储在状态寄存器的专用寄存器内,可由FPGA内部动态配置端口(DRP----Dynamic Reconfiguration Port)的16位同步读/写端口访问;
ADC的转换数据也可以由JTAG访问,当使用这种方式时,并不需要直接去例化XADC模块,如下图所示:
XADC提供了多种接口供外部模块访问,本此推文我们将使用cortex M3软核处理器和XADC的axi4lite接口,通过keil c编程来读取芯片的温度、片内电源电压、外部输入模拟电压等信息,系统原理图如下:
其中的XADC ip如下图,其配置说明见视频讲解:
相关keil c源码如下:
// XADC initialize
static XSysMon SysMonInst; //XADC
XSysMon_Config *ConfigPtr;
u32 TempRawData;
u32 VccAuxRawData;
u32 VccIntRawData;
u32 VccBRAMdata;
u32auxrawdata;
float TempData;
float VccAuxData;
float VccIntData;
float VBRAM;
float MaxData;
float MinData;
float aux04data;
float aux12data;
ConfigPtr = XSysMon_LookupConfig(XPAR_SYSMON_0_DEVICE_ID);
if (ConfigPtr == NULL) {
return XST_FAILURE;
}
XSysMon_CfgInitialize(&SysMonInst, ConfigPtr, ConfigPtr->BaseAddress);
//default mode
XSysMon_SetSequencerMode(&SysMonInst, XSM_SEQ_MODE_SAFE);
//enable channels
XSysMon_SetSeqChEnables(&SysMonInst,XSM_SEQ_CH_TEMP| //temperature
XSM_SEQ_CH_VCCINT | //vccint
XSM_SEQ_CH_VCCAUX| //vccaux
XSM_SEQ_CH_VBRAM | //VBRAM
XSM_SEQ_CH_AUX04 | //aux04
XSM_SEQ_CH_AUX12//aux12
);
//cycle mode
XSysMon_SetSequencerMode(&SysMonInst,XSM_SEQ_MODE_CONTINPASS);
while ( 1 )
{
。。。。。。。。。。。。。
//==================================================
TempRawData = XSysMon_GetAdcData(&SysMonInst, XSM_CH_TEMP);
TempData = XSysMon_RawToTemperature(TempRawData);
sprintf (debugStr,"\r\nThe Current Temperature is %0d.%03d Centigrades.\r\n",
(int)(TempData), SysMonFractionToInt(TempData));
print ( debugStr );
TempRawData = XSysMon_GetMinMaxMeasurement(&SysMonInst, XSM_MAX_TEMP);
MaxData = XSysMon_RawToTemperature(TempRawData);
sprintf (debugStr,"The Maximum Temperature is %0d.%03d Centigrades. \r\n",
(int)(MaxData), SysMonFractionToInt(MaxData));
print ( debugStr );
TempRawData = XSysMon_GetMinMaxMeasurement(&SysMonInst, XSM_MIN_TEMP);
MinData = XSysMon_RawToTemperature(TempRawData);
sprintf (debugStr,"The Minimum Temperature is %0d.%03d Centigrades. \r\n",
(int)(MinData), SysMonFractionToInt(MinData));
print ( debugStr );
VccIntRawData = XSysMon_GetAdcData(&SysMonInst, XSM_CH_VCCINT);
VccIntData = XSysMon_RawToVoltage(VccIntRawData);
sprintf (debugStr,"The Current VCCINT is %0d.%03d Volts. \r\n",
(int)(VccIntData), SysMonFractionToInt(VccIntData));
print ( debugStr );
VccAuxRawData = XSysMon_GetAdcData(&SysMonInst,XSM_CH_VCCAUX );
VccAuxData = XSysMon_RawToVoltage(VccAuxRawData);
sprintf (debugStr,"The Current VCCAUX is %0d.%03d Volts. \r\n",
(int)(VccAuxData), SysMonFractionToInt(VccAuxData));
print ( debugStr );
VccBRAMdata = XSysMon_GetAdcData(&SysMonInst,XSM_CH_VBRAM );
VBRAM = XSysMon_RawToVoltage(VccBRAMdata);
sprintf (debugStr,"The Current VBRAM is %0d.%03d Volts. \r\n",
(int)(VBRAM), SysMonFractionToInt(VBRAM));
print ( debugStr );
//--------------------------------------------------------
auxrawdata = XSysMon_GetAdcData(&SysMonInst,XSM_CH_AUX_MIN+4 );
aux04data = XSysMon_RawToVoltage(auxrawdata)/3.0;
sprintf (debugStr,"The Current aux04 is %0d.%03d Volts. \r\n",
(int)(aux04data), SysMonFractionToInt(aux04data));
print ( debugStr );
auxrawdata = XSysMon_GetAdcData(&SysMonInst,XSM_CH_AUX_MIN+12 );
aux12data = XSysMon_RawToVoltage(auxrawdata)/3.0;
sprintf (debugStr,"The Current aux12 is %0d.%03d Volts. \r\n",
(int)(aux12data), SysMonFractionToInt(aux12data));
print ( debugStr );
//==================================================
}
}
XADC的采样值如何转换为实际的物理量?可以参考见文档说明,如下截图:
视频讲解: