实验目的
使用底板上的 PS 端的用户按键 PS_KEY1 通过中断控制核心板上 LED2 的亮灭
简介
Zynq 芯片的 PS 部分是基于使用双核 Cortex-A9 处理器和 GIC pl390 中断控制器的 ARM 架构。中断结
构与 CPU 紧密链接,并接受来自 I/O 外设(IOP)和可编程逻辑(PL)的中断。
补充
GIC pl390 中断控制器
GIC (Generic Interrupt Controller) 是一种在 ARM 架构中广泛使用的中断控制器,用于管理处理器核心与外部设备之间的中断请求。它支持多种类型的中断,并且能够高效地将中断分配给系统中的一个或多个 CPU 核心。GIC pl390 特别是 ARMv7 架构中使用的一个版本。
GIC pl390 主要特性
多核支持:GIC pl390 设计支持多核系统,允许将中断路由到一个或多个 CPU 核心,以实现负载均衡和提高系统的响应速度。
多种中断类型:
SGI (Software Generated Interrupts):由软件生成的中断,通常用于多核间的通信。
PPI (Private Peripheral Interrupts):每个 CPU 核心独有的中断,如定时器中断。
SPI (Shared Peripheral Interrupts):共享外围设备中断,可以被所有 CPU 核心访问。
优先级处理:GIC 支持不同级别的中断优先级,确保高优先级的中断可以优先得到处理。
中断目标选择:可以为每个中断设置目标 CPU 列表,灵活控制中断的分发。
中断使能/禁用:可以在 GIC 层面单独使能或禁用特定的中断。
中断分组:中断可以被分组,便于管理和配置。
安全扩展:支持 TrustZone 技术,提供安全和非安全状态下的中断处理机制。
硬件设计
直接沿用 gpio_mio工程的
软件设计
main.c 文件
/***************************** Include Files *********************************/
#include "xparameters.h"
#include "xgpiops.h"
#include "xscugic.h"
#include "xil_exception.h"
#include "xplatform_info.h"
#include <xil_printf.h>
#include "sleep.h"
/************************** Constant Definitions *****************************/
//以下常量映射到xparameters.h文件
#define GPIO_DEVICE_ID XPAR_XGPIOPS_0_DEVICE_ID //PS端GPIO器件ID
#define INTC_DEVICE_ID XPAR_SCUGIC_SINGLE_DEVICE_ID //通用中断控制器ID
#define GPIO_INTERRUPT_ID XPAR_XGPIOPS_0_INTR //PS端GPIO中断ID
//定义使用到的MIO引脚号
#define KEY 11 //KEY 连接到 MIO11
#define LED 0 //LED 连接到 MIO0
/************************** Function Prototypes ******************************/
static void intr_handler(void *callback_ref);
int setup_interrupt_system(XScuGic *gic_ins_ptr, XGpioPs *gpio, u16 GpioIntrId);
/**************************Global Variable Definitions ***********************/
XGpioPs gpio; //PS端GPIO驱动实例
XScuGic intc; //通用中断控制器驱动实例
u32 key_press; //KEY按键按下的标志
u32 key_val; //用于控制LED的键值
/************************** Function Definitions *****************************/
int main(void)
{
int status;
XGpioPs_Config *ConfigPtr; //PS 端GPIO配置信息
xil_printf("ljl Gpio interrupt test \r\n");
//根据器件ID查找配置信息
ConfigPtr = XGpioPs_LookupConfig(GPIO_DEVICE_ID);
if (ConfigPtr == NULL) {
return XST_FAILURE;
}
//初始化Gpio driver
XGpioPs_CfgInitialize(&gpio, ConfigPtr, ConfigPtr->BaseAddr);
//设置KEY所连接的MIO引脚的方向为输入
XGpioPs_SetDirectionPin(&gpio, KEY, 0);
//设置LED所连接的MIO引脚的方向为输出并使能输出
XGpioPs_SetDirectionPin(&gpio, LED, 1);//方向为输出
XGpioPs_SetOutputEnablePin(&gpio, LED, 1);//使能输出
XGpioPs_WritePin(&gpio, LED, 0x0);
//建立中断,出现错误则打印信息并退出
status = setup_interrupt_system(&intc, &gpio, GPIO_INTERRUPT_ID);
if (status != XST_SUCCESS) {
xil_printf("Setup interrupt system failed\r\n");
return XST_FAILURE;
}
//中断触发时,key_press为TURE,延时一段时间后判断按键是否按下,是则反转LED
while (1) {
if (key_press) {
usleep(20000);//20ms消抖
if (XGpioPs_ReadPin(&gpio, KEY) == 0) {
key_val = ~key_val;
XGpioPs_WritePin(&gpio, LED, key_val);
}
key_press = FALSE;
XGpioPs_IntrClearPin(&gpio, KEY); //清除按键KEY中断
XGpioPs_IntrEnablePin(&gpio, KEY); //使能按键KEY中断
}
}
return XST_SUCCESS;
}
//中断处理函数
// @param CallBackRef是指向上层回调引用的指针
static void intr_handler(void *callback_ref)
{
XGpioPs *gpio = (XGpioPs *) callback_ref;
//读取KEY按键引脚的中断状态,判断是否发生中断
if (XGpioPs_IntrGetStatusPin(gpio, KEY)){
key_press = TRUE;
XGpioPs_IntrDisablePin(gpio, KEY); //屏蔽按键KEY中断
}
}
//建立中断系统,使能KEY按键的下降沿中断
// @param GicInstancePtr是一个指向XScuGic驱动实例的指针
// @param gpio是一个指向连接到中断的GPIO组件实例的指针
// @param GpioIntrId是Gpio中断ID
// @return 如果成功返回XST_SUCCESS, 否则返回XST_FAILURE
int setup_interrupt_system(XScuGic *gic_ins_ptr, XGpioPs *gpio, u16 GpioIntrId)
{
int status;
XScuGic_Config *IntcConfig; //中断控制器配置信息
//查找中断控制器配置信息并初始化中断控制器驱动
IntcConfig = XScuGic_LookupConfig(INTC_DEVICE_ID);
if (NULL == IntcConfig) {
return XST_FAILURE;
}
status = XScuGic_CfgInitialize(gic_ins_ptr, IntcConfig,
IntcConfig->CpuBaseAddress);
if (status != XST_SUCCESS) {
return XST_FAILURE;
}
//为中断设置中断处理函数
status = XScuGic_Connect(gic_ins_ptr, GpioIntrId,
(Xil_ExceptionHandler) intr_handler, (void *) gpio);
if (status != XST_SUCCESS) {
return status;
}
//使能来自于Gpio器件的中断
XScuGic_Enable(gic_ins_ptr, GpioIntrId);
//设置KEY按键的中断类型为下降沿中断
XGpioPs_SetIntrTypePin(gpio, KEY, XGPIOPS_IRQ_TYPE_EDGE_FALLING);
//使能按键KEY中断
XGpioPs_IntrEnablePin(gpio, KEY);
//初始化异常
Xil_ExceptionInit();//这个里面是没有内容的,在这里是保证函数的完整性
//设置并使能中断异常
Xil_ExceptionRegisterHandler(XIL_EXCEPTION_ID_INT,
(Xil_ExceptionHandler) XScuGic_InterruptHandler, gic_ins_ptr);
Xil_ExceptionEnable();
return XST_SUCCESS;
}
参考官方示例代码
下载验证
完成比完美重要!!!
学习记录,侵权联系删除
来源:正点原子