zoukankan      html  css  js  c++  java
  • Zynq 7020笔记之 GPIO MIO 和EMIO的学习

    1 参考

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

    2 理论指示

    在PS侧,有PS自己的IO pin,称为MIO,共有54个(编号0-53)。如果PS侧IO不够使用,则可以通过扩展的方式来使用PL侧的IO。扩展方式有两中:EMIO和GPIO。 EMIO 方式可以将PL侧IO直接看作PS侧IO使用,只是编号从54-117. 而GPIO则没有数量限制。直接挂到AXI总线上就可以。
    在这里插入图片描述
    在这里插入图片描述
    上图是EMIO和MIO的IO映射关系示意图。
    对于MIO的使用。
    MIO的例化在ZYNQ的Perpheral IO和IO Configuration中体现。
    Perpheral IO中的0-43就是MIO的pin Number.这个Pin Number在SDK(C编程中)可以体现到。

    3 实验目的

    练习使用MIO,EMIO,GPIO等接口。

    4 实验过程

    建立工程,并初始化GPIO,EMIO等。然后:
    当按下GPIO LED对应的KEY时,GPIO LED会进行亮灭转换;
    当按下EMIO LED对应的KEY时,EMIO LED会进行亮灭转换;
    当按下MIO LED对应的KEY时,MIO LED会进行亮灭转换;

    5 实验平台

    Microphase ZUS zynq7020 开发板。 串口使用 uart1[48,49]. DDR选择 MT41J256M16 RE-125,32bit. BANK1 = 1.8v.
    同时对GPIO EMIO进行下图的设置。

    EMIO,EMIO也是在Zynq的设置中进行设置的。

    在这里插入图片描述
    在这里插入图片描述
    上图中的3代表EMIO的宽度,不管是input还是output都算在一起。然后对应的pin number会从54开始映射,到54+emio_width(eg.3)-1。假如在block design中 EMIO端名为ps_emio_port,则pin assignment 会从最低位开始映射,即ps_emio_port[0] = EMIO number 54. ps_emio_port[width-1] = EMIO Number 54+emio_width-1。

    GPIO 是挂在PS_to_PL AXI 总线上的外设,比较简单。

    6 Vivado 建立工程

    block design 如下:
    在这里插入图片描述

    7、SDK的工程程序

    #本例程是将GPIO,EMIO和MIO融合在一起的程序。
    #include <stdio.h>
    #include "platform.h"
    #include "xgpio.h"
    #include "xgpiops.h"
    #include "xparameters.h"
    #include <unistd.h>  //sleep()  usleep()
    
    
    ////// parameter define ,根据xparameters.h中的参数来定义每个AXI_GPIO外设的ID
    #define 	KEY_GPIO_DEVICE_ID		XPAR_AXI_GPIO_1_DEVICE_ID
    #define 	LED_Auto_GPIO_DEVICE_ID	XPAR_AXI_GPIO_0_DEVICE_ID
    #define 	LED_key_GPIO_DEVICE_ID	XPAR_AXI_GPIO_2_DEVICE_ID
    
    //定义EMIO的pin number,根据PL程序中port的高地位来映射。54对应最低位,依次累加。【重要】
    #define 	KEY_iPinNumberEMIO			56
    #define 	LED_Auto_iPinNumberEMIO		55
    #define 	LED_Key_iPinNumberEMIO		54  //PL侧EMIO例化的端口的最低位,为端口54,然后依次向上排列
    
    //定义MIO的pin number,根据zynq设定,是多少就定于多少。
    #define 	KEY_iPinNumberMIO			47
    #define 	LED_Auto_iPinNumberMIO		50
    #define 	LED_Key_iPinNumberMIO		51
    
    
    int main()
    {
    
    	//定义 gpiO 所用参数
    	XGpio KEY_GpioInst;
    	XGpio LED_Auto_GpioInst;
    	XGpio LED_Key_GpioInst;
    	u32   led_Auto_gpio	;
    	u32   Key_gpio_value	;
    
    
    	int	  key_gpio_status;
    	int	  led_auto_gpio_status;
    	int	  led_key_gpio_status;
    	int   i;
    
    	//定义EMIO所用参数,和MIO所用参数。
    	//使用EMIO 和MIO都需要对PS侧GPIO进行初始化,当两个都使用时只需要初始化一次就可以了,所以有些参数共同使用
    
    	static XGpioPs psGpioInstancePtr;  //共用
    	XGpioPs_Config* GpioConfigPtr;   //共用
    	u32   emio_Led;
    	int	  emio_status;  //共用
    	u32   Key_EMIO_value	;
    	int   j ;
    
    
    	u32   mio_led ;
    	u32	  Key_MIO_value ;
    	int   k;
    
     //固定初始化。
    	init_platform();
    
    	// init gpio,并检测初始化之后的状态
    	key_gpio_status 		= XGpio_Initialize(&KEY_GpioInst		,KEY_GPIO_DEVICE_ID 		);
    	led_auto_gpio_status 	= XGpio_Initialize(&LED_Auto_GpioInst	,LED_Auto_GPIO_DEVICE_ID 	);
    	led_key_gpio_status 	= XGpio_Initialize(&LED_Key_GpioInst	,LED_key_GPIO_DEVICE_ID 	);
    
    	if(key_gpio_status == 0)
    	{
    		printf(" KEY GPIO  init successful ! 
    ");
    
    	} else {
    
    		printf(" KEY GPIO  init Failed ! 
    ");
    	}
    
    	if(led_auto_gpio_status == 0)
    		{
    			printf(" LED Auto GPIO  init successful ! 
    ");
    
    		} else {
    
    			printf(" LED Auto GPIO  init Failed ! 
    ");
    		}
    
    	if(led_key_gpio_status == 0)
    		{
    			printf(" LED KEY GPIO  init successful ! 
    ");
    
    		} else {
    
    			printf(" LED KEY GPIO  init Failed ! 
    ");
    		}
    
    	// 设置GPIO的方向,
    	XGpio_SetDataDirection(&KEY_GpioInst		,	1,	1);  // set as input
    	XGpio_SetDataDirection(&LED_Auto_GpioInst	,	1,	0);  // set as output
    	XGpio_SetDataDirection(&LED_Key_GpioInst	,	1,	0);  // set as output
    
       //并对output信号进行消隐(这里output接LED灯),最后的1为data.这里LED 为0时点亮。初始化之后设置为1,熄灭led.
    	XGpio_DiscreteWrite(&LED_Auto_GpioInst	,	1, 	1);  ////消隐,初始化,关闭LED
    	XGpio_DiscreteWrite(&LED_Key_GpioInst	,	1, 	1);  ////消隐,初始化,关闭LED
    
    
    	// init ps侧GPIO (emio and mio ),并检测初始化状态。
    
    	GpioConfigPtr = XGpioPs_LookupConfig(XPAR_PS7_GPIO_0_DEVICE_ID);
    	if(GpioConfigPtr == NULL)  return XST_FAILURE ;
    	emio_status = XGpioPs_CfgInitialize(&psGpioInstancePtr,GpioConfigPtr,GpioConfigPtr->BaseAddr);
    	if(emio_status == XST_SUCCESS)
    		printf(" PS EMIO and MIO init successful ! 
    ");
    	else
    		printf(" PS EMIO and MIO init Failed ! 
    ");
    
    	// 设置EMIO的方向,
    	XGpioPs_SetDirectionPin(&psGpioInstancePtr,KEY_iPinNumberEMIO,0);
    	XGpioPs_SetDirectionPin(&psGpioInstancePtr,LED_Auto_iPinNumberEMIO,1);
    	XGpioPs_SetDirectionPin(&psGpioInstancePtr,LED_Key_iPinNumberEMIO,1);
       //并对output信号进行消隐(这里output接LED灯),
    	XGpioPs_SetOutputEnablePin(&psGpioInstancePtr,	LED_Auto_iPinNumberEMIO	,	1);
    	XGpioPs_SetOutputEnablePin(&psGpioInstancePtr,	LED_Key_iPinNumberEMIO	,	1);
    
    	//// 设置EMIO的方向,并对output信号进行消隐(这里output接LED灯)
    	XGpioPs_SetDirectionPin(&psGpioInstancePtr,	KEY_iPinNumberMIO		,	0);
    	XGpioPs_SetDirectionPin(&psGpioInstancePtr,	LED_Auto_iPinNumberMIO	,	1);
    	XGpioPs_SetDirectionPin(&psGpioInstancePtr,	LED_Key_iPinNumberMIO	,	1);
    
    	XGpioPs_SetOutputEnablePin(&psGpioInstancePtr,	LED_Auto_iPinNumberMIO	,	1);
    	XGpioPs_SetOutputEnablePin(&psGpioInstancePtr,	LED_Key_iPinNumberMIO	,	1);
    
    //对EMIO和MIO输出端口进行消隐。
    	XGpioPs_WritePin(&psGpioInstancePtr,LED_Auto_iPinNumberEMIO	,	1);   //消隐
    	XGpioPs_WritePin(&psGpioInstancePtr,LED_Key_iPinNumberEMIO	,	1);   //消隐
    	XGpioPs_WritePin(&psGpioInstancePtr,LED_Auto_iPinNumberMIO	,	1);   //消隐
    	XGpioPs_WritePin(&psGpioInstancePtr,LED_Key_iPinNumberMIO	,	1);   //消隐
    
        printf("LED test Start ----> 
    ")  ;
        while(1)
        {
    
        	printf("EMIO LED test Start ----> 
    ")  ;
        	//EMIO所接的 LED1自动闪烁
        	printf(".......EMIO LED Auto test Start ........... 
    ")  ;
    		for(j = 0; j < 5; j++)
    		{
    			for(emio_Led = 0; emio_Led < 2; emio_Led ++)
    			{
    				XGpioPs_WritePin(&psGpioInstancePtr,LED_Auto_iPinNumberEMIO,emio_Led);   //取 最后一位
    				sleep(1);
    			}
    		}
    		XGpioPs_WritePin(&psGpioInstancePtr,LED_Auto_iPinNumberEMIO,1);  //消隐
    
    		//当EMIO所接的开关被按下(低有效)之后,EMIO所接的LED2亮一会之后熄灭。
    		printf(".......wait EMIO KEY test Start ........... 
    ")  ;
    		while(1)
    		{
    			Key_EMIO_value = XGpioPs_ReadPin(&psGpioInstancePtr ,KEY_iPinNumberEMIO)& 0x01;
    			if(Key_EMIO_value == 0x00)
    			{
    				printf(".......KEY EMIO have Pressed, LED KEY EMIO Turn on ....... 
    ")  ;
    				XGpioPs_WritePin(&psGpioInstancePtr ,LED_Key_iPinNumberEMIO,0);
    				sleep(5);
    				break ;
    			}
    		}
    		XGpioPs_WritePin(&psGpioInstancePtr ,LED_Key_iPinNumberEMIO,1);  //消隐
    
    
    
        	printf("GPIO LED test Start ----> 
    ")  ;
    
        	printf(".......LED Auto test Start ........... 
    ")  ;
    
        	for(i = 0; i < 5; i++)
        	{
        		for(led_Auto_gpio = 0; led_Auto_gpio < 2; led_Auto_gpio ++)
    			{
        			XGpio_DiscreteWrite(&LED_Auto_GpioInst,1, 1<<led_Auto_gpio);
        			sleep(1);
        		 }
        	}
        	XGpio_DiscreteWrite(&LED_Auto_GpioInst	,	1, 	1);   ////消隐
    
    
        	printf(".......Wait KEY GPIO Pressed ........... 
    ")  ;
    
        	while(1)
        	{
        		Key_gpio_value = XGpio_DiscreteRead(&KEY_GpioInst,1)& 0x01;
        		if(Key_gpio_value == 0x00)
        		{
        			printf(".......KEY GPIO have Pressed, LED KEY Turn on ....... 
    ")  ;
        			XGpio_DiscreteWrite(&LED_Key_GpioInst,1,0);
        			sleep(5);
        			break ;
        		}
        	}
        	XGpio_DiscreteWrite(&LED_Key_GpioInst,1,1);  //消隐
    
    
    
    		printf("MIO LED test Start ----> 
    ")  ;
    		printf(".......LED MIO test Start ........... 
    ")  ;
    		for(k = 0; k < 5; k++)
    		{
    			for(mio_led = 0; mio_led < 2; mio_led ++)
    			{
    				XGpioPs_WritePin(&psGpioInstancePtr,LED_Auto_iPinNumberMIO,mio_led);   //取 最后一位
    				sleep(5);
    
    			}
    
    		}
    		XGpioPs_WritePin(&psGpioInstancePtr,LED_Auto_iPinNumberMIO,1);   //消隐
    
    		printf(".......wait MIO KEY test Start ........... 
    ")  ;
    		while(1)
    		{
    			Key_MIO_value = XGpioPs_ReadPin(&psGpioInstancePtr ,KEY_iPinNumberMIO)& 0x01;
    			if(Key_MIO_value == 0x00)
    			{
    				printf(".......KEY EMIO have Pressed, LED KEY EMIO Turn on ....... 
    ")  ;
    				XGpioPs_WritePin(&psGpioInstancePtr ,LED_Key_iPinNumberMIO,0);
    				sleep(5);
    				break ;
    			}
    		}
    		XGpioPs_WritePin(&psGpioInstancePtr ,LED_Key_iPinNumberMIO,1);  //消隐
    
    
        }
    
     //结束时需要添加的。
        cleanup_platform();
        return 0 ;
    
    }
    

    8 调试步骤

  • 相关阅读:
    使用docker sail镜像创建laravel项目
    Python使用阿里云镜像
    VMware安装OpenEuler虚拟机并配置图形界面
    机器学习模型评估指标汇总 (一)
    机器学习模型评估指标汇总 (二)
    运行docker命令需要sudo权限的问题
    如何不重装修复损坏的 Ubuntu 系统
    卡尔曼滤波
    升级anaconda
    jupyter notebook 代码自动补全
  • 原文地址:https://www.cnblogs.com/fhyfhy/p/11760987.html
Copyright © 2011-2022 走看看