前面的部分请参考:https://blog.csdn.net/weixin_42066185/article/details/104066170
将上面的例子修改成为中断模式情况:
/*
* main.c
*
* Created on: 2020年1月21日
* Author: Scottar
*/
#include "stdio.h"
#include "xparameters.h"
#include "xgpiops.h"
#include "xscugic.h"
#define GPIO_DEVICE_ID XPAR_XGPIOPS_0_DEVICE_ID
#define INTC_DEVICE_ID XPAR_SCUGIC_SINGLE_DEVICE_ID //GIC只有一个所以就是0U
#define EMIO_LED0 57
#define EMIO_LED1 56
#define EMIO_LED2 55
#define EMIO_LED3 54
#define EMIO_KEY0 61
#define EMIO_KEY1 60
#define EMIO_KEY2 59
#define EMIO_KEY3 58
XGpioPs_Config *ConfigPtr; //结构体 共有两个参数,一个参数是id 一个是器件的及地址
XScuGic_Config *IntcConfig; /* Instance of the interrupt controller */ //终端控制器的配置信息
XGpioPs Gpio; /* The driver instance for GPIO Device. */
XScuGic Intc; /* The Instance of the Interrupt Controller Driver */ //终端控制器的实例
//GPIO的中断号就是52
#define GPIO_INTERRUPT_ID XPAR_XGPIOPS_0_INTR
void SetupInterruptSystem(XScuGic *GicInstancePtr, XGpioPs *Gpio,
u16 GpioIntrId);
void IntrHandler();
u32 key_down = 0;
u32 key0=0;
u32 key1=0;
u32 key2=0;
u32 key3=0;
//
//
//#define XGPIOPS_DEVICE_MAX_PIN_NUM (u32)118 /**< Max pins in the Zynq GPIO device
// * 0 - 31, Bank 0
// * 32 - 53, Bank 1
// * 54 - 85, Bank 2
// * 86 - 117, Bank 3
int main(){
u32 key_value;
print("GPIO MIO control led ");
//初始化GPIO的驱动
/* Initialize the GPIO driver. */
//根据器件的id 然后查找器件的配置信息
ConfigPtr = XGpioPs_LookupConfig(GPIO_DEVICE_ID);
//初始化gpio 驱动
XGpioPs_CfgInitialize(&Gpio, ConfigPtr,ConfigPtr->BaseAddr);
//将GPIo的方向设置成为输出
//(0是输入 1 是输出)
XGpioPs_SetDirectionPin(&Gpio, EMIO_LED0, 1);
XGpioPs_SetDirectionPin(&Gpio, EMIO_LED1, 1);
XGpioPs_SetDirectionPin(&Gpio, EMIO_LED2, 1);
XGpioPs_SetDirectionPin(&Gpio, EMIO_LED3, 1);
//(0是输入 1 是输出) 设定成按键的读入的状态
XGpioPs_SetDirectionPin(&Gpio, EMIO_KEY0, 0);
XGpioPs_SetDirectionPin(&Gpio, EMIO_KEY1, 0);
XGpioPs_SetDirectionPin(&Gpio, EMIO_KEY2, 0);
XGpioPs_SetDirectionPin(&Gpio, EMIO_KEY3, 0);
//0 是关闭输出使能 1 是打开输出使能
XGpioPs_SetOutputEnablePin(&Gpio, EMIO_LED0, 1);
XGpioPs_SetOutputEnablePin(&Gpio, EMIO_LED1, 1);
XGpioPs_SetOutputEnablePin(&Gpio, EMIO_LED2, 1);
XGpioPs_SetOutputEnablePin(&Gpio, EMIO_LED3, 1);
//写数据到GPIO的输出的引脚
//XGpioPs_WritePin(&Gpio, MIO0_LED, 1);
SetupInterruptSystem(&Intc, &Gpio, GPIO_INTERRUPT_ID);
print("we are going in while ");
while(1){
//
// //读取按键的状态
// key_value = XGpioPs_ReadPin(&Gpio,EMIO_KEY0);
//
// //将按键的状态写入led
// XGpioPs_WritePin(&Gpio, EMIO_LED0, ~key_value);
//
// //读取按键的状态
// key_value = XGpioPs_ReadPin(&Gpio,EMIO_KEY1);
//
// //将按键的状态写入led
// XGpioPs_WritePin(&Gpio, EMIO_LED1, ~key_value);
//
// //读取按键的状态
// key_value = XGpioPs_ReadPin(&Gpio,EMIO_KEY2);
//
// //将按键的状态写入led
// XGpioPs_WritePin(&Gpio, EMIO_LED2, ~key_value);
//
// //读取按键的状态
// key_value = XGpioPs_ReadPin(&Gpio,EMIO_KEY3);
//
// //将按键的状态写入led
// XGpioPs_WritePin(&Gpio, EMIO_LED3, ~key_value);
if (key_down == 1) // 表示四个按键中有按键被按下
{
key_down =0; // 复位这个转来,以便下次再继续进行检测
if(key0==1) // 按键0被按下
{
key0=0;
key_value = XGpioPs_ReadPin(&Gpio,EMIO_LED0);
key_value = ~key_value;
XGpioPs_WritePin(&Gpio, EMIO_LED0, key_value);
}
if(key1==1) // 按键1被按下
{
key1=0;
key_value = XGpioPs_ReadPin(&Gpio,EMIO_LED1);
key_value = ~key_value;
XGpioPs_WritePin(&Gpio, EMIO_LED1, key_value);
}
if(key2==1) // 按键2被按下
{
key2=0;
key_value = XGpioPs_ReadPin(&Gpio,EMIO_LED2);
key_value = ~key_value;
XGpioPs_WritePin(&Gpio, EMIO_LED2, key_value);
}
if(key3==1){ // 按键3被按下
key3=0;
key_value = XGpioPs_ReadPin(&Gpio,EMIO_LED3);
key_value = ~key_value;
XGpioPs_WritePin(&Gpio, EMIO_LED3, key_value);
}
}
}
return 0;
}
void SetupInterruptSystem(XScuGic *GicInstancePtr, XGpioPs *Gpio,
u16 GpioIntrId)
{
//查找器件的配置信息,也就是GIC,并且进行初始化
IntcConfig = XScuGic_LookupConfig(INTC_DEVICE_ID);
XScuGic_CfgInitialize(GicInstancePtr, IntcConfig,IntcConfig->CpuBaseAddress);
//初始化arm一场的春丽
Xil_ExceptionInit();
//中断请求的异常,注册异常处理的程序
Xil_ExceptionRegisterHandler(XIL_EXCEPTION_ID_INT,
(Xil_ExceptionHandler)XScuGic_InterruptHandler,
GicInstancePtr);
/* Enable interrupts in the Processor. */
Xil_ExceptionEnableMask(XIL_EXCEPTION_IRQ);
/*
* Connect the device driver handler that will be called when an
* interrupt for the device occurs, the handler defined above performs
* the specific interrupt processing for the device.
*/
//关联中断处理函数
XScuGic_Connect(GicInstancePtr, GpioIntrId,
(Xil_ExceptionHandler)IntrHandler,
(void *)Gpio);
//进行中断的配置
/* Enable falling edge interrupts for all the pins in bank 0. */
//XGpioPs_SetIntrType(Gpio, GPIO_BANK, 0x00, 0xFFFFFFFF, 0x00);
XGpioPs_SetIntrTypePin(Gpio, EMIO_KEY0,XGPIOPS_IRQ_TYPE_EDGE_FALLING);
XGpioPs_SetIntrTypePin(Gpio, EMIO_KEY1,XGPIOPS_IRQ_TYPE_EDGE_FALLING);
XGpioPs_SetIntrTypePin(Gpio, EMIO_KEY2,XGPIOPS_IRQ_TYPE_EDGE_FALLING);
XGpioPs_SetIntrTypePin(Gpio, EMIO_KEY3,XGPIOPS_IRQ_TYPE_EDGE_FALLING);
/* Enable the GPIO interrupts of Bank 0. */
XGpioPs_IntrEnablePin(Gpio,EMIO_KEY0);
XGpioPs_IntrEnablePin(Gpio,EMIO_KEY1);
XGpioPs_IntrEnablePin(Gpio,EMIO_KEY2);
XGpioPs_IntrEnablePin(Gpio,EMIO_KEY3);
/* Enable the interrupt for the GPIO device. */
XScuGic_Enable(GicInstancePtr, GpioIntrId);
}
void IntrHandler()
{
key_down = 1 ; //表示有按键被按下来了
usleep(200000); //实现延时消除对按键抖动的检测
if (XGpioPs_IntrGetStatusPin(&Gpio,EMIO_KEY0)){ //检测是否是按键0 的标志位被置位了
key0=1;
print("Key0 is pressed\r\n");
XGpioPs_IntrClearPin(&Gpio,EMIO_KEY0);
}
if (XGpioPs_IntrGetStatusPin(&Gpio,EMIO_KEY1)){
key1=1;
print("Key1 is pressed\r\n");
XGpioPs_IntrClearPin(&Gpio,EMIO_KEY1);
}
if (XGpioPs_IntrGetStatusPin(&Gpio,EMIO_KEY2)){
key2=1;
print("Key2 is pressed\r\n");
XGpioPs_IntrClearPin(&Gpio,EMIO_KEY2);
}
if (XGpioPs_IntrGetStatusPin(&Gpio,EMIO_KEY3)){
key3=1;
print("Key3 is pressed\r\n");
XGpioPs_IntrClearPin(&Gpio,EMIO_KEY3);
}
}
3、实验结果
通过前后的按键可以,四个按键可以分别控制四个灯的亮灭的情况