MIO与EMIO在各bank的分布
根据官方手册可以看到MIO分布在BANK0与BANK1有54个,而EMIO分布在BANK2与BANK3有64个。
中断系统的介绍
根据官方手册的GIC中断控制器的系统级块图可以看出中断源有:软件中断SGI、两个CPU的私有中断PPI、共享外设中断SPI(包括PS端的IOP和PL端)。
根据这张图就更清晰的看出各中断源如何与GIC连接的。
一、MIO和EMIO的设置
1.初始化MIO与EMIO
XGpioPs_Config *ConfigPtr; /*为GPIO的设备信息创建一个指针*/
ConfigPtr = XGpioPs_LookupConfig(XPAR_AXI_GPIO_0_DEVICE_ID);/*根据设备ID查找到GPIO的配置信息*/
XGpioPs_CfgInitialize(&Gpio, ConfigPtr, ConfigPtr->BaseAddr);/*根据查找到的GPIO的配置信息进行初始化*/
2.MIO与EMIO的输入输出设置
//设置IO方向函数
XGpioPs_SetDirectionPin(&Gpio, PL_LED, 1);/*(函数指针,IO管脚编号,0设置为输入 1设置为输出)*/
XGpioPs_SetDirectionPin(&Gpio, PL_KEY, 0x0);
//设置IO输出使能函数
XGpioPs_SetOutputEnablePin(&Gpio, PL_LED, 1);/*(函数指针,IO管脚编号,0设置为禁止 1设置为使能)*/
//设置IO输出数据函数
XGpioPs_WritePin(&Gpio, PL_LED, 0x0);/*(函数指针,IO管脚编号,0设置为输出为0 1设置输出为1)*/
二、中断的设置
1.初始化Scugic驱动
XScuGic_Config *IntcConfig; /* 为中断设置配置一个实例指针 */
//根据设备ID查找到Scugic的配置信息,并进行初始化,这里只需要注意填下ID号,其他的不需要关心
IntcConfig = XScuGic_LookupConfig(XPAR_SCUGIC_SINGLE_DEVICE_ID);
XScuGic_CfgInitialize(&GicInstancePtr, IntcConfig,IntcConfig->CpuBaseAddress);
2.配置中断服务
//注册异常处理函数(不需要关心)
Xil_ExceptionRegisterHandler(XIL_EXCEPTION_ID_INT,
(Xil_ExceptionHandler)XScuGic_InterruptHandler,
&GicInstancePtr);
//注册/绑定具体外设的中断服务函数(需要用户去关心)
XScuGic_Connect(&GicInstancePtr, XPS_GPIO_INT_ID,
(Xil_ExceptionHandler)XGpioPs_IntrHandler,
&Gpio);
//(指针,中断ID号,中断函数地址,回调参考指针)
//设置具体外设的中断相关的寄存器(使能、禁止、中断检测类型)(需要用户去关心)
XGpioPs_SetIntrType(&Gpio, XGPIOPS_BANK2 , 0xFFFFFFFF, 0x00000000, 0x00);/*(实例指针,bank号,中断触发类型_0电平触发_1边沿触发,
中断触发极性_0低电平或下降沿_1高电平或上升沿,中断触发敏感度_0单边缘触发_1双边缘触发)*/
/* 设置回调函数. */
XGpioPs_SetCallbackHandler(&Gpio, &Gpio, IntrHandler);//(实例指针,回调指针,中断函数指针)
//设置某位的中断使能(需要用户去关心)
XGpioPs_IntrEnable(&Gpio, XGPIOPS_BANK2, (1 << (PL_KEY - 54)));//(实例指针,BANK号,32位_位1为使能_位0为禁止)
//在GIC中允许该外设的中断源向Cpu发出中断
XScuGic_Enable(&GicInstancePtr, XPS_GPIO_INT_ID);
//开启总中断
Xil_ExceptionEnableMask(XIL_EXCEPTION_IRQ);
3.中断处理函数的设置
static void IntrHandler(void *CallBackRef, u32 Bank, u32 Status)
{
XGpioPs *Gpio = (XGpioPs *)CallBackRef;
u32 DataRead;
/* Push the switch button */
if(Status)
{
DataRead = XGpioPs_ReadPin(Gpio , PL_KEY);
if (DataRead == 0) {
flag ++;
}
}
}
三、整体代码
#include "stdio.h"
#include "xgpiops.h"
#include "xparameters.h"
#include "xscugic.h"
#include "xil_exception.h"
#include "unistd.h"
static XGpioPs Gpio; /* The Instance of the GPIO Driver */
static XScuGic GicInstancePtr; /* The Instance of the Interrupt Controller Driver */
#define PS_LED 7 //MIO_LED为MIO7,对应的GPIO编号为7
#define PS_KEY 47 //MIO_KEY为MIO47,对应的GPIO编号为47
#define PL_KEY (54 + 1) //EMIO_KEY为EMIO1,对应的GPIO编号为55
#define PL_LED (54 + 0) //EMIO_LED为EMIO0,对应的GPIO编号为54
int flag;
static void IntrHandler(void *CallBackRef, u32 Bank, u32 Status)
{
XGpioPs *Gpio = (XGpioPs *)CallBackRef;
u32 DataRead;
/* Push the switch button */
if(Status)
{
DataRead = XGpioPs_ReadPin(Gpio , PL_KEY);
if (DataRead == 0) {
flag ++;
}
}
}
int main (void)
{
//MIO初始化
XGpioPs_Config *ConfigPtr; /*为GPIO的设备信息创建一个指针*/
ConfigPtr = XGpioPs_LookupConfig(XPAR_AXI_GPIO_0_DEVICE_ID);/*根据设备ID查找到GPIO的配置信息*/
XGpioPs_CfgInitialize(&Gpio, ConfigPtr, ConfigPtr->BaseAddr);
//设置本例中用到的GPIO的基本工作模式(输入(MIO47)、输出(MIO7)、初始值)
XGpioPs_SetDirectionPin(&Gpio, PL_LED, 1);
XGpioPs_SetOutputEnablePin(&Gpio, PL_LED, 1);
XGpioPs_WritePin(&Gpio, PL_LED, 0x0);
/* Set the direction for the specified pin to be input */
XGpioPs_SetDirectionPin(&Gpio, PL_KEY, 0x0);
//初始化SCUGIO驱动
XScuGic_Config *IntcConfig; /* Instance of the interrupt controller */
IntcConfig = XScuGic_LookupConfig(XPAR_SCUGIC_SINGLE_DEVICE_ID);
XScuGic_CfgInitialize(&GicInstancePtr, IntcConfig,IntcConfig->CpuBaseAddress);
//注册异常处理函数
Xil_ExceptionRegisterHandler(XIL_EXCEPTION_ID_INT,
(Xil_ExceptionHandler)XScuGic_InterruptHandler,
&GicInstancePtr);
//注册/绑定具体外设的中断服务函数(需要用户去关心)
XScuGic_Connect(&GicInstancePtr, XPS_GPIO_INT_ID,
(Xil_ExceptionHandler)XGpioPs_IntrHandler,
&Gpio);
//设置具体外设的中断相关的寄存器(使能、禁止、中断检测类型)(需要用户去关心)
/* Enable falling edge interrupts for all the pins in bank 0. */
XGpioPs_SetIntrType(&Gpio, XGPIOPS_BANK2 , 0xFFFFFFFF, 0x00000000, 0x00);
/* Set the handler for gpio interrupts. */
XGpioPs_SetCallbackHandler(&Gpio, &Gpio, IntrHandler);
//设置某位的中断使能(需要用户去关心)
XGpioPs_IntrEnable(&Gpio, XGPIOPS_BANK2, (1 << (PL_KEY - 54)));
//在GIC中允许该外设的中断源向Cpu发出中断
XScuGic_Enable(&GicInstancePtr, XPS_GPIO_INT_ID);
//开启总中断
Xil_ExceptionEnableMask(XIL_EXCEPTION_IRQ);
while(1)
{
if(flag > 0)
{
flag--;
XGpioPs_WritePin(&Gpio, PL_LED, 0x1);
usleep(500000);
XGpioPs_WritePin(&Gpio, PL_LED, 0x0);
usleep(500000);
}
}
}
标签:GPIO,MIO,EMIO,中断,ZYNQ,Gpio,XGpioPs,ID,PL
From: https://www.cnblogs.com/Lclone/p/16934208.html