0%

ZYNQ嵌入式之PS-XADC(基于PYNQ-Z2开发板)

本节简单演示了PL JATG接口读取XADC数据以及通过PS-XADC接口读取XADC数据的简单实例

XADC简介

  • Xilinx模拟混合信号模块,简称XADC,是一个硬核,即PL部分的硬核。它具有 JTAG 和 DRP 接口,用于访问 7 系列 FPGA 中的 XADC 状态和控制寄存器。 Zynq-7000 SoC 器件添加了第三个接口,即 PS-XADC 接口,供 PS 软件控制 XADC
  • XADC有两个独立的12位ADC可配置为同时对两个外部输入模拟通道进行采样
  • 模拟输入可支持1MSPS采样率下500 KHz的信号带宽

通过PL JATG读取XADC数据

  • vivado中的配置跟hello world一致

    image-20230926120452482


通过PS XADC获取XADC数据

  • 实验任务:通过PS-XADC接口,读取XADC测量的芯片温度、供电电压等信息,并通过串口打印出来

1.Vivado中的相关配置

  • 与hello world实验一样

    image-20230926121924206

2.Vitis中的代码编写

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
#include<iostream>
#include<xparameters.h>
#include<xadcps.h>
#include<xstatus.h>
#include<sleep.h>

using namespace std;

#define XADC_DEVICE_ID XPAR_XADCPS_0_DEVICE_ID //PS XADC器件ID


static int XAdcPolledPrintfExample(u16 XAdcDeviceId);
static int XAdcFractionToInt(float FloatNum);

static XAdcPs XAdcInst; //XADC驱动实例

int main(void)
{

while(1) // 每5S打印一次
{
cout<<"======================================"<<endl;
XAdcPolledPrintfExample(XADC_DEVICE_ID);
cout<<"************************************************************"<<endl;
usleep(5000000);
}

return 0;
}

int XAdcPolledPrintfExample(u16 XAdcDeviceId)
{
XAdcPs_Config *ConfigPtr;
u32 TempRawData; //温度 原始数据
u32 VccPintRawData; //PS 内核电压 原始数据
u32 VccPauxRawData; //PS 辅助电压 原始数据
u32 VccPdroRawData; //PS DDR电压 原始数据

u32 VccintRawData; //PL 内核电压 原始数据
u32 VccauxRawData; //PL 辅助电压 原始数据
u32 VccdroRawData; //PL BRAM电压 原始数据


float TempData; //温度
float VccPintData; //PS 内核电压
float VccPauxData; //PS 辅助电压
float MaxData;
float MinData;
float VccintData; //PL 内核电压
float VccauxData; //PL 辅助电压
float vccBRAM; //PL BRAM电压

XAdcPs *XAdcInstPtr = &XAdcInst;

//初始化XADC驱动
ConfigPtr = XAdcPs_LookupConfig(XAdcDeviceId);
XAdcPs_CfgInitialize(XAdcInstPtr, ConfigPtr,
ConfigPtr->BaseAddress);

/* 设置XADC操作模式为“默认安全模式”
* 在该模式下,XADC 会自动监测片上温度和电压传感器的数据,并将结果保存在状态寄存器中,
* 此时 XADC的操作与其他任何控制寄存器的设置无关 */
XAdcPs_SetSequencerMode(XAdcInstPtr, XADCPS_SEQ_MODE_SAFE);

//获取原始温度传感器数据,并转换成温度信息
TempRawData = XAdcPs_GetAdcData(XAdcInstPtr, XADCPS_CH_TEMP);
TempData = XAdcPs_RawToTemperature(TempRawData);
printf("芯片当前温度为: %0d.%03d ℃.\r\n", (int)(TempData), XAdcFractionToInt(TempData));

TempRawData = XAdcPs_GetMinMaxMeasurement(XAdcInstPtr, XADCPS_MAX_TEMP);
MaxData = XAdcPs_RawToTemperature(TempRawData);
printf("芯片最高温度为: %0d.%03d ℃. \r\n", (int)(MaxData), XAdcFractionToInt(MaxData));

TempRawData = XAdcPs_GetMinMaxMeasurement(XAdcInstPtr, XADCPS_MIN_TEMP);
MinData = XAdcPs_RawToTemperature(TempRawData & 0xFFF0);
printf("芯片最低温度为: %0d.%03d ℃. \r\n", (int)(MinData), XAdcFractionToInt(MinData));

//获取VCCPINT传感器数据,并转换成电压信息
VccPintRawData = XAdcPs_GetAdcData(XAdcInstPtr, XADCPS_CH_VCCPINT);
VccPintData = XAdcPs_RawToVoltage(VccPintRawData);
printf("\r\n当前VCCPINT为: %0d.%03d V. \r\n", (int)(VccPintData), XAdcFractionToInt(VccPintData));

VccPintRawData = XAdcPs_GetMinMaxMeasurement(XAdcInstPtr, XADCPS_MAX_VCCPINT);
MaxData = XAdcPs_RawToVoltage(VccPintRawData);
printf("最大VCCPINT为: %0d.%03d V. \r\n", (int)(MaxData), XAdcFractionToInt(MaxData));

VccPintRawData = XAdcPs_GetMinMaxMeasurement(XAdcInstPtr, XADCPS_MIN_VCCPINT);
MinData = XAdcPs_RawToVoltage(VccPintRawData);
printf("最小VCCPINT为: %0d.%03d V. \r\n", (int)(MinData), XAdcFractionToInt(MinData));

//获取VCCPAUX传感器数据,并转换成电压信息
VccPauxRawData = XAdcPs_GetAdcData(XAdcInstPtr, XADCPS_CH_VCCPAUX);
VccPauxData = XAdcPs_RawToVoltage(VccPauxRawData);
printf("\r\n当前VCCPAUX为: %0d.%03d V. \r\n", (int)(VccPauxData), XAdcFractionToInt(VccPauxData));

VccPauxRawData = XAdcPs_GetMinMaxMeasurement(XAdcInstPtr, XADCPS_MAX_VCCPAUX);
MaxData = XAdcPs_RawToVoltage(VccPauxRawData);
printf("最大VCCPAUX为: %0d.%03d V. \r\n", (int)(MaxData), XAdcFractionToInt(MaxData));


VccPauxRawData = XAdcPs_GetMinMaxMeasurement(XAdcInstPtr, XADCPS_MIN_VCCPAUX);
MinData = XAdcPs_RawToVoltage(VccPauxRawData);
printf("最小VCCPAUX为: %0d.%03d V. \r\n", (int)(MinData), XAdcFractionToInt(MinData));

//获取VCCPDRO传感器数据,并转换成电压信息
VccPdroRawData = XAdcPs_GetAdcData(XAdcInstPtr, XADCPS_CH_VCCPDRO);
VccPintData = XAdcPs_RawToVoltage(VccPdroRawData);
printf("\r\n当前VCCPDDRO为: %0d.%03d V. \r\n", (int)(VccPintData), XAdcFractionToInt(VccPintData));

VccPdroRawData = XAdcPs_GetMinMaxMeasurement(XAdcInstPtr, XADCPS_MAX_VCCPDRO);
MaxData = XAdcPs_RawToVoltage(VccPdroRawData);
printf("最大VCCPDDRO为: %0d.%03d V. \r\n", (int)(MaxData), XAdcFractionToInt(MaxData));

VccPdroRawData = XAdcPs_GetMinMaxMeasurement(XAdcInstPtr, XADCPS_MIN_VCCPDRO);
MinData = XAdcPs_RawToVoltage(VccPdroRawData);
printf("最小VCCPDDRO为: %0d.%03d V. \r\n", (int)(MinData), XAdcFractionToInt(MinData));

//获取VCCINT传感器数据,并转换成电压信息
VccintRawData = XAdcPs_GetAdcData(XAdcInstPtr, XADCPS_CH_VCCINT);
VccintData = XAdcPs_RawToVoltage(VccintRawData);
printf("\r\n当前VCCINT为: %0d.%03d V. \r\n",
(int)(VccintData), XAdcFractionToInt(VccintData));

VccintRawData = XAdcPs_GetMinMaxMeasurement(XAdcInstPtr,
XADCPS_MAX_VCCINT);
MaxData = XAdcPs_RawToVoltage(VccintRawData);
printf("最大VCCINT为: %0d.%03d V. \r\n",
(int)(MaxData), XAdcFractionToInt(MaxData));

VccintRawData = XAdcPs_GetMinMaxMeasurement(XAdcInstPtr,
XADCPS_MIN_VCCINT);
MinData = XAdcPs_RawToVoltage(VccintRawData);
printf("最小VCCINT为: %0d.%03d V. \r\n",
(int)(MinData), XAdcFractionToInt(MinData));


//获取VCCAUX传感器数据,并转换成电压信息
VccauxRawData = XAdcPs_GetAdcData(XAdcInstPtr, XADCPS_CH_VCCAUX);
VccauxData = XAdcPs_RawToVoltage(VccauxRawData);
printf("\r\n当前VCCAUX为: %0d.%03d V. \r\n",
(int)(VccauxData), XAdcFractionToInt(VccauxData));

VccauxRawData = XAdcPs_GetMinMaxMeasurement(XAdcInstPtr,
XADCPS_MAX_VCCAUX);
MaxData = XAdcPs_RawToVoltage(VccauxRawData);
printf("最大VCCAUX为: %0d.%03d V. \r\n",
(int)(MaxData), XAdcFractionToInt(MaxData));

VccauxRawData = XAdcPs_GetMinMaxMeasurement(XAdcInstPtr,
XADCPS_MIN_VCCAUX);
MinData = XAdcPs_RawToVoltage(VccauxRawData);
printf("最小VCCAUX为: %0d.%03d V. \r\n",
(int)(MinData), XAdcFractionToInt(MinData));


//获取VCCBRAM传感器数据,并转换成电压信息
VccdroRawData = XAdcPs_GetAdcData(XAdcInstPtr, XADCPS_CH_VBRAM);
vccBRAM = XAdcPs_RawToVoltage(VccdroRawData);
printf("\r\n当前VCCBRAM为: %0d.%03d V. \r\n",
(int)(vccBRAM), XAdcFractionToInt(vccBRAM));

VccdroRawData = XAdcPs_GetMinMaxMeasurement(XAdcInstPtr,
XADCPS_MAX_VBRAM);
MaxData = XAdcPs_RawToVoltage(VccdroRawData);
printf("最大VCCBRAM为: %0d.%03d V. \r\n",
(int)(MaxData), XAdcFractionToInt(MaxData));

VccdroRawData = XAdcPs_GetMinMaxMeasurement(XAdcInstPtr,
XADCPS_MIN_VBRAM);
MinData = XAdcPs_RawToVoltage(VccdroRawData);
printf("最小VCCBRAM为: %0d.%03d V. \r\n",
(int)(MinData), XAdcFractionToInt(MinData));



return 0;
}

int XAdcFractionToInt(float FloatNum)
{
float Temp;

Temp = FloatNum;
if (FloatNum < 0) {
Temp = -(FloatNum);
}

return( ((int)((Temp -(float)((int)Temp)) * (1000.0f))));
}

3.实验结果

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
Connected to COM4 at 115200
======================================
芯片当前温度为: 39.036 ℃.

芯片最高温度为: 39.505 ℃.

芯片最低温度为: 37.529 ℃.



当前VCCPINT为: 1.021 V.

最大VCCPINT为: 1.024 V.

最小VCCPINT为: 1.020 V.




当前VCCPAUX为: 1.797 V.

最大VCCPAUX为: 1.800 V.

最小VCCPAUX为: 1.795 V.



当前VCCPDDRO为: 1.493 V.

最大VCCPDDRO为: 1.496 V.

最小VCCPDDRO为: 1.486 V.



当前VCCINT为: 1.023 V.

最大VCCINT为: 1.025 V.

最小VCCINT为: 1.022 V.



当前VCCAUX为: 1.797 V.

最大VCCAUX为: 1.800 V.

最小VCCAUX为: 1.795 V.



当前VCCBRAM为: 1.023 V.

最大VCCBRAM为: 1.025 V.

最小VCCBRAM为: 1.022 V.

************************************************************
欢迎来到ssy的世界