FPGA_ZYNQ_XADC

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档

文章目录

  • 前言
  • 一、ADC介绍
  • 二、使用步骤
    • 1.搭建FPGA BD工程
    • 1.1新建工程
    • 1.2搭建 FPGA BD 工程
    • 1.3生成bit文件导入硬件加载SDK
    • 2.新建SDK工程
    • 3.代码分析
  • 代码分析
  • 总体步骤:


前言

使用芯片内部 XADC 采集片上电压以及温度

一、ADC介绍

Xilinx 7 系列的 ADC 是一个双 12 位分辨率的而且每秒一兆(MSPS, 1 Mega sample per second)采样速率的模数转换器,是一种通用的、高精度的模数转换器,双通道的 ADC 支持单极和差分输入工作模式,其最多可支持 17路外部模拟输入通道。

FPGA_ZYNQ_XADC_第1张图片

由图可看到 ADC 分为 12 位的 A 和 B 两个其中
ADC A 可以对供电电压进行采样,供电电压包括 VCCINT、VCCAUX、VCCBRAM,其中 Zynq-7000 系列的芯片还支持对 VCCPINT、VCCPAUX 和 VCCO_DDR 的采样,还包括温度的采样和外部模拟输入的采样。ADC B 只能对外部模拟输入进行采样转换

二、使用步骤

1.搭建FPGA BD工程

1.1新建工程

FPGA_ZYNQ_XADC_第2张图片
FPGA_ZYNQ_XADC_第3张图片

1.2搭建 FPGA BD 工程

创建BD文件,添加并配置ZYNQ处理器
在这里插入图片描述
FPGA_ZYNQ_XADC_第4张图片在这里插入图片描述
FPGA_ZYNQ_XADC_第5张图片
在这里插入图片描述
把PS的时钟可以接入PL部分,连接FCLK_CLK0和M_AXI_GPO_ACLK
FPGA_ZYNQ_XADC_第6张图片双击ZYNQ CPU IP,对其进行设置,使其对应我们的硬件设置,否则SDK的程序会崩溃。
时钟配置
FPGA_ZYNQ_XADC_第7张图片
内存配置
MZ7XA-7020、MZ7XB-7020、MZ702N、MZ702P、MZ7015、MZ7035、MZ7100 的内存型号为 1024GB,选取内存型号MT41K256M16RE-125
MZ7XA-7010mini 的内存为 512MB,选取内存型号:MT41K128M16 JT-125
FPGA_ZYNQ_XADC_第8张图片
设置外设接口,Bank0 IO Voltage为LVCMOS3.3V,Bank1 IO Voltage为LVCMOS1.8V
QSPI FLASH配置:
FPGA_ZYNQ_XADC_第9张图片串口配置:
在这里插入图片描述
添加XADC的IP到BD文件
FPGA_ZYNQ_XADC_第10张图片双击XADC进行配置
采样方式采用 AXI4Lite,连续采样模式,Channel Sequencer 模式,DCLK 设置 100M
FPGA_ZYNQ_XADC_第11张图片
勾选采集信号
VCCINT:内部 PL 核心电压
VREFP:XADC 正参考电压
VREFN:XADC 负参考电压
VCCBram:PL BRAM 电压
VCCPInt:PS 内部核心电压
VCCPAux:PS 辅助电压
VCCDdr:DDR RAM 的工作电压FPGA_ZYNQ_XADC_第12张图片
在这里插入图片描述

右击 system.bd, 单击Generate Output Products
FPGA_ZYNQ_XADC_第13张图片
FPGA_ZYNQ_XADC_第14张图片
右击system.bd 选择 Create HDL Wrapper
FPGA_ZYNQ_XADC_第15张图片

1.3生成bit文件导入硬件加载SDK

生成 Bit 文件。导出到硬件: FileExport HardwareInclude bitstream
加载 SDK:FileLaunch SDKOK

2.新建SDK工程

选择 File->New->Application Project
FPGA_ZYNQ_XADC_第16张图片
将例程主函数复制到工程工程函数

代码如下(示例):

/*
 * main.c
 *
 *  Created on: 2016年6月25日
 *      Author: Administrator
 */
#include 
//#include "platform.h"
#include "xadcps.h"
#include "xil_types.h"
#define XPAR_AXI_XADC_0_DEVICE_ID 0

//void print(char *str);

static XAdcPs XADCMonInst;

int main()
{

  XAdcPs_Config *ConfigPtr;
  XAdcPs *XADCInstPtr = &XADCMonInst;

  //status of initialisation
  int Status_ADC;

  //temperature readings
  u32 TempRawData;
  float TempData;

  //Vcc Int readings
  u32 VccIntRawData;
  float VccIntData;

  //Vcc Aux readings
  u32 VccAuxRawData;
  float VccAuxData;

  //Vbram readings
  u32 VBramRawData;
  float VBramData;

  //VccPInt readings
  u32 VccPIntRawData;
  float VccPIntData;

  //VccPAux readings
  u32 VccPAuxRawData;
  float VccPAuxData;

  //Vddr readings
  u32 VDDRRawData;
  float VDDRData;

 // init_platform();

    //printf("Adam Edition MicroZed Using Vivado How To Printf \n\r");

    //XADC initilization

     ConfigPtr = XAdcPs_LookupConfig(XPAR_AXI_XADC_0_DEVICE_ID);
       if (ConfigPtr == NULL) {
           return XST_FAILURE;
         }

       Status_ADC = XAdcPs_CfgInitialize(XADCInstPtr,ConfigPtr,ConfigPtr->BaseAddress);
       if(XST_SUCCESS != Status_ADC){
           print("ADC INIT FAILED\n\r");
           return XST_FAILURE;
        }

       //self test
       Status_ADC = XAdcPs_SelfTest(XADCInstPtr);
     if (Status_ADC != XST_SUCCESS) {
       return XST_FAILURE;
     }

		//stop sequencer
		XAdcPs_SetSequencerMode(XADCInstPtr,XADCPS_SEQ_MODE_SINGCHAN);

		//disable alarms
		XAdcPs_SetAlarmEnables(XADCInstPtr, 0x0);

		//configure sequencer to just sample internal on chip parameters
		XAdcPs_SetSeqInputMode(XADCInstPtr, XADCPS_SEQ_MODE_SAFE);


		//configure the channel enables we want to monitor

		XAdcPs_SetSeqChEnables(XADCInstPtr,XADCPS_CH_TEMP|XADCPS_CH_VCCINT|XADCPS_CH_VCCAUX|XADCPS_CH_VBRAM|XADCPS_CH_VCCPINT| XADCPS_CH_VCCPAUX|XADCPS_CH_VCCPDRO);

		while(1)
		{
			TempRawData = XAdcPs_GetAdcData(XADCInstPtr, XADCPS_CH_TEMP);
			TempData = XAdcPs_RawToTemperature(TempRawData);
			printf("Raw Temp %lu Real Temp %f \n\r", TempRawData, TempData);

			VccIntRawData= XAdcPs_GetAdcData(XADCInstPtr, XADCPS_CH_VCCINT);
			VccIntData = XAdcPs_RawToVoltage(VccIntRawData);
			printf("Raw VccInt %lu Real VccInt %f \n\r", VccIntRawData,VccIntData);

			VccAuxRawData = XAdcPs_GetAdcData(XADCInstPtr, XADCPS_CH_VCCAUX);
			VccAuxData = XAdcPs_RawToVoltage(VccAuxRawData);
			printf("Raw VccAux %lu Real VccAux %f \n\r", VccAuxRawData,VccAuxData);


			VBramRawData = XAdcPs_GetAdcData(XADCInstPtr, XADCPS_CH_VBRAM);
			VBramData = XAdcPs_RawToVoltage(VBramRawData);
			printf("Raw VccBram %lu Real VccBram %f \n\r", VBramRawData, VBramData);

			VccPIntRawData = XAdcPs_GetAdcData(XADCInstPtr, XADCPS_CH_VCCPINT);
			VccPIntData = XAdcPs_RawToVoltage(VccPIntRawData);
			printf("Raw VccPInt %lu Real VccPInt %f \n\r", VccPIntRawData, VccPIntData);

			VccPAuxRawData = XAdcPs_GetAdcData(XADCInstPtr, XADCPS_CH_VCCPAUX);
			VccPAuxData = XAdcPs_RawToVoltage(VccPAuxRawData);
			printf("Raw VccPAux %lu Real VccPAux %f \n\r", VccPAuxRawData, VccPAuxData);

			VDDRRawData = XAdcPs_GetAdcData(XADCInstPtr, XADCPS_CH_VCCPDRO);
			VDDRData = XAdcPs_RawToVoltage(VDDRRawData);
			printf("Raw VccDDR %lu Real VccDDR %f \n\r", VDDRRawData, VDDRData);
		 }

		return 0;
}



3.代码分析

代码如下(示例):

data = pd.read_csv(
    'https://labfile.oss.aliyuncs.com/courses/1283/adult.data.csv')
print(data.head())

该处使用的url网络请求的数据。


代码分析

在系统查找,是否有这个设备的定义
  ConfigPtr = XAdcPs_LookupConfig(XPAR_AXI_XADC_0_DEVICE_ID);
       if (ConfigPtr == NULL) {
           return XST_FAILURE;
         }
将传入的ID参数与xilinx头文件中已定义的XADC的设备ID进行相等判断
如果一致将XAdcPs_ConfigTable地址返回,否则返回空
XAdcPs_Config *XAdcPs_LookupConfig(u16 DeviceId)
{
	XAdcPs_Config *CfgPtr = NULL;
	u32 Index;

	for (Index=0; Index < 1; Index++) {
		if (XAdcPs_ConfigTable[Index].DeviceId == DeviceId) {
			CfgPtr = &XAdcPs_ConfigTable[Index];
			break;
		}
	}

	return CfgPtr;
}
设备初始化
       Status_ADC = XAdcPs_CfgInitialize(XADCInstPtr,ConfigPtr,ConfigPtr->BaseAddress);
       if(XST_SUCCESS != Status_ADC){
           print("ADC INIT FAILED\n\r");
           return XST_FAILURE;
        }
采样前自检
       Status_ADC = XAdcPs_SelfTest(XADCInstPtr);
     if (Status_ADC != XST_SUCCESS) {
       return XST_FAILURE;
     }

停止定序器并关闭警告
		XAdcPs_SetSequencerMode(XADCInstPtr,XADCPS_SEQ_MODE_SINGCHAN);
		XAdcPs_SetAlarmEnables(XADCInstPtr, 0x0);
复位定序器并设为输入模式,使能采样通道
XAdcPs_SetSeqInputMode(XADCInstPtr, XADCPS_SEQ_MODE_SAFE);		XAdcPs_SetSeqChEnables(XADCInstPtr,XADCPS_CH_TEMP|XADCPS_CH_VCCINT|XADCPS_CH_VCCAUX|XADCPS_CH_VBRAM|XADCPS_CH_VCCPINT| XADCPS_CH_VCCPAUX|XADCPS_CH_VCCPDRO);
最后通过XAdcPs_GetAdcData获取对应值,库中有对应数值转换函数
以获取温度为例
		TempRawData = XAdcPs_GetAdcData(XADCInstPtr, XADCPS_CH_TEMP);
			TempData = XAdcPs_RawToTemperature(TempRawData);
在库中有#define XAdcPs_RawToTemperature(AdcData)				\
	((((float)(AdcData)/65536.0f)/0.00198421639f ) - 273.15f)

总体步骤:

1,查询id
2,初始化设备
3,关闭定定序器
4,关闭报警
5,复位定序器,设为输入模式
6,使能采样通道
7,获取采样值

你可能感兴趣的:(fpga)