• 【ZYNQ-嵌入式】zynq学习笔记(三)——GPIO中断软件配置


    第一步:书写SetupInterruptSystem设置中断系统函数

    (1)三个Exception:

    ①初始化ARM处理器异常句柄
    ②给IRQ异常处理注册程序(IRQ:中断请求)
    ③使能处理器中断

    代码如下:

    	/*
    	 * 初始化ARM处理器异常句柄
    	 */
    	Xil_ExceptionInit();
    	/*
    	 * 通过调用该函数,给IRQ异常处理注册程序(IRQ:中断请求)
    	 */
    	Xil_ExceptionRegisterHandler(XIL_EXCEPTION_ID_INT,
    				(Xil_ExceptionHandler)XScuGic_InterruptHandler,
    				GicInstancePtr);
    	/*
    	 * 使能处理器中断
    	 */
    	Xil_ExceptionEnableMask(XIL_EXCEPTION_IRQ);
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    (2)查找器件配置信息,并进行初始化:

    	/*
    	 * 查找器件配置信息,并进行初始化。
    	 */
    	XScuGic_Config *IntcConfig;
    	IntcConfig = XScuGic_LookupConfig(INTC_DEVICE_ID);
    	XScuGic_CfgInitialize(GicInstancePtr, IntcConfig,IntcConfig->CpuBaseAddress);
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    (3)两个XScuGic:

    ①关联中断处理函数。
    ②为GPIO使能中断。

    	/*
    	 * 关联中断处理函数
    	 */
    	XScuGic_Connect(GicInstancePtr, GpioIntrId,
    				(Xil_ExceptionHandler)IntrHandler,     //IntrHandler是我们自己要编写的中断服务函数!
    				(void *)Gpio);
    	/*
    	 * 为GPIO器件使能中断
    	 */
    	XScuGic_Enable(GicInstancePtr, GpioIntrId);
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    【注:后续添加头文件xscugic.h】
    【注:后续书写中断服务函数IntrHandler】

    (4)两个XGpioPs:

    ①设置MIO引脚“中断触发类型”。
    ②打开MIO中断使能信号。

    	/*
    	 * 设置MIO引脚“中断触发类型”。(在xgpiops.h中寻找相关宏定义)
    	 */
    	XGpioPs_SetIntrTypePin(Gpio, Key, XGPIOPS_IRQ_TYPE_EDGE_FALLING);  //下降沿触发
    	/*
    	 * 打开MIO中断使能信号。
    	 */
    	XGpioPs_IntrEnablePin(Gpio, Key);
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    【注:Key是“触发引脚”,稍后会定义为全局变量】

    其中,“中断触发类型”在xgpios.h中找到:
    在这里插入图片描述

    (5)补充头文件、宏定义和全局变量: Debug溯源法。
    【完整函数代码】

    #include"xgpiops.h"
    #include"xscugic.h"
    
    #define INTC_DEVICE_ID		XPAR_SCUGIC_SINGLE_DEVICE_ID
    
    XGpioPs Gpio;
    static u32 Key = 2;
    
    void SetupInterruptSystem(XScuGic *GicInstancePtr, XGpioPs *Gpio, u16 GpioIntrId)
    {
    	/*
    	 * 查找器件配置信息,并进行初始化。
    	 */
    	XScuGic_Config *IntcConfig;
    	IntcConfig = XScuGic_LookupConfig(INTC_DEVICE_ID);
    	XScuGic_CfgInitialize(GicInstancePtr, IntcConfig,IntcConfig->CpuBaseAddress);
    	/*
    	 * 初始化ARM处理器异常句柄
    	 */
    	Xil_ExceptionInit();
    	/*
    	 * 通过调用该函数,给IRQ异常处理注册程序(IRQ:中断请求)
    	 */
    	Xil_ExceptionRegisterHandler(XIL_EXCEPTION_ID_INT,
    				(Xil_ExceptionHandler)XScuGic_InterruptHandler,
    				GicInstancePtr);
    	/*
    	 * 使能处理器中断
    	 */
    	Xil_ExceptionEnableMask(XIL_EXCEPTION_IRQ);
    
    
    	/*
    	 * 关联中断处理函数
    	 */
    	XScuGic_Connect(GicInstancePtr, GpioIntrId,
    				(Xil_ExceptionHandler)IntrHandler,     //IntrHandler是我们自己要编写的中断服务函数!
    				(void *)Gpio);
    	/*
    	 * 为GPIO器件使能中断
    	 */
    	XScuGic_Enable(GicInstancePtr, GpioIntrId);
    
    	/*
    	 * 设置MIO引脚“中断触发类型”。(在xgpiops.h中寻找相关宏定义)
    	 */
    	XGpioPs_SetIntrTypePin(Gpio, Key, XGPIOPS_IRQ_TYPE_EDGE_FALLING);  //下降沿触发
    	/*
    	 * 打开MIO中断使能信号。
    	 */
    	XGpioPs_IntrEnablePin(Gpio, Key);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52

    第二步:自己书写中断服务函数

    注意!要和先前写的SetupInterruptSystem函数匹配!
    在这里插入图片描述
    注意,此处博主这是书写了最简单的服务函数。服务函数内部当然可以编写任何你想实现的程序!

    xxxx InterHandler(xxxx){
    	xxxxx;
    }
    
    • 1
    • 2
    • 3

    第三步:在main中的GPIO一般配置完成后,使用SetupInterruptSystem

    GPIO的一般配置在笔记(二)中已经写过:
    【ZYNQ-嵌入式】zynq学习笔记(二)—— GIPO的硬件配置和软件配置
    【注:需要添加一些宏定义和全局变量!】

    XScuGic Intc;
    static u32 Output_Pin_m = 0;  //GPIO管脚位号,具体要查看手册
    static u32 Input_Pin_m = 1;
    static u32 Key = 2;  //用于触发中断
    
    
    int main(void)
    {
    	printf("GPIO-MIO-TEST\n\r");
    	GPIO_INPUT_INIT(Input_Pin_m);
    	GPIO_OUTPUT_INIT(Output_Pin_m);
    
    	printf("GPIO-MIO-INTERUPT-TEST\n\r");
    	SetupInterruptSystem(&Intc,&Gpio,GPIO_INTERRUPT_ID);
    
    	u32 key_value;
    	while(1){
    		//读取按键状态
    		key_value = GPIO_Read(Input_Pin_m);
    		//按键状态写入LED
    		GPIO_Write(Output_Pin_m , ~key_value);
    	}
    	return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24

    附录:GPIO中断配置函数集【重要】

    #include
    #include"xgpiops.h"
    #include"xscugic.h"
    #include"xparameters.h"
    
    #define INTC_DEVICE_ID		XPAR_SCUGIC_SINGLE_DEVICE_ID
    #define GPIO_INTERRUPT_ID	XPAR_XGPIOPS_0_INTR    //GPIO中断号:52U
    
    XGpioPs Gpio;
    XScuGic Intc;
    static u32 Output_Pin_m = 0;  //GPIO管脚位号,具体要查看手册
    static u32 Input_Pin_m = 1;
    static u32 Key = 2;
    
    void SetupInterruptSystem(XScuGic *GicInstancePtr, XGpioPs *Gpio, u16 GpioIntrId);
    void IntrHandler(void);   //中断处理函数
    
    /***********************************
     * 设置中断系统函数
     ***********************************/
    void SetupInterruptSystem(XScuGic *GicInstancePtr, XGpioPs *Gpio, u16 GpioIntrId)
    {
    	/*
    	 * 查找器件配置信息,并进行初始化。
    	 */
    	XScuGic_Config *IntcConfig;
    	IntcConfig = XScuGic_LookupConfig(INTC_DEVICE_ID);
    	XScuGic_CfgInitialize(GicInstancePtr, IntcConfig,IntcConfig->CpuBaseAddress);
    	/*
    	 * 初始化ARM处理器异常句柄
    	 */
    	Xil_ExceptionInit();
    	/*
    	 * 通过调用该函数,给IRQ异常处理注册程序(IRQ:中断请求)
    	 */
    	Xil_ExceptionRegisterHandler(XIL_EXCEPTION_ID_INT,
    				(Xil_ExceptionHandler)XScuGic_InterruptHandler,
    				GicInstancePtr);
    	/*
    	 * 使能处理器中断
    	 */
    	Xil_ExceptionEnableMask(XIL_EXCEPTION_IRQ);
    
    
    	/*
    	 * 关联中断处理函数
    	 */
    	XScuGic_Connect(GicInstancePtr, GpioIntrId,
    				(Xil_ExceptionHandler)IntrHandler,     //IntrHandler是我们自己要编写的中断服务函数!
    				(void *)Gpio);
    	/*
    	 * 为GPIO器件使能中断
    	 */
    	XScuGic_Enable(GicInstancePtr, GpioIntrId);
    
    	/*
    	 * 设置MIO引脚“中断触发类型”。(在xgpiops.h中寻找相关宏定义)
    	 */
    	XGpioPs_SetIntrTypePin(Gpio, Key, XGPIOPS_IRQ_TYPE_EDGE_FALLING);  //下降沿触发
    	/*
    	 * 打开MIO中断使能信号。
    	 */
    	XGpioPs_IntrEnablePin(Gpio, Key);
    
    }
    /****************************************
     * 中断处理函数(中断服务函数)
     ****************************************/
    void IntrHandler(){
    	printf("INTERUPT!\n\r");
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72

    【注:必须先配置常规GPIO,才能进一步配置GPIO中断!】

  • 相关阅读:
    64 坐标系
    575. 分糖果(javascript)575. Distribute Candies
    css设置遮罩层(半透明)
    【LLM模型篇】LLaMA2 | Vicuna | EcomGPT等
    代码随想录算法训练营第五十二天|
    python随手小练1
    命令行工具集合busybox编译
    Openssl数据安全传输平台009:加密理论基础:哈希/非对称加密RSA/对称加密AES
    Java8中判断一个对象不为空存在一个类对象是哪个
    Python和Java代码实现:切线法求解一维最优化问题
  • 原文地址:https://blog.csdn.net/GalaxyerKw/article/details/126652118