GPIO 中断程序处理过程;
1.查找ID,初始化gpio,设置gpio为输入;
2.查找中断设备SCU GIC的ID,初始化中断;
3.初始化ARM处理器中断句柄,注册中断函数,使能处理器中断,涉及的三个函数,主要中断都要使用;
4.关联中断处理函数,中断发生时,具体要处理的函数,由用户自己写;根据中断号使能中断,GPIO公用52号中断;
5.设置中断触发方式,使能引脚中断。
注意:在中断处理函数中要适时关闭中断,不然会一直处于中断状态。用户程序要适时的清除中断状态,再开启中断,以便等待下一次中断的到来。
中断来的时候,先执行完中断处理程序,再回主程序继续执行程序。
/*
* main_mio_inter.c
*
* Created on: 2020年3月12日
* Author:
*/
#include "xparameters.h"
#include "xgpiops.h"
#include "xscugic.h"
#include "xil_exception.h"
#include "xplatform_info.h"
#include <xil_printf.h>
#include "sleep.h"
#define DeviceId XPAR_XGPIOPS_0_DEVICE_ID
#define INTC_DEVICE_ID XPAR_SCUGIC_SINGLE_DEVICE_ID
#define GPIO_INTERRUPT_ID XPAR_XGPIOPS_0_INTR //52号中断
#define XGPIOPS_IRQ_TYPE XGPIOPS_IRQ_TYPE_EDGE_FALLING//下降沿触发
#define mio_key 50
#define mio_led 7
XScuGic_Config *IntcConfig; /* Instance of the interrupt controller */
XScuGic Intc; /* The Instance of the Interrupt Controller Driver */
XGpioPs_Config *ConfigPtr;
XGpioPs Gpio;
u32 key_press=0;
u32 led_value=1;
void SetupInterruptSystem(XScuGic *GicInstancePtr, XGpioPs *Gpio,u16 GpioIntrId);
void IntrHandler( );
int main(){
xil_printf("GPIO Interrupt Example Test \r\n");
/* Initialize the Gpio driver. */
ConfigPtr = XGpioPs_LookupConfig(DeviceId);
if (ConfigPtr == NULL) {
return XST_FAILURE;
}
XGpioPs_CfgInitialize(&Gpio, ConfigPtr, ConfigPtr->BaseAddr);
//设置输入和输出
XGpioPs_SetDirectionPin(&Gpio, mio_key, 0x0);
XGpioPs_SetDirectionPin(&Gpio, mio_led, 1);
//中断设置
SetupInterruptSystem(&Intc, &Gpio, GPIO_INTERRUPT_ID);
//按键值输出到led
while(1){
if (key_press){
led_value=~led_value;
key_press=0;
//清除之前的中断状态
XGpioPs_IntrClearPin(&Gpio, mio_key);
XGpioPs_WritePin(&Gpio, mio_led,led_value); //key_value值写入led
//延时消抖200ms
usleep(200000);
//重新开启MIO中断
XGpioPs_IntrEnablePin(&Gpio, mio_key);
}
}
}
void SetupInterruptSystem(XScuGic *GicInstancePtr, XGpioPs *Gpio,
u16 GpioIntrId)
{
//查找设备ID,并初始化
IntcConfig = XScuGic_LookupConfig(INTC_DEVICE_ID);
XScuGic_CfgInitialize(GicInstancePtr, IntcConfig,
IntcConfig->CpuBaseAddress);
/****************所有中断都要使用************************************/
//初始化ARM处理器中断句柄
Xil_ExceptionInit();
// IRQ异常,注册中断处理函数
Xil_ExceptionRegisterHandler(XIL_EXCEPTION_ID_INT,
(Xil_ExceptionHandler)XScuGic_InterruptHandler,
GicInstancePtr);
//使能处理器的中断
Xil_ExceptionEnableMask(XIL_EXCEPTION_IRQ);
/*******************************************************************/
//关联中断处理函数,中断发生时,具体要干的事
XScuGic_Connect(GicInstancePtr, GpioIntrId,
(Xil_ExceptionHandler)IntrHandler,
(void *)Gpio);
//使能GPIO器件中断
XScuGic_Enable(GicInstancePtr, GpioIntrId);
//设置mio引脚中断触发类型: 下降沿
XGpioPs_SetIntrTypePin(Gpio, mio_key, XGPIOPS_IRQ_TYPE);
//使能MIO引脚中断使能
XGpioPs_IntrEnablePin(Gpio, mio_key);
}
void IntrHandler( ){
xil_printf("MIO inter detected!\n\t");
key_press=1;
//关闭中断
XGpioPs_IntrDisablePin(&Gpio, mio_key);
}