10_XADC实验
任务: 通过 PS-XADC 接口,读取 XADC 测量的芯片温度、供电电压等信息,并通过串口 打印出来。
搭建系统
与“hello world”实验相同,只配置UART0外设
代码
#include "xparameters.h"
#include "xadcps.h"
#include "xstatus.h"
#include "stdio.h"
#include "xil_printf.h"
#include "sleep.h"
#define XADC_DEVICE_ID XPAR_XADCPS_0_DEVICE_ID //PS XADC器件ID
#define printf xil_printf /* Small foot-print printf function */
static int XAdcPolledPrintfExample(u16 XAdcDeviceId);
static int XAdcFractionToInt(float FloatNum);
static XAdcPs XAdcInst; //XADC驱动实例
int main(void)
{
while(1) // 每5S打印一次
{
printf("======================================\n");
XAdcPolledPrintfExample(XADC_DEVICE_ID);
printf("************************************************************\n");
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))));
}
串口输出
每5s输出一次结果
======================================
芯片当前温度为: 48.026 ℃.
芯片最高温度为: 48.641 ℃.
芯片最低温度为: 45.650 ℃.
当前VCCPINT为: 1.023 V.
最大VCCPINT为: 1.026 V.
最小VCCPINT为: 1.021 V.
当前VCCPAUX为: 1.804 V.
最大VCCPAUX为: 1.807 V.
最小VCCPAUX为: 1.802 V.
当前VCCPDDRO为: 1.495 V.
最大VCCPDDRO为: 1.498 V.
最小VCCPDDRO为: 1.487 V.
当前VCCINT为: 1.025 V.
最大VCCINT为: 1.026 V.
最小VCCINT为: 1.023 V.
当前VCCAUX为: 1.805 V.
最大VCCAUX为: 1.807 V.
最小VCCAUX为: 1.803 V.
当前VCCBRAM为: 1.024 V.
最大VCCBRAM为: 1.026 V.
最小VCCBRAM为: 1.023 V.
****************************************
操作中的问题
串口打印的数据,有时会莫名出现乱码。如:
当前VCCBRAM为: 1.495 V.
最大VCCBRAM为�� 1.498 V.
最小VCCBRAM为: 1.487 V.
可能的原因是波特率不稳定,详细见文章:
(184条消息) 串口输出乱码问题的解决方法汇总(持续更新):_「已注销」的博客-CSDN博客
但是如果出现的概率很小,可忽略。