什么是中断处理函数(IRQHandler)的标准流程? |
您所在的位置:网站首页 › 嵌入式ADC是什么 › 什么是中断处理函数(IRQHandler)的标准流程? |
大家好,我是痞子衡,是正经搞技术的痞子。今天痞子衡给大家介绍的是以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 方向被配置为输入时有效): ![]() 边沿检测功能会涉及中断响应,在 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 |