裸机开发-GPIO外设

重新开始学ZYNQ开发,学完上linux系统

基础知识:ZYNQ 的三种GPIO :MIO、EMIO、AXI - FPGA/ASIC技术 - 电子发烧友网

GPIO是ZYNQ PS端的一个IO外设,用于观测(input)和控制(output)器件引脚的状态

MIO(Multiplexed I/O)多路复用IO。是ZYNQ PS端的一部分,将来自PS外设和静态存储器接口的访问多路复用到PS引脚上,直接连接到PS端的引脚,用于控制外设(如LED、按键等)。MIO的引脚位置是固定的,不需要像PL端那样进行引脚约束。

EMIO(Extended MIO),扩展的MIO。EMIO是PS与PL的接口,当PS引脚不够用的时候,可以使用EMIO来进行扩展,从而使用PL的IO;当某个设备硬件已经连接到PL端,但是通过Verilog代码实现较复杂的时候,可以用EMIO让PS端来驱动。

GPIO分组:Bank0:32位控制MIO[31:0];Bank1:32位控制MIO[53:32]; Bank2:32位控制EMIO[31:0];Bank3:32位控制EMIO[63:32]。

软件通过GPIO可以独立且动态的编程,作为输入/输出以及中断模式。

实验任务一:点灯大师(基于寄存器)使用PS端的MIO控制两个LED,实现LED闪烁的效果,闪烁间隔为1s。

第一步:在vivado上block design中创建了一个最小系统(system)作为zynq的ps端。在最小系统(DDR3+UART)中添加了GPIO(通用输入输出)外设,负责管理和控制MIO引脚的状态。GPIO通过MIO引脚直接连接到LED,实现对其的控制。

第二步:代码逻辑控制ps端,通过GPIO的数据手册中的几个寄存器控制LED.

复制代码
#include <stdio.h>
#include "xil_io.h"
#include "sleep.h"

#define GPIOPS_BASE_ADDRESS 	 0xE000A000  // GPIO基地址
#define XGPIOPS_DIRM_OFFSET 	 0x00000204  // 方向模式寄存器偏移地址
#define XGPIOPS_OUTEN_OFFSET 	 0x00000208  // 输出使能寄存器偏移地址
#define XGPIOPS_DATA_LSW_OFFSETR 0x00000000  // 带屏蔽的数据寄存器偏移地址

int main() {
    printf("GPIO MIO TEST!\n");

    // 对GPIO引脚进行配置
    // 配置方向模式寄存器,使MIO7和MIO8为输出模式
    Xil_Out32(GPIOPS_BASE_ADDRESS + XGPIOPS_DIRM_OFFSET, 0x00000180);  // 0000_0000_0000_0000_0000_0001_1000_0000
    // 配置输出使能寄存器,使MIO7和MIO8输出使能
    Xil_Out32(GPIOPS_BASE_ADDRESS + XGPIOPS_OUTEN_OFFSET, 0x00000180); // 0000_0000_0000_0000_0000_0001_1000_0000

    while (1) {
        // 点亮MIO7,熄灭MIO8
        Xil_Out32(GPIOPS_BASE_ADDRESS + XGPIOPS_DATA_LSW_OFFSETR, 0xff7f0080); // 0000_0000_0000_0000_0000_0000_1000_0000
        sleep(1); // 延迟1秒
        Xil_Out32(GPIOPS_BASE_ADDRESS + XGPIOPS_DATA_LSW_OFFSETR, 0xff7f0000); // 0000_0000_0000_0000_0000_0000_1000_0000
        sleep(1); // 延迟1秒
        // 点亮MIO8,熄灭MIO7
        Xil_Out32(GPIOPS_BASE_ADDRESS + XGPIOPS_DATA_LSW_OFFSETR, 0xfeff0100); // 0000_0000_0000_0000_0000_0001_0000_0000
        sleep(1); // 延迟1秒
        Xil_Out32(GPIOPS_BASE_ADDRESS + XGPIOPS_DATA_LSW_OFFSETR, 0xfeff0000); // 0000_0000_0000_0000_0000_0001_0000_0000
        sleep(1);
    }
    return 0;
}

实验任务二:点灯大师(基于库函数)使用PS端的MIO控制两个LED,实现LED闪烁的效果,闪烁间隔为1s(和实验一逻辑是一样)。

复制代码
#include <stdio.h>
#include "xparameters.h"
#include "xgpiops.h"
#include "sleep.h"

#define GPIO_DEVICE_ID		XPAR_XGPIOPS_0_DEVICE_ID
#define MIO_LED0            7 //MIO 7
#define MIO_LED1            8 //MIO 7


XGpioPs Gpio;

int main(){
	XGpioPs_Config *ConfigPtr;
	printf("GPIO TEST SUCCESS!\n");
	//对GPIO进行初始化(两步)    /* Initialize the GPIO driver. */
	//第一步:根据器件ID去查找器件的配置信息
	ConfigPtr = XGpioPs_LookupConfig(GPIO_DEVICE_ID);
	//第二步:对GPIO的驱动进行初始化
	XGpioPs_CfgInitialize(&Gpio, ConfigPtr,ConfigPtr->BaseAddr);
	//设置引脚的方向,0为输入,1为输出
	XGpioPs_SetDirectionPin(&Gpio, MIO_LED0, 1);
	XGpioPs_SetDirectionPin(&Gpio, MIO_LED1, 1);
	//设置输出使能,1:使能输出,0:不使能输出
	XGpioPs_SetOutputEnablePin(&Gpio, MIO_LED0, 1);
	XGpioPs_SetOutputEnablePin(&Gpio, MIO_LED1, 1);
	while(1){
	//对引脚输出为高电平,点亮LED灯
	XGpioPs_WritePin(&Gpio, MIO_LED0, 0x1);
	sleep(1);
	//交替闪烁
	XGpioPs_WritePin(&Gpio, MIO_LED1, 0x1);
	sleep(1);
	//对引脚输出为低电平,熄灭LED灯   /* Set the GPIO output to be low. */
	XGpioPs_WritePin(&Gpio, MIO_LED0, 0x0);
	sleep(1);
	XGpioPs_WritePin(&Gpio, MIO_LED1, 0x0);
	sleep(1);
	}

	return 0;
}

上板验证:

实验任务3:使用两个用户按键分别控制PS端的两个LED灯的亮灭,其中一个按键需要通过EMIO进行扩展(PL端的参与)。需要增加GPIO输入的功能,实验二GPIO用于输出。

相关推荐
我送炭你添花3 小时前
电子世界的奇妙冒险:从一个电阻开始(系列目录)
人工智能·单片机·嵌入式硬件·fpga开发
知识充实人生5 小时前
FPGA设计杂谈之九:HRIO/HPIO/HDIO
fpga开发·xilinx·hr i/o·hp i/o·hd i/o·io类型
maverick_11114 小时前
【FPGA】 在Verilog中,! 和 ~ 的区别
fpga开发
黄埔数据分析2 天前
QDMA把描述符当数据搬移, 不用desc engine
fpga开发
南檐巷上学2 天前
基于FPGA的正弦信号发生器、滤波器的设计(DAC输出点数受限条件下的完整正弦波产生器)
fpga开发·数字信号处理·dsp·dds
嵌入式-老费2 天前
Linux Camera驱动开发(fpga + csi rx/csi tx)
fpga开发
ALINX技术博客3 天前
【202601芯动态】全球 FPGA 异构热潮,ALINX 高性能异构新品预告
人工智能·fpga开发·gpu算力·fpga
JJRainbow3 天前
SN75176 芯片设计RS-232 转 RS-485 通信模块设计原理图
stm32·单片机·嵌入式硬件·fpga开发·硬件工程
s9123601013 天前
FPGA眼图
fpga开发
北京青翼科技3 天前
【PCIe732】青翼PCIe采集卡-优质光纤卡- PCIe接口-万兆光纤卡
图像处理·人工智能·fpga开发·智能硬件·嵌入式实时数据库