什么是中断处理函数(IRQHandler)的标准流程?

您所在的位置:网站首页 嵌入式ADC是什么 什么是中断处理函数(IRQHandler)的标准流程?

什么是中断处理函数(IRQHandler)的标准流程?

2024-07-08 22:37| 来源: 网络整理| 查看: 265

大家好,我是痞子衡,是正经搞技术的痞子。今天痞子衡给大家介绍的是以i.MXRT的GPIO模块为例谈谈中断处理函数(IRQHandler)的标准流程。

在痞子衡旧文 《串口(UART)自动波特率识别程序设计与实现(中断)》里,我们利用了 GPIO 模块内部集成的 I/O 边沿检测功能完成了 RXD 信号下降沿的捕捉,这里涉及到了 GPIO 中断处理函数。中断处理函数 IRQHandler 是嵌入式里非常特殊的一类函数,它们是嵌入式系统能够实时完成任务的关键所在,任何一个中断处理函数都需要被谨慎对待。

上面那篇旧文里,痞子衡写的 GPIO 中断处理函数其实是有一点瑕疵的,虽然不影响最终波特率识别功能,但其并不是标准流程写法。今天痞子衡就和大家聊一聊什么是中断处理函数的标准流程:

一、GPIO模块中断简介

GPIO 基本上可以说是 MCU 里最入门级的外设了,我们先来简单看一下 i.MXRT1011 里 GPIO 模块功能。

1.1 GPIO 一般设计

i.MXRT 里每组 GPIO 最大包含 32 个 Pin,正好对应 32bit 寄存器,下面是 GPIO 三大基础寄存器:

GDIR[31:0] - 配置 Pin 的输入/输出方向(仅当 IOMUXC 里配置为 GPIO 模式) DR[31:0] - 设置 Pin 输出电平 PSR[31:0] - 保存 Pin 输入电平(以 ipg_clk_s 时钟来采样)

操作上述 GPIO 外设寄存器的前提条件是在 IOMUXC 模块里已将 Pin 功能模式配为 GPIO (因为每个 Pin 可能被多种外设UART/Timer等复用)。比如文章开头提及的那篇旧文里我们用于波特率检测的 GPIO_09 引脚,它有如下八种复用功能,其中 Alt5 功能是 GPIO。

将 GPIO_09 引脚设为 GPIO 功能模式后,还需要根据应用场景进一步配置其 Pad 属性,下图是 Pad 内部电路结构,我们可以配置的属性有很多,比如驱动强度、速度等级、上下拉等,这些也是在 IOMUXC 模块里完成的。

在串口波特率识别检测场景里,我们需要在 IOMUXC 模块里将 GPIO_09 引脚配置为 GPIO 模式,并且相应配置 Pad 属性(主要是使能内部上拉,因为串口信号 Idle 状态是高电平),示例代码如下:

#include "fsl_iomuxc.h" void io_pin_config(void) {     CLOCK_EnableClock(kCLOCK_Iomuxc);           /* iomuxc clock (iomuxc_clk_enable): 0x03U */     IOMUXC_SetPinMux(         IOMUXC_GPIO_09_GPIOMUX_IO09,            /* GPIO_09 is configured as GPIOMUX_IO09 */         0U);                                    /* Software Input On Field: Input Path is determined by functionality */     IOMUXC_SetPinConfig(         IOMUXC_GPIO_09_GPIOMUX_IO09,            /* GPIO_09 PAD functional properties : */         0x01B0A0U);                             /* Slew Rate Field: Slow Slew Rate                                                     Drive Strength Field: R0/4                                                     Speed Field: fast(150MHz)                                                     Open Drain Enable Field: Open Drain Disabled                                                     Pull / Keep Enable Field: Pull/Keeper Enabled                                                     Pull / Keep Select Field: Pull                                                     Pull Up / Down Config. Field: 100K Ohm Pull Up                                                     Hyst. Enable Field: Hysteresis Enabled */ } 1.2 GPIO 中断设计

如果仅仅是控制 I/O 输入输出电平,那 GPIO 外设功能也太简陋了。为了让 GPIO 外设具备更大的应用价值,IC 设计者往往会为其加入边沿检测功能,如下图蓝框标出的寄存器(这些寄存器仅在 Pin 方向被配置为输入时有效):

EDGE_SEL[31:0] - 配置是否使能 Pin 双边沿检测 ICRx[31:0] - 配置 Pin 低电平/高电平/上升沿/下降沿四种检测模式(仅当 EDGE_SEL 里没使能双边沿) IMR[31:0] - 配置是否使能 Pin 中断 ISR[31:0] - 记录 Pin 中断状态

边沿检测功能会涉及中断响应,在 i.MXRT 里为了节省中断号资源,将 16 个 Pin 编为一组,这 16 个 Pin 共享一个中断号。i.MXRT1011 里一共 37 个 GPIO(即GPIO1[31:0]、GPIO2[13:0]、GPIO5[0]),所以你在 MIMXRT1011.h 头文件里会看到如下中断号定义:

typedef enum IRQn {   /* Core interrupts */   // ...省略   /* Device specific interrupts */   GPIO1_Combined_0_15_IRQn     = 70,   GPIO1_Combined_16_31_IRQn    = 71,   GPIO2_Combined_0_15_IRQn     = 72,  // 没用满   GPIO5_Combined_0_15_IRQn     = 73,  // 没用满   // ...省略 } IRQn_Type;

在串口波特率识别检测场景里,我们需要在 GPIO 模块里将 GPIO_09 引脚配置为输入模式,且开启下降沿捕获中断,示例代码如下:

#include "fsl_gpio.h" void io_func_config(void) {     // I/O 配置为输入,下降沿捕获模式     gpio_pin_config_t sw_config = {         kGPIO_DigitalInput,         0,         kGPIO_IntFallingEdge,     };     // 初始化 GPIO1[9] 管脚     GPIO_PinInit(GPIO1, 9, &sw_config);     // 使能 GPIO1[9] 管脚中断     GPIO_PortEnableInterrupts(GPIO1, 1U 


【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3