IMX6ULL开发板GPIO中断实验全解析

发布于:2024-12-05 ⋅ 阅读:(138) ⋅ 点赞:(0)

一、实验背景与目标

和大家一样,最近在学习linux,就用到了正点原子的imx6u的开发板。将学习过程记录下来。
本次实验聚焦于其GPIO中断功能的探索与实践。实验的目标是实现当开发板上的特定按键(如KEY0)被按下时,触发中断,并执行相应的操作,例如控制蜂鸣器的开关状态。这种基于中断的处理方式,相较于传统的轮询检测按键状态,大大提高了系统的响应效率和资源利用率,使得系统能够在按键事件发生时及时做出反应,而在无事件时处于低功耗或执行其他任务的状态。

二、按键电路原理剖析

(一)引脚连接详情

正点原子IMX6ULL ALPHA/Mini开发板的按键KEY0与I.MX6ULL处理器的“UART1_CTS_B”引脚紧密相连。这一连接关系是整个实验的硬件基础,后续对按键状态的读取以及中断的触发都依赖于此引脚的电平变化。

在这里插入图片描述

(二)电平状态解读

在默认情况下,当按键处于松开状态时,通过“UART1_CTS_B”引脚,GPIO读取到的是高电平。而当按键被按下时,该引脚的电平会转变为低电平。这种电平的变化特性成为了我们判断按键是否被按下的关键依据。
在这里插入图片描述

(三)按键消抖的必要性与实现

在实际的按键操作中,由于机械结构等因素,按键在按下或松开的瞬间,其电平并不会立刻稳定,而是会出现短暂的抖动现象。这种抖动可能会导致系统误认为按键被多次按下或松开,从而引发误操作。为了避免这种情况,我们需要进行按键消抖处理。常见的消抖方法有软件延时消抖和硬件消抖电路。在本次实验中,我们主要采用软件延时消抖的方式。即在检测到按键电平变化后,延时一段时间(通常为几毫秒到几十毫秒),再次检测按键电平,如果电平保持稳定,则认为是有效的按键操作,否则忽略此次电平变化。

三、GPIO配置步骤详解

(一)复用功能配置

首先,我们需要将“UART1_CTS_B”引脚的复用功能设置为GPIO1_IO18模式。这一步骤通过配置相关的复用寄存器来实现。例如,在正点原子提供的底层驱动代码中,可能会有类似IOMUXC_SetPinMux(IOMUXC_UART1_CTS_B_GPIO1_IO18, 0);的代码语句。其中,IOMUXC_SetPinMux函数是用于设置引脚复用功能的函数,第一个参数指定了要配置的引脚及其目标复用模式,第二个参数在本次设置中通常为0,表示按照默认的复用配置参数进行设置。
在这里插入图片描述

(二)电气特性配置

接着,要对引脚的电气特性进行精心配置,包括压摆率、下拉电阻、磁滞特性等。这些电气参数的合理设置能够确保引脚在不同的工作环境和信号变化情况下稳定可靠地工作。例如,IOMUXC_SetPinConfig(IOMUXC_UART1_CTS_B_GPIO1_IO18, 0xF080);这样的代码就是用于设置引脚电气特性的。其中,0xF080是一个十六进制的配置值,它对应着一系列的电气参数设置,如设置合适的驱动能力、上下拉电阻的启用与阻值等。

(三)方向配置

最后,通过配置GPIOx_GIDR寄存器,将该引脚明确设置为输入模式。因为按键是作为输入设备,我们需要读取其电平状态,所以将引脚方向配置为输入是必不可少的环节。在代码实现中,可能会有类似GPIO_SetDir(base, pin, 0);的语句,其中GPIO_SetDir函数用于设置GPIO引脚的方向,base表示GPIO的基地址,pin表示具体的引脚号,0表示设置为输入模式。
在这里插入图片描述

四、GPIO中断模式配置要点

(一)中断触发类型设定

这是中断配置中的关键部分。我们可以使用寄存器GPIOx_ICR1等,来灵活设置GPIO1_IO18引脚的中断触发类型。可供选择的触发类型丰富多样,包括低电平触发、高电平触发、电平下降沿触发、电平上升沿触发以及电平上升下降沿都触发等模式。例如,如果我们希望在按键按下(电平下降沿)时触发中断,就可以使用相应的代码来设置,如GPIO_SetPinInterruptConfig(base, pin, kGPIO_FalllingEdgeInt);,其中kGPIO_FalllingEdgeInt是一个预先定义好的枚举值,表示下降沿触发中断,basepin分别为GPIO的基地址和引脚号。不同的触发类型适用于不同的应用场景,需要根据实际需求谨慎选择。

(二)中断使能操作

在设置好中断触发类型后,还需要使能GPIO输入中断触发。这一步通过设置GPIOx_MR寄存器对应引脚位来完成。例如,GPIO_EnableInterrupt(base, pin);这样的代码语句就是用于使能指定引脚的中断功能。只有使能了中断,当满足设定的中断触发条件时,系统才会响应中断请求并跳转到中断处理函数中执行相应的代码。

(三)中断标志位清除

当GPIO中断处理完成后,务必向GPIOx_ISR寄存器的对应引脚位写1,以清除GPIO外设的中断标志位。这一步骤非常重要,如果不及时清除中断标志位,可能会导致后续的中断处理出现异常,例如多次进入中断处理函数或者中断无法正常响应等问题。在代码中,通常会有GPIO_ClearPendedInterruptStatus(GPIO1, 1 << 18);这样的语句,用于清除特定引脚的中断标志位,其中1 << 18表示针对GPIO1的第18引脚进行操作。

五、GPIO中断处理函数编写指南

(一)相关定义与枚举类型

bsp/bsp_gpio.h头文件中,我们需要增加一些重要的定义和枚举类型,以方便对GPIO中断进行管理和配置。例如,定义GPIO输入信号中断触发类型的枚举类型enum _gpio_int_mode,其成员包括kGPIO_Noint(无中断)、kGPIO_LowInterrupt(低电平中断)、kGPIO_HighInterrupt(高电平中断)、kGPIO_RaisingEdgeInt(上升沿中断)、kGPIO_FalllingEdgeInt(下降沿中断)、kGPIO_FallingOrRaisingEdgeInt(上升下降沿中断)等模式。这些枚举值使得我们在代码中能够清晰、直观地指定中断触发类型,提高了代码的可读性和可维护性。

(二)中断处理函数的具体实现

编写中断处理函数时,首先要完成GPIO引脚的一系列初始化工作,包括IO口复用模式、电气特性、工作模式为输入模式的配置,以及使能输入信号中断触发并设置触发方式等,这些步骤与前面介绍的GPIO配置和中断模式配置步骤紧密相关。例如:

void gpio_init(GPIO_Typ *base, int pin, gpio_pin_config_t config)
{
    // 配置引脚复用
    IOMUXC_SetPinMux(IOMUXC_UART1_CTS_B_GPIO1_IO18, 0);
    // 配置引脚电气特性
    IOMUXC_SetPinConfig(IOMUXC_UART1_CTS_B_GPIO1_IO18, 0xF080);

    // 配置GPIO方向
    if (config.directioin == kGPIO_DigitalOutput)
    {
        GPIO_SetDir(base, pin, 1);
        GPIO_WritePinOutput(base, pin, config.outputLogic);
    }
    else
    {
        GPIO_SetDir(base, pin, 0);
    }

    // 配置GPIO中断模式
    if (config.intMode!= kGPIO_Noint)
    {
        GPIO_SetPinInterruptConfig(base, pin, config.intMode);
        GPIO_EnableInterrupt(base, pin);
    }
}

然后,在中断处理函数内部,我们需要首先检查是否是我们关注的GPIO1_IO18引脚触发的中断。例如:

void GPIO1_Combined_0_15_IRQHandler(void)
{
    // 检查是否是GPIO1_IO18引脚触发的中断
    if (GPIO_GetPendedInterruptStatus(GPIO1, 1 << 18))
    {
        // 清除中断标志位
        GPIO_ClearPendedInterruptStatus(GPIO1, 1 << 18);

        // 在这里添加中断处理的具体逻辑,例如控制蜂鸣器
        //...
    }
}

在确定是目标引脚触发的中断后,要及时清除中断标志位,以确保中断系统的正常运行。最后,在//...处添加针对本次中断事件的具体处理逻辑,比如根据实验目标,如果是控制蜂鸣器,就可以在这里编写控制蜂鸣器开关的代码,如根据当前蜂鸣器状态进行反转操作等。

希望这篇博客能够帮助到正在学习IMX6ULL开发板GPIO中断实验的朋友们,让大家在嵌入式开发的道路上少走弯路,顺利前行。如果在实验过程中有任何疑问或者建议,欢迎大家留言交流。


网站公告

今日签到

点亮在社区的每一天
去签到