Xilinx ZYNQ 7000+Vivado2015.2系列(四)之GPIO的三种方式:MIO、EMIO、AXI_GPIO

转自:https://blog.csdn.net/u014485485/article/details/78141594

Xilinx ZYNQ 7000+Vivado2015.2系列(四)之GPIO的三种方式:MIO、EMIO、AXI_GPIO

2017年09月30日 12:16:44

阅读数:848

前言:

ZYNQ 7000有三种GPIO:MIO,EMIO,AXI_GPIO

MIO是固定管脚的,属于PS,使用时不消耗PL资源;EMIO通过PL扩展,使用时需要分配管脚,使用时消耗PL管脚资源;AXI_GPIO是封装好的IP核,PS通过M_AXI_GPIO接口控制PL部分实现IO,使用时消耗管脚资源和逻辑资源。

使用的板子是zc702。

1.MIO方式

Zynq7000 系列芯片有 54 个 MIO(multiuse I/O), 它们分配在 GPIO 的 Bank0 和Bank1 隶属于 PS 部分, 这些 IO 与 PS 直接相连。 不需要添加引脚约束, MIO 信号对 PL部分是透明的, 不可见。 所以对 MIO 的操作可以看作是纯 PS 的操作。

新建Vivado工程,添加ZYNQ CPU核,双击,配置好时钟和内存类型,确认勾选MIO:

如系列(三)文章所述,生成bit stream,然后Launch SDK。

在SDK中新建工程,源文件如下:

 
  1. #include "xgpiops.h"

  2. #include "sleep.h"

  3. int main()

  4. {

  5. static XGpioPs psGpioInstancePtr;

  6. XGpioPs_Config* GpioConfigPtr;

  7. int iPinNumber= 8; //DS12连接的是MIO8

  8. u32 uPinDirection = 0x1; //1表示输出, 0表示输入

  9. int xStatus;

  10. //--MIO的初始化

  11. GpioConfigPtr = XGpioPs_LookupConfig(XPAR_PS7_GPIO_0_DEVICE_ID);

  12. if(GpioConfigPtr == NULL)

  13. return XST_FAILURE;

  14. xStatus = XGpioPs_CfgInitialize(&psGpioInstancePtr,GpioConfigPtr,

  15. GpioConfigPtr->BaseAddr);

  16. if(XST_SUCCESS != xStatus)

  17. print(" PS GPIO INIT FAILED \n\r");

  18. //--MIO的输入输出操作

  19. XGpioPs_SetDirectionPin(&psGpioInstancePtr, iPinNumber,uPinDirection);//配置MIO输出方向

  20. XGpioPs_SetOutputEnablePin(&psGpioInstancePtr, iPinNumber,1);//配置MIO的第8位输出

  21. while(1)

  22. {

  23. XGpioPs_WritePin(&psGpioInstancePtr, iPinNumber, 1);//点亮MIO的第8位输出1

  24. usleep(500000); //延时

  25. XGpioPs_WritePin(&psGpioInstancePtr, iPinNumber, 0);//熄灭MIO的第8位输出0

  26. usleep(500000); //延时

  27. }

  28. /****************************************************************

  29. while(1)

  30. {

  31. XGpioPs_WriteReg(0xE000A000,0x00000000, 0xFF7FFFFF&0xFFFF0080);

  32. usleep(500000); //延时

  33. XGpioPs_WriteReg(0xE000A000,0x00000000, 0xFF7FFFFF&0xFFFF0000);

  34. usleep(500000); //延时

  35. } *

  36. *****************************************************************/

  37. return 0;

  38. }


下载到板子上,DS12就开始闪烁了。

2.EMIO方式

EMIO 分配在 bank2 和 bank3 和 PL部分相连。EMIO 有 64 个引脚可供我们使用 。当 MIO 不够用时, PS 可以通过驱动 EMIO 控制 PL 部分的引脚 。

Vivado工程里ZYNQ CPU核配置,确保EMIO勾选,这里我设置了位宽为4,后面为其分配了四个管脚:



在Diagram里面将GPIO_0的引脚引出来,生成顶层文件后查看这个引脚的名字,因为我修改了名字,这里叫emio_0_tri_io


管脚约束文件:

 
  1. #GPIO PMOD1

  2. set_property PACKAGE_PIN E15 [get_ports {emio_0_tri_io[0]}]

  3. set_property IOSTANDARD LVCMOS25 [get_ports {emio_0_tri_io[0]}]

  4. set_property PACKAGE_PIN D15 [get_ports {emio_0_tri_io[1]}]

  5. set_property IOSTANDARD LVCMOS25 [get_ports {emio_0_tri_io[1]}]

  6. set_property PACKAGE_PIN W17 [get_ports {emio_0_tri_io[2]}]

  7. set_property IOSTANDARD LVCMOS25 [get_ports {emio_0_tri_io[2]}]

  8. set_property PACKAGE_PIN W5 [get_ports {emio_0_tri_io[3]}]

  9. set_property IOSTANDARD LVCMOS25 [get_ports {emio_0_tri_io[3]}]


SDK部分:MIO号是0~53,EMIO从54开始

 
  1. #include "xgpiops.h"

  2. #include "sleep.h"

  3. int main()

  4. {

  5. static XGpioPs psGpioInstancePtr;

  6. XGpioPs_Config* GpioConfigPtr;

  7. int xStatus;

  8. //-- EMIO的初始化

  9. GpioConfigPtr = XGpioPs_LookupConfig(XPAR_PS7_GPIO_0_DEVICE_ID);

  10. if(GpioConfigPtr == NULL)

  11. return XST_FAILURE;

  12. xStatus = XGpioPs_CfgInitialize(&psGpioInstancePtr,GpioConfigPtr,

  13. GpioConfigPtr->BaseAddr);

  14. if(XST_SUCCESS != xStatus)

  15. print(" PS GPIO INIT FAILED \n\r");

  16. //--EMIO的输入输出操作

  17. XGpioPs_SetDirectionPin(&psGpioInstancePtr, 54,1);

  18. XGpioPs_SetDirectionPin(&psGpioInstancePtr, 55,1);

  19. XGpioPs_SetDirectionPin(&psGpioInstancePtr, 56,1);

  20. XGpioPs_SetDirectionPin(&psGpioInstancePtr, 57,1);

  21. //使能EMIO输出

  22. XGpioPs_SetOutputEnablePin(&psGpioInstancePtr, 54,1);

  23. XGpioPs_SetOutputEnablePin(&psGpioInstancePtr, 55,1);

  24. XGpioPs_SetOutputEnablePin(&psGpioInstancePtr, 56,1);

  25. XGpioPs_SetOutputEnablePin(&psGpioInstancePtr, 57,1);

  26. while(1)

  27. {

  28. XGpioPs_WritePin(&psGpioInstancePtr, 54, 1);//EMIO的第0位输出1

  29. usleep(200000); //延时

  30. XGpioPs_WritePin(&psGpioInstancePtr, 54, 0);//EMIO的第0位输出0

  31. usleep(200000); //延时

  32. XGpioPs_WritePin(&psGpioInstancePtr, 55, 1);//EMIO的第1位输出1

  33. usleep(200000); //延时

  34. XGpioPs_WritePin(&psGpioInstancePtr, 55, 0);//EMIO的第1位输出0

  35. usleep(200000); //延时

  36. XGpioPs_WritePin(&psGpioInstancePtr, 56, 1);//EMIO的第2位输出1

  37. usleep(200000); //延时

  38. XGpioPs_WritePin(&psGpioInstancePtr, 56, 0);//EMIO的第2位输出0

  39. usleep(200000); //延时

  40. XGpioPs_WritePin(&psGpioInstancePtr, 57, 1);//EMIO的第3位输出1

  41. usleep(200000); //延时

  42. XGpioPs_WritePin(&psGpioInstancePtr, 57, 0);//EMIO的第3位输出0

  43. usleep(200000); //延时

  44. }

  45. return 0;

  46. }

下载到板子里,PMOD1的4个led灯交替闪烁。

3.AXI_GPIO方式

VIvado工程里,ZYNQ CPU核配置:
勾选M_AXI_GPIO 接口:

勾选复位信号:

给PL的时钟信号:

加入AXI_GPIO IP,这里设置位宽为4,后面将控制4个led灯:

自动连接后如下图:

管脚约束如下:

 
  1. #GPIO PMOD1

  2. set_property PACKAGE_PIN E15 [get_ports {gpio_sw_tri_o[0]}]

  3. set_property IOSTANDARD LVCMOS25 [get_ports {gpio_sw_tri_o[0]}]

  4. set_property PACKAGE_PIN D15 [get_ports {gpio_sw_tri_o[1]}]

  5. set_property IOSTANDARD LVCMOS25 [get_ports {gpio_sw_tri_o[1]}]

  6. set_property PACKAGE_PIN W17 [get_ports {gpio_sw_tri_o[2]}]

  7. set_property IOSTANDARD LVCMOS25 [get_ports {gpio_sw_tri_o[2]}]

  8. set_property PACKAGE_PIN W5 [get_ports {gpio_sw_tri_o[3]}]

  9. set_property IOSTANDARD LVCMOS25 [get_ports {gpio_sw_tri_o[3]}]


SDk部分如下:

 
  1. #include <stdio.h>

  2. #include "platform.h"

  3. #include "xparameters.h"

  4. #include "xgpio.h"

  5. int main() {

  6. XGpio gpio_led;

  7. int status;

  8. int i,x,y;

  9.  
  10. init_platform();

  11. status = XGpio_Initialize(&gpio_led, 0);

  12. if(status == 0){

  13. printf("success \r\n");

  14. }

  15.  
  16. XGpio_SetDataDirection(&gpio_led,1,0);//设置通道1为输出

  17. while (1){

  18. for (i = 0; i<=3; i++){

  19. XGpio_DiscreteWrite(&gpio_led, 1, 0x01<<i);

  20. for(x =1000; x > 0; x-- ){

  21. for (y = 100000; y > 0; y--);

  22. }

  23. }

  24. }

  25. cleanup_platform();

  26. return 0;

  27. }


可以看到,与EMIO一样需要分配管脚,但是AXI_GPIO使用的头文件是#include "xgpio.h",而EMIO是#include "xgpiops.h"。

下载完成后,PMOD1 的四个LED灯依次闪烁。

总结:

MIO和EMIO使用PS的GPIO,,MIO固定管脚,EMIO手动分配管脚;IP方式手动分配管脚,综合后需要消耗PL的逻辑资源。

猜你喜欢

转载自blog.csdn.net/liuzq/article/details/81367976