实验平台:黑金AXU3EG
开发环境:vivado2020.1、vitis2020.1
软件设计思路:在中断服务子程序中,对按键中断标志位赋值,每次进入中断,执行终端服务子程序时,将按键中断标志位置一,之后软件除能按键中断,在中断相关设置函数中,需要为IRQ异常注册处理程序,之后关联中断服务程序
为IRQ异常注册处理程序
/*初始化ARM处理器异常句柄和
* 给IRQ异常注册处理程序
* 每次中断时都需要调用
* 原封不动的复制粘贴就OK*/
//初始化ARM处理器异常句柄
Xil_ExceptionInit();
//给IRQ异常注册处理程序
Xil_ExceptionRegisterHandler(XIL_EXCEPTION_ID_INT,
(Xil_ExceptionHandler)XScuGic_InterruptHandler,
GicInstancePtr);
Xil_ExceptionEnable();
关联中断服务程序
= XScuGic_Connect(GicInstancePtr, GpioIntrId,
(Xil_ExceptionHandler)IntrHandler,
(void *)Gpio); //用来关联中断服务子程序
整体代码:
#include "xparameters.h" //器件参数信息
#include "xgpiops.h" //包含PS GPIO的函数声明
#include "xstatus.h" //包含XST_FAILURE和XST_SUCCESS的宏定义
#include "xplatform_info.h"
#include <xil_printf.h> //包含print()函数
#include "sleep.h" //sleep()函数
#include "xscugic.h"
#include "xil_exception.h"
#define GPIO_DEVICE_ID XPAR_XGPIOPS_0_DEVICE_ID //定义器件ID号
#define GPIO_INTERRUPT_ID XPAR_XGPIOPS_0_INTR //PS端GPIO中断ID号
#define INTC_DEVICE_ID XPAR_SCUGIC_SINGLE_DEVICE_ID //通用中断控制器ID
#define PS_LED 40 //PS端LED宏定义
#define PS_KEY 26 //PS端KEY宏定义
XGpioPs Gpio; //GPIO设备的驱动程序实例
XScuGic Intc; //通用中断控制器驱动实例
int KEY_FLAG; //按键中断标志位
int LED_FLAG = 0; //LED状态标志位
int SetupInterruptSystem(XScuGic *GicInstancePtr, XGpioPs *Gpio,
u16 GpioIntrId);
static void IntrHandler(void *CallBackRef);
int main(void)
{
int Status;
//设备配置信息结构体指针
XGpioPs_Config *ConfigPtr;
print("MIO test \r\n");
//查询设备器件ID号
ConfigPtr = XGpioPs_LookupConfig(GPIO_DEVICE_ID);
if(ConfigPtr == NULL)
{
return XST_FAILURE;
}
//初始化 GPIO driver
XGpioPs_CfgInitialize(&Gpio, ConfigPtr, ConfigPtr->BaseAddr);
//设置指定引脚的方向
XGpioPs_SetDirectionPin(&Gpio, PS_LED, 1);
XGpioPs_SetDirectionPin(&Gpio, PS_KEY, 0);
//设置指定引脚的输出使能
XGpioPs_SetOutputEnablePin(&Gpio, PS_LED, 1);
Status = SetupInterruptSystem(&Intc,&Gpio,GPIO_INTERRUPT_ID);
if(Status != XST_SUCCESS)
{
print("Setup interrupt system failed \r\n ");
return XST_FAILURE;
}
while(1)
{
if(KEY_FLAG)
{
LED_FLAG = ~LED_FLAG;
usleep(10000);
XGpioPs_WritePin(&Gpio, PS_LED, LED_FLAG);
}
KEY_FLAG = 0;
XGpioPs_IntrClearPin(&Gpio,PS_KEY);
XGpioPs_IntrEnablePin(&Gpio,PS_KEY);
}
//返回值为XGpioPs 实例/驱动程序初始化状态值
return XST_SUCCESS;
}
void IntrHandler(void *CallBackRef)
{
XGpioPs *Gpio = (XGpioPs *)CallBackRef;
if(XGpioPs_IntrGetStatusPin(Gpio, PS_KEY))
{
print("interrupt \r\n");
KEY_FLAG = 1;
//按键进入中断后 标志位置一 屏蔽按键中断
XGpioPs_IntrDisablePin(Gpio, PS_KEY);
}
}
int SetupInterruptSystem(XScuGic *GicInstancePtr, XGpioPs *Gpio,
u16 GpioIntrId)
{
int Status;
//中断控制器配置信息
XScuGic_Config *IntcConfig;
//查找中断控制器配置信息并初始化中断控制器驱动 并进行初始化
IntcConfig = XScuGic_LookupConfig(INTC_DEVICE_ID);
if (NULL == IntcConfig) {
return XST_FAILURE;
}
Status = XScuGic_CfgInitialize(GicInstancePtr, IntcConfig,
IntcConfig->CpuBaseAddress);
if (Status != XST_SUCCESS) {
return XST_FAILURE;
}
/*初始化ARM处理器异常句柄和
* 给IRQ异常注册处理程序
* 每次中断时都需要调用
* 原封不动的复制粘贴就OK*/
//初始化ARM处理器异常句柄
Xil_ExceptionInit();
//给IRQ异常注册处理程序
Xil_ExceptionRegisterHandler(XIL_EXCEPTION_ID_INT,
(Xil_ExceptionHandler)XScuGic_InterruptHandler,
GicInstancePtr);
Xil_ExceptionEnable();
//为中断设置中断处理函数(关联中断服务子程序)
Status = XScuGic_Connect(GicInstancePtr, GpioIntrId,
(Xil_ExceptionHandler)IntrHandler,
(void *)Gpio);
if (Status != XST_SUCCESS)
{
return XST_FAILURE;
}
//使能来自GPIO的中断
XScuGic_Enable(GicInstancePtr, GpioIntrId);
//设置引脚中断类型 设置按键下降沿中断
XGpioPs_SetIntrTypePin(Gpio, PS_KEY, XGPIOPS_IRQ_TYPE_EDGE_FALLING);
//使能按键中断
XGpioPs_IntrEnablePin(Gpio, PS_KEY);
return XST_SUCCESS;
}