MIO中斷分析

 

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

}



 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章