当前位置:   article > 正文

【JokerのZYNQ7020】XADC。_zynq7020 xadc

zynq7020 xadc

软件环境:vivado 2017.4        硬件平台:XC7Z020 


 

手册ug480_7Series_XADC,由上图可见,右边红框圈的,ZYNQ的XADC模块包括2个12bit 1MSPS的模数转换器;左边红框圈的,共十七组信号,都分P端N端,也就是差分信号的两端,单端当然也可接受;最上边红框,意味着XADC模块也可采集片上传感器测量到的片上包括芯片温度、供电电压等信息;最终这些测量转换数据存储在状态寄存器的专用寄存器内,可由FPGA内部动态配置端口(DRP ----Dynamic Reconfiguration Port)的16位同步读/写端口访问。ADC的转换数据也可以由JTAG访问,当使用这种方式时,并不需要直接去例化XADC模块,因为这是一个已经存在与FPGA JTAG结构的专用接口,此时因为没有在设计中直接例化XADC模块,故XADC模块工作在一种预先定义好的模式即缺省模式,此模式下XADC模块专用于监视芯片上的供电电压和芯片温度。

其片上可采集的参数主要如下,这次例程就是针对这些片上数据进行XADC采集实验。

 


Vivado 2017.4 Create Block Design后,添加ZYNQ7 Processing system和XADC Wizard。

打开XADC Wizard模块设置,Basic选项卡下,选Channel Sequencer。

Channel Swquencer选项卡下,勾选要测试的数据量。

然后自动连线, Generate the output products,Create a HDL wrapper,Generate Bitstream,Export Hardware(注意勾选include biestream),最后launch SDK进行测试。

SDK中new application然后添加如下测试代码。

  1. #include <stdio.h>
  2. #include "xadcps.h"
  3. #include "xil_types.h"
  4. #define XPAR_AXI_XADC_0_DEVICE_ID 0
  5. static XAdcPs XADCMonInst;
  6. int main()
  7. {
  8. XAdcPs_Config *ConfigPtr;
  9. XAdcPs *XADCInstPtr = &XADCMonInst;
  10. //status of initialisation
  11. int Status_ADC;
  12. /********************芯片温度********************/
  13. u32 TempRawData;
  14. float TempData;
  15. /********************内部PL核心电压********************/
  16. u32 VccIntRawData;
  17. float VccIntData;
  18. /********************辅助PL电压********************/
  19. u32 VccAuxRawData;
  20. float VccAuxData;
  21. /********************PL BRAM电压********************/
  22. u32 VBramRawData;
  23. float VBramData;
  24. /********************PS内部核心电压********************/
  25. u32 VccPIntRawData;
  26. float VccPIntData;
  27. /********************PS辅助电压********************/
  28. u32 VccPAuxRawData;
  29. float VccPAuxData;
  30. /********************DDR RAM的工作电压********************/
  31. u32 VDDRRawData;
  32. float VDDRData;
  33. printf("XADC_TEST BEGIN!!! \n\r");
  34. //XADC initilization
  35. ConfigPtr = XAdcPs_LookupConfig(XPAR_AXI_XADC_0_DEVICE_ID);
  36. if (ConfigPtr == NULL) {
  37. return XST_FAILURE;
  38. }
  39. Status_ADC = XAdcPs_CfgInitialize(XADCInstPtr,ConfigPtr,ConfigPtr->BaseAddress);
  40. if(XST_SUCCESS != Status_ADC){
  41. print("ADC INIT FAILED\n\r");
  42. return XST_FAILURE;
  43. }
  44. //self test
  45. Status_ADC = XAdcPs_SelfTest(XADCInstPtr);
  46. if (Status_ADC != XST_SUCCESS) {
  47. return XST_FAILURE;
  48. }
  49. //stop sequencer
  50. XAdcPs_SetSequencerMode(XADCInstPtr,XADCPS_SEQ_MODE_SINGCHAN);
  51. //disable alarms
  52. XAdcPs_SetAlarmEnables(XADCInstPtr, 0x0);
  53. //configure sequencer to just sample internal on chip parameters
  54. XAdcPs_SetSeqInputMode(XADCInstPtr, XADCPS_SEQ_MODE_SAFE);
  55. //configure the channel enables we want to monitor
  56. XAdcPs_SetSeqChEnables(XADCInstPtr,XADCPS_CH_TEMP|XADCPS_CH_VCCINT|XADCPS_CH_VCCAUX|XADCPS_CH_VBRAM|XADCPS_CH_VCCPINT| XADCPS_CH_VCCPAUX|XADCPS_CH_VCCPDRO);
  57. while(1)
  58. {
  59. TempRawData = XAdcPs_GetAdcData(XADCInstPtr, XADCPS_CH_TEMP);
  60. TempData = XAdcPs_RawToTemperature(TempRawData);
  61. printf("Raw Temp %lu Real Temp %f \n\r", TempRawData, TempData);
  62. VccIntRawData= XAdcPs_GetAdcData(XADCInstPtr, XADCPS_CH_VCCINT);
  63. VccIntData = XAdcPs_RawToVoltage(VccIntRawData);
  64. printf("Raw VccInt %lu Real VccInt %f \n\r", VccIntRawData,VccIntData);
  65. VccAuxRawData = XAdcPs_GetAdcData(XADCInstPtr, XADCPS_CH_VCCAUX);
  66. VccAuxData = XAdcPs_RawToVoltage(VccAuxRawData);
  67. printf("Raw VccAux %lu Real VccAux %f \n\r", VccAuxRawData,VccAuxData);
  68. VBramRawData = XAdcPs_GetAdcData(XADCInstPtr, XADCPS_CH_VBRAM);
  69. VBramData = XAdcPs_RawToVoltage(VBramRawData);
  70. printf("Raw VccBram %lu Real VccBram %f \n\r", VBramRawData, VBramData);
  71. VccPIntRawData = XAdcPs_GetAdcData(XADCInstPtr, XADCPS_CH_VCCPINT);
  72. VccPIntData = XAdcPs_RawToVoltage(VccPIntRawData);
  73. printf("Raw VccPInt %lu Real VccPInt %f \n\r", VccPIntRawData, VccPIntData);
  74. VccPAuxRawData = XAdcPs_GetAdcData(XADCInstPtr, XADCPS_CH_VCCPAUX);
  75. VccPAuxData = XAdcPs_RawToVoltage(VccPAuxRawData);
  76. printf("Raw VccPAux %lu Real VccPAux %f \n\r", VccPAuxRawData, VccPAuxData);
  77. VDDRRawData = XAdcPs_GetAdcData(XADCInstPtr, XADCPS_CH_VCCPDRO);
  78. VDDRData = XAdcPs_RawToVoltage(VDDRRawData);
  79. printf("Raw VccDDR %lu Real VccDDR %f \n\r", VDDRRawData, VDDRData);
  80. }
  81. return 0;
  82. }

接下来对程序中的一些函数做一些解释说明:

XAdcPs_LookupConfig()和XAdcPs_CfgInitialize()就不多说了,跟IO部分一样,这两个函数一个是查找设备ID,看设备是否存在,另一个是设备存在的前提下,获取设备的配置表的基址。

XAdcPs_SelfTest()作用是这样的,先把设备复位,然后往警报门限寄存器中写入警报门限的值,再读出来,看写进去的和读出来的值是否相等,相等就说明test成功然后再次复位清除设置的值,否则test失败。

XAdcPs_SetSequencerMode()设置采样序列模式,可设置安全模式、单次、循环、单通道、同步、独立。这里将定序器设置的是单通道,从而停止定序器当前操作。至于这些模式之间的详细区别,因为现在还用不到,所以还没细看,只是感觉,除了单次或者单通道模式外,其他的肯定还要配置通道序列(几通道是序列一、几通道是序列二等等),应该是采集外部信号的时候才会用到,相对复杂一些,等用的时候在看把= =。

  1. #define XADCPS_SEQ_MODE_SAFE 0 /**< Default Safe Mode */
  2. #define XADCPS_SEQ_MODE_ONEPASS 1 /**< Onepass through Sequencer */
  3. #define XADCPS_SEQ_MODE_CONTINPASS 2 /**< Continuous Cycling Sequencer */
  4. #define XADCPS_SEQ_MODE_SINGCHAN 3 /**< Single channel -No Sequencing */
  5. #define XADCPS_SEQ_MODE_SIMUL_SAMPLING 4 /**< Simultaneous sampling */
  6. #define XADCPS_SEQ_MODE_INDEPENDENT 8 /**< Independent mode */

XAdcPs_SetAlarmEnables()设置采样值报警,1使能,0失能。就是采集值大于模块配置时候设置的门限值时报警。

XAdcPs_SetSeqInputMode()设置输入模式,相当于是复位定序器,并按照当前设置的模式进行工作。安全模式下仅采样内部的片上传感器参数。

XAdcPs_SetSeqChEnables()使能采样通道,需要采哪些通道,就将通道与进第二个参数里。

XAdcPs_GetAdcData()获取采集到的ADC的量,传参哪个通道,就采哪个通道。

XAdcPs_RawToTemperature()将采集到的温度数字量,转化成实际的温度值,转换关系如下。

  1. #define XAdcPs_RawToTemperature(AdcData) \
  2. ((((float)(AdcData)/65536.0f)/0.00198421639f ) - 273.15f)

XAdcPs_RawToVoltage()将采集到的电压数字量,转化成实际的电压值,转换关系如下。

  1. #define XAdcPs_RawToVoltage(AdcData) \
  2. ((((float)(AdcData))* (3.0f))/65536.0f)

所以在最后总结一下XADC在SDK中大致的流程:

通过XGpioPs_LookupConfig函数,找到所设备的基址------------>

通过XGpioPs_CfgInitialize函数,初始化设备配置------------>

通过XAdcPs_SelfTest函数,进行采样前自检------------>

通过XAdcPs_SetSequencerMode函数,停止定序器------------>

通过XAdcPs_SetAlarmEnables函数,关闭报警------------>

通过XAdcPs_SetSeqInputMode函数,复位定序器,设置输入模式------------>

通过XAdcPs_SetSeqChEnables函数,使能需要采样的通道------------>

通过XAdcPs_GetAdcData函数,进行ADC采样。

声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:【wpsshop博客】
推荐阅读
相关标签
  

闽ICP备14008679号