ZYNQ-GPIO之MIO中断
中断:打断CPU执行正常的程序,转而处理紧急的程序,然后返回原程序暂停的程序继续执行。
如下图,此处紧急程序就叫中断:
GPIO中断各寄存器:
实验任务:
使用GPIO的MIO中断功能,实现PS端的按键控制核心板上的led亮灭
实验流程图:
block design与MIO那节的system一致
vitis代码:
#include <stdio.h>
#include "xparameters.h"
#include "xgpiops.h"
#include "sleep.h"
#include "xscugic.h"
#include "xil_exception.h"
#include <xil_printf.h>
#include "xplatform_info.h"#define GPIO_DEVICE_ID XPAR_XGPIOPS_0_DEVICE_ID
#define INTC_DEVICE_ID XPAR_SCUGIC_SINGLE_DEVICE_ID
//GPIO的中断号:XPAR_XGPIOPS_0_INTR,即52
#define GPIO_INTERRUPT_ID XPAR_XGPIOPS_0_INTR
#define MIO0_LED 0 //MIO 0
#define MIO12_KEY 11 //MIO11按键//#define EMIO_KEY1 55
XGpioPs_Config *ConfigPtr;
XScuGic_Config *IntcConfig; //GIC配置信息的驱动实例XGpioPs Gpio; //GPIO器件的驱动实例
XScuGic Intc; //GIC器件的驱动实例void SetupInterruptSystem(XScuGic *GicInstancePtr, XGpioPs *Gpio,u16 GpioIntrId);
void IntrHandler();u32 key_press = 0;int main(){u32 led_value =0; //获取按键值printf("GPIO interrupt TEST SUCCESS!\n\r");//对GPIO进行初始化(两步) /* Initialize the GPIO driver. *///第一步:根据器件ID去查找器件的配置信息ConfigPtr = XGpioPs_LookupConfig(GPIO_DEVICE_ID);//第二步:对GPIO的驱动进行初始化XGpioPs_CfgInitialize(&Gpio, ConfigPtr,ConfigPtr->BaseAddr);//设置引脚的方向,0为输入,1为输出XGpioPs_SetDirectionPin(&Gpio, MIO0_LED, 1);//设置按键PS_KEY0为输入XGpioPs_SetDirectionPin(&Gpio, MIO12_KEY, 0);//设置输出使能,1:使能输出,0:不使能输出XGpioPs_SetOutputEnablePin(&Gpio, MIO0_LED, 1);//中断配置SetupInterruptSystem(&Intc, &Gpio, GPIO_INTERRUPT_ID);while(1){if(key_press){led_value = ~led_value;key_press = 0;//清除之前的中断状态寄存器的值XGpioPs_IntrClearPin(&Gpio,MIO12_KEY);//将led_value的值写入ledXGpioPs_WritePin(&Gpio, MIO0_LED, led_value);//延时200ms消抖usleep(200000);XGpioPs_IntrEnablePin(&Gpio,MIO12_KEY);}}return 0;
}void SetupInterruptSystem(XScuGic *GicInstancePtr, XGpioPs *Gpio,u16 GpioIntrId)
{//根据中断控制器(GIC)的器件ID来查找配置信息IntcConfig = XScuGic_LookupConfig(INTC_DEVICE_ID);//根据查找到的配置信息初始化中断控制器(GIC)XScuGic_CfgInitialize(GicInstancePtr, IntcConfig,IntcConfig->CpuBaseAddress);//异常初始化(初始化ARM处理器异常句柄)Xil_ExceptionInit();//注册中断请求异常的处理程序Xil_ExceptionRegisterHandler(XIL_EXCEPTION_ID_INT,(Xil_ExceptionHandler)XScuGic_InterruptHandler,GicInstancePtr);//使能处理器的中断Xil_ExceptionEnableMask(XIL_EXCEPTION_IRQ);//关联GPIO中断处理程序XScuGic_Connect(GicInstancePtr, GpioIntrId,(Xil_ExceptionHandler)IntrHandler,(void *)Gpio);//为GPIO器件使能中断XScuGic_Enable(GicInstancePtr, GpioIntrId);//设置MIO中断触发类型为下降沿触发XGpioPs_SetIntrTypePin(Gpio,MIO12_KEY,XGPIOPS_IRQ_TYPE_EDGE_FALLING);//打开MIO中的中断使能信号XGpioPs_IntrEnablePin(Gpio,MIO12_KEY);}//定义一个简单的中断服务函数,即检测到中断产生(按键按下)就打印这个信息
void IntrHandler(){printf("interrupt detected\n\r");key_press = 1;XGpioPs_IntrDisablePin(&Gpio,MIO12_KEY);
}
实现:检测到按键按下,核心板上的红灯会在亮灭状态间进行翻转,即中断产生,会打印检测到中断产生的信息。