当前位置: 首页 > news >正文

ZYNQ笔记(三):GPIO 中断

版本:Vivado2020.2(Vitis)

任务:使用 GPIO 中断实现按键 (PL端) KEY控制 (PS端) LED亮灭翻转

目录

 一、介绍

二、硬件设计

三、软件设计

四、效果


 一、介绍

        ZYNQ 的 GPIO 中断功能允许 PS 端通过硬件中断快速响应GPIO引脚的电平变化(如按键按下、传感器触发等),无需轮询,适合实时性要求高的场景。ZYNQ GPIO支持以下中断触发方式:(通常推荐边沿触发)

  • 边沿触发:上升沿(RISING)、下降沿(FALLING)、双边沿(BOTH)。

  • 电平触发:高电平(LEVEL_HIGH)、低电平(LEVEL_LOW)。

二、硬件设计

        (1)ZYNQ 的配置不再赘述,如Bank电压、UART串口配置(用于debug)、去掉未使用端口等等。其次PL端KEY用了1个EMIO管脚,设置EMIO位宽为1。

        (2)最后整体 bd 设计部分如图所示:设计检查、Generate Output Products、 Create HDL Wrapper、管脚约束、Gnerate Bitstream、Export Hardware(包含比特流文件)、启动Vitis

三、软件设计

#include "stdio.h"
#include "xil_printf.h"
#include "xparameters.h"
#include "xil_exception.h"
#include "xgpiops.h"
#include "xscugic.h"
#include "sleep.h"

//===========================自定义宏===========================//

#define GPIO_DEVICE_ID  	XPAR_XGPIOPS_0_DEVICE_ID     //宏定义器件ID
#define INTC_DEVICE_ID		XPAR_SCUGIC_SINGLE_DEVICE_ID //宏定义中断控制器(GIC)ID
#define GPIO_INTERRUPT_ID	XPAR_XGPIOPS_0_INTR          //宏定义GPIO中断号

#define MIO_LED 	        7	//宏定义LED管脚(PS端LED,根据开发板LED引脚设值,这里对应GPIO MIO 7)
#define EMIO_KEY  	        54	//宏定义KEY管脚(PL端KEY,根据EMIO管脚分配设值,这里对应GPIO 54)

//===========================实例化===========================//

XGpioPs Gpio;				    //GPIO驱动实例
XScuGic Intc;					//中断控制器驱动实例

//===========================函数变量声明===========================//

static void Gpio_Init();	//GPIO初始化
static void IntrHandler();	//中断处理函数
static void Setup_Intr_System(XScuGic *GicInstancePtr, XGpioPs *Gpio, u16 GpioIntrId); //建立中断系统

static u32 key_value;

int main()
{
	xil_printf("GPIO Interrupt Test \r\n");

	Gpio_Init();
	Setup_Intr_System(&Intc,&Gpio,GPIO_INTERRUPT_ID);

	while(1)
	return 0;
}
//===========================中断处理函数===========================//
void IntrHandler()
{
	//debug打印字符串
	xil_printf("Interrupt detected! \n\r");
	//屏蔽按键中断
	XGpioPs_IntrDisablePin(&Gpio, EMIO_KEY);
	//按键消抖延时20ns(不消抖会反复中断)
	usleep(20000);
	//翻转数据并写入LED
	key_value = ~key_value;
	XGpioPs_WritePin(&Gpio, MIO_LED, key_value);
	//清除EMIO_KEY中断状态(不清除会一直触发中断,导致死循环)
	XGpioPs_IntrClearPin(&Gpio, EMIO_KEY);
	//重新使能按键中断
	XGpioPs_IntrEnablePin(&Gpio, EMIO_KEY);
}
//===========================GPIO初始化函数===========================//
void Gpio_Init()
{
	//定义GPIO配置信息(指针类型)
	XGpioPs_Config * ConfigPtr;
	//根据器件ID,查找GPIO配置信息
	ConfigPtr = XGpioPs_LookupConfig(GPIO_DEVICE_ID);
	//初始化器件驱动
	XGpioPs_CfgInitialize(&Gpio, ConfigPtr, ConfigPtr->BaseAddr);
	//GPIO方向设置(0输入/1输出)
	XGpioPs_SetDirectionPin(&Gpio, MIO_LED,  1);
	XGpioPs_SetDirectionPin(&Gpio, EMIO_KEY, 0);
	//设置输出使能(1使能)
	XGpioPs_SetOutputEnablePin(&Gpio, MIO_LED, 1);
}

//===========================建立中断系统===========================//
/* 建立中断系统,使能EMIO_KEY按键的下降沿产生中断
 * @param GicInstancePtr 是一个指向 XScuGic 驱动实例的指针
 * @param Gpio 是一个指向连接到中断的 GPIO 驱动实例的指针
 * @param GpioIntrId 是 Gpio中断控制器ID
 */
void Setup_Intr_System(XScuGic *GicInstancePtr, XGpioPs *Gpio, u16 GpioIntrId)
{
    //定义中断控制器配置信息(指针类型)
	XScuGic_Config * IntcConfig;
	//根据中断控制器ID,查找GIC配置信息(Generic Interrupt Controller(通用)中断控制器)
	IntcConfig = XScuGic_LookupConfig(INTC_DEVICE_ID);
	//初始化中断控制器驱动
	XScuGic_CfgInitialize(GicInstancePtr, IntcConfig, IntcConfig->CpuBaseAddress);
    //设置并打开中断异常处理功能
	Xil_ExceptionInit();
	Xil_ExceptionRegisterHandler(XIL_EXCEPTION_ID_INT,
			(Xil_ExceptionHandler)XScuGic_InterruptHandler,
			GicInstancePtr);
	Xil_ExceptionEnable();
	//为GPIO中断设置中断处理函数(IntrHandler为自己编写的中断函数)
	XScuGic_Connect(GicInstancePtr, GpioIntrId,
				(Xil_ExceptionHandler)IntrHandler,
				(void *)&Gpio);
	//使能处理器中断
	Xil_ExceptionEnableMask(XIL_EXCEPTION_IRQ);
	//使能来自GPIO器件的中断
	XScuGic_Enable(GicInstancePtr, GpioIntrId);
	//设置GPIO引脚的中断类型(设置EMIO_KEY引脚下降沿时中断)
	XGpioPs_SetIntrTypePin(Gpio, EMIO_KEY, XGPIOPS_IRQ_TYPE_EDGE_FALLING);
	//使能来自GPIO引脚的中断
	XGpioPs_IntrEnablePin(Gpio, EMIO_KEY);
}

四、效果

        上板启动串口发送测试信息,之后每当按一次按键时,串口发送中断debug信息,同时LED灯状态翻转一次。

相关文章:

  • wordpress ip设置baidu优化
  • html 存入wordpress抖音seo优化排名
  • 苏州高端网站建设设计公司哪家好如何开发微信小程序
  • 酒店用品网站建设网站做优化好还是推广好
  • 公司网站建设开发维护工作/自己怎么免费做网站
  • 中企动力做的网站山西太原/百度站长平台工具
  • 3DMAX笔记-UV知识点和烘焙步骤
  • Kotlin 学习-集合
  • Stable Diffusion+Pyqt5: 实现图像生成与管理界面(带保存 + 历史记录 + 删除功能)——我的实验记录(结尾附系统效果图)
  • 【C++基础-关键字】:extern
  • 深入理解Java Optional:告别NullPointerException的优雅方式
  • PMP 考试以及学习资料
  • 艾尔登法环地图不能使用鼠标移动或点击传送点原因和设置方法
  • 计算机视觉与深度学习 | 视觉里程计(Visual Odometry, VO)学习思路总结
  • K8S学习之基础七十五:istio实现灰度发布
  • 探秘Transformer系列之(25)--- KV Cache优化之处理长文本序列
  • 架构师论文《论模型驱动软件开发方法在智能制造转型实践中的应用》
  • ​MySQL面试题:索引的底层原理与优化策略​
  • Langflow 远程命令执行漏洞复现(CVE-2025-3248)(附脚本)
  • Python代码缩进统一规范
  • 微信小程序事件详解
  • 6.3es新特性web worker
  • 基于 OpenHarmony 5.0 的星闪轻量型设备应用开发——Ch2 OpenHarmony LiteOS-M 内核应用开发
  • 【系统架构】AI时代下,系统架构师如何修炼
  • 2025.4.8 dmy NOI模拟赛总结(转化贡献方式 dp, 交互(分段函数找断点),SAM上计数)
  • 【spark-submit】--提交任务