1 实验任务
本实验任务是通过PS侧的XADC接口,读取PL侧的XADC硬核测量的芯片温度、供电电压等信息, 并通过串口打印出来。
2 系统框图
3 硬件设计
3.1 Block Design
- 添加ZYNQ7 Processing System IP核
- (1)在Peripheral I/O页面
- 1)勾选UART
- 2)正确选择Bank 0和Bank 1的电压
- (2)在DDR Configuration页面
- 1)DDR Controller Configuration下,合理配置Memory Type、Memory Part和Bus Width等参数
- (1)在Peripheral I/O页面
3.2 注意事项
- 将XADC配置为默认安全模式(Default Safe Mode),在该模式下:
- (1)Channel Selection:详见ug480的Table 4-3
- (2)Channel Averaging :默认16
- (3)Channel Analog-Input Mode :默认Unipolar
- (4)Channel Settling Time :默认4 XADCCLK
- (5)ALM[7:0] Outputs:默认Disabled
- (6)OT Output:默认Enabled
- (7)注意:在默认安全模式下,(1)~(4)设置不受XADC控制寄存器设置的影响(The XADC operates independently of any other control register settings in this mode.)
- 1)通过XSysMon_SetSeqChEnables函数禁用所有通道后,用Vivado Hardware Manager抓信号发现,XADC依然按照Table 4-3所示的通道顺序进行采样并转换
- 个人建议:
- (1)在PL侧例化一个XADC IP核,完成基本配置
- (2)在PS侧初始化XADC实例后,使用API函数获取温度和电压值即可
- 时序图:如下图所示,注意
- (1)CHANNEL表示上一个已转换完成的通道,而不是当前正在转换的通道
- (2)EOC表示CHANNEL通道的转换结果已写入寄存器
- (3)EOS在整个序列的最后一个通道的转换结果写入寄存器后和EOC同步拉高
- (4)08是校验通道,周期略长
4 软件设计
4.1 注意事项
无。
4.2 工程源码
/***************************** Include Files ********************************/
#include "stdio.h"
#include "xparameters.h"
#include "xadcps.h"
#include "sleep.h"
/************************** Constant Definitions ****************************/
#define XADC_DEVICE_ID XPAR_XADCPS_0_DEVICE_ID
/**************************** Type Definitions ******************************/
/***************** Macros (Inline Functions) Definitions ********************/
/************************** Function Prototypes *****************************/
int XadcInit(XAdcPs* XadcInstPtr);
/************************** Variable Definitions ****************************/
XAdcPs XadcInst;
/****************************************************************************/
int main()
{
//
int Status;
u32 TempRawData; // 温度 原始数据
u32 VccPintRawData; // PS侧内核电压 原始数据
u32 VccPauxRawData; // PS侧辅助电压 原始数据
u32 VccoDdrRawData; // PS侧DDR电压 原始数据
u32 VccIntRawData; // PL侧内核电压 原始数据
u32 VccAuxRawData; // PL侧辅助电压 原始数据
u32 VccBramRawData; // PL侧BRAM电压 原始数据
float TempRealData; // 温度 真实数据
float VccPintRealData; // PS侧内核电压 真实数据
float VccPauxRealData; // PS侧辅助电压 真实数据
float VccoDdrRealData; // PS侧DDR电压 真实数据
float VccIntRealData; // PL侧内核电压 真实数据
float VccAuxRealData; // PL侧辅助电压 真实数据
float VccBramRealData; // PL侧BRAM电压 真实数据
//
printf("PS XADC Test.\n");
//
Status = XadcInit(&XadcInst);
if (Status == XST_FAILURE) {
printf("Error : ps xadc initialization failed.\n");
return XST_FAILURE;
}
//
while(1) {
//
sleep(5);
//
printf("\n");
// 获取温度
TempRawData = XAdcPs_GetAdcData(&XadcInst, XADCPS_CH_TEMP);
TempRealData = XAdcPs_RawToTemperature(TempRawData);
printf("温度 = %f C.\n", TempRealData);
// 获取PS侧内核电压
VccPintRawData = XAdcPs_GetAdcData(&XadcInst, XADCPS_CH_VCCPINT);
VccPintRealData = XAdcPs_RawToVoltage(VccPintRawData);
printf("PS侧内核电压\t\t= %.3f V.\n", VccPintRealData);
// 获取PS侧辅助电压
VccPauxRawData = XAdcPs_GetAdcData(&XadcInst, XADCPS_CH_VCCPAUX);
VccPauxRealData = XAdcPs_RawToVoltage(VccPauxRawData);
printf("PS侧辅助电压\t\t= %.3f V.\n", VccPauxRealData);
// 获取PS侧DDR电压
VccoDdrRawData = XAdcPs_GetAdcData(&XadcInst, XADCPS_CH_VCCPDRO);
VccoDdrRealData = XAdcPs_RawToVoltage(VccoDdrRawData);
printf("PS侧DDR电压\t\t= %.3f V.\n", VccoDdrRealData);
// 获取PL侧内核电压
VccIntRawData = XAdcPs_GetAdcData(&XadcInst, XADCPS_CH_VCCINT);
VccIntRealData = XAdcPs_RawToVoltage(VccIntRawData);
printf("PL侧内核电压\t\t= %.3f V.\n", VccIntRealData);
// 获取PL侧辅助电压
VccAuxRawData = XAdcPs_GetAdcData(&XadcInst, XADCPS_CH_VCCAUX);
VccAuxRealData = XAdcPs_RawToVoltage(VccAuxRawData);
printf("PL侧辅助电压\t\t= %.3f V.\n", VccAuxRealData);
// 获取PL侧BRAM电压
VccBramRawData = XAdcPs_GetAdcData(&XadcInst, XADCPS_CH_VBRAM);
VccBramRealData = XAdcPs_RawToVoltage(VccBramRawData);
printf("PL侧BRAM电压\t= %.3f V.\n", VccBramRealData);
}
//
return XST_SUCCESS;
}
/****************************************************************************/
int XadcInit(XAdcPs* XadcInstPtr)
{
//
int Status;
XAdcPs_Config* XadcConfigPtr;
//
XadcConfigPtr = XAdcPs_LookupConfig(XPAR_XADCPS_0_DEVICE_ID);
if (XadcConfigPtr == NULL) {
return XST_FAILURE;
}
Status = XAdcPs_CfgInitialize(XadcInstPtr, XadcConfigPtr, XadcConfigPtr->BaseAddress);
if (Status != XST_SUCCESS) {
return XST_FAILURE;
}
//
XAdcPs_SetSequencerMode(XadcInstPtr, XADCPS_SEQ_MODE_SAFE);
//
return XST_SUCCESS;
}