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);
}