stm32 使用 rt-thread 引脚PIN中断设置边沿触发问题

devtools/2024/12/22 20:11:00/

一、PIN中断设置

1.1 RT-Thread的PIN中断简介

  RT-Thread是一个开源的嵌入式实时操作系统,它提供了丰富的设备驱动和组件,方便开发者进行嵌入式系统开发。其中,PIN设备是RT-Thread对通用输入输出(GPIO)的抽象和封装,使得开发者可以更方便地管理GPIO,包括配置引脚模式、读写引脚状态、处理外部中断等。
  PIN中断是RT-Thread中处理外部事件的一种重要机制。当GPIO引脚上的电平发生变化时,可以触发中断,进而执行相应的中断回调函数。这种机制对于按键检测、传感器信号采集等场景非常有用。

中断触发模式可配置,一般有下图所示 5 种中断触发模式:
在这里插入图片描述
输入输出模式可控制:

  • 输出模式一般包括:推挽、开漏、上拉、下拉。引脚为输出模式时,可以通过配置引脚输出的电平状态为高电平或低电平来控制连接的外围设备。
  • 输入模式一般包括:浮空、上拉、下拉、模拟。引脚为输入模式时,可以读取引脚的电平状态,即高电平或低电平。

1.2 RT-Thread的PIN中断使用步骤

1.获取GPIO编号
使用RT-Thread提供的GET_PIN宏来获取引脚编号。例如,获取编号为PA0的引脚,可以使用#define LED0_PIN GET_PIN(A, 0)。
2.设置引脚模式
根据硬件原理图和实际需求,将引脚设置为合适的模式,如输入模式或输出模式。在中断实验中,通常将引脚设置为下拉输入模式或上拉输入模式。
3.注册中断回调函数、配置中断触发模式、编写中断服务程序
3.1 使用rt_pin_attach_irq()函数将中断回调函数与引脚关联起来。这个回调函数会在引脚检测到指定电平变化时被触发。
3.2 根据实际的硬件需求,设置中断的触发模式,如上升沿触发、下降沿触发、边沿触发(上升沿和下降沿都触发)、高电平触发或低电平触发。
3.3 在中断回调函数中编写具体的处理逻辑,如切换LED灯的状态、记录按键事件等。
4.使能引脚中断
使用rt_pin_irq_enable()函数来使能之前注册的引脚中断。如果不使能中断,即使中断事件发生了,也不会触发回调函数。

RT-Thread 提供的 PIN 设备管理接口来访问 GPIO,相关接口如下所示:
在这里插入图片描述

二、问题描述

stm32单片机 使用引脚的外部中断,设置为下拉输入,当使能外中断时,引脚被拉高。

/* 按键1引脚为输入模式 */
rt_pin_mode(PIN_NUM, PIN_MODE_INPUT_PULLDOWN);// PB1为低/*绑定中断,下降沿模式,回调函数名为beep on */
rt_pin_attach_irq(PIN_NUM, PIN_IRQ_MODE_FALLING, beep_On,RT NULL);//PB1为低/*使能外中断 */
rt_pin_irq_enable(PIN_NUM, PIN_IRQ_ENABLE);//PB1被拉高 为什么会被拉高?

查看代码,发现配置上升沿触发时,又对引脚模式进行了配置,配置为了上拉。

static rt_err_t stm32_pin_irq_enable(struct rt_device *device, rt_base_t pin,rt_uint8_t enabled)
{const struct pin_irq_map *irqmap;rt_base_t level;rt_int32_t irqindex = -1;GPIO_InitTypeDef GPIO_InitStruct;if (PIN_PORT(pin) >= PIN_STPORT_MAX){return -RT_ENOSYS;}if (enabled == PIN_IRQ_ENABLE){irqindex = bit2bitno(PIN_STPIN(pin));if (irqindex < 0 || irqindex >= (rt_int32_t)ITEM_NUM(pin_irq_map)){return -RT_ENOSYS;}level = rt_hw_interrupt_disable();if (pin_irq_hdr_tab[irqindex].pin == -1){rt_hw_interrupt_enable(level);return -RT_ENOSYS;}irqmap = &pin_irq_map[irqindex];/* Configure GPIO_InitStructure */GPIO_InitStruct.Pin = PIN_STPIN(pin);GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;switch (pin_irq_hdr_tab[irqindex].mode){case PIN_IRQ_MODE_RISING:GPIO_InitStruct.Pull = GPIO_PULLDOWN;GPIO_InitStruct.Mode = GPIO_MODE_IT_RISING;break;case PIN_IRQ_MODE_FALLING:GPIO_InitStruct.Pull = GPIO_PULLUP;GPIO_InitStruct.Mode = GPIO_MODE_IT_FALLING;break;case PIN_IRQ_MODE_RISING_FALLING:GPIO_InitStruct.Pull = GPIO_NOPULL;GPIO_InitStruct.Mode = GPIO_MODE_IT_RISING_FALLING;break;}HAL_GPIO_Init(PIN_STPORT(pin), &GPIO_InitStruct);HAL_NVIC_SetPriority(irqmap->irqno, 5, 0);HAL_NVIC_EnableIRQ(irqmap->irqno);pin_irq_enable_mask |= irqmap->pinbit;rt_hw_interrupt_enable(level);}else if (enabled == PIN_IRQ_DISABLE){irqmap = get_pin_irq_map(PIN_STPIN(pin));if (irqmap == RT_NULL){return -RT_ENOSYS;}level = rt_hw_interrupt_disable();HAL_GPIO_DeInit(PIN_STPORT(pin), PIN_STPIN(pin));pin_irq_enable_mask &= ~irqmap->pinbit;
#if defined(SOC_SERIES_STM32F0) || defined(SOC_SERIES_STM32G0)if ((irqmap->pinbit >= GPIO_PIN_0) && (irqmap->pinbit <= GPIO_PIN_1)){if (!(pin_irq_enable_mask & (GPIO_PIN_0 | GPIO_PIN_1))){HAL_NVIC_DisableIRQ(irqmap->irqno);}}else if ((irqmap->pinbit >= GPIO_PIN_2) && (irqmap->pinbit <= GPIO_PIN_3)){if (!(pin_irq_enable_mask & (GPIO_PIN_2 | GPIO_PIN_3))){HAL_NVIC_DisableIRQ(irqmap->irqno);}}else if ((irqmap->pinbit >= GPIO_PIN_4) && (irqmap->pinbit <= GPIO_PIN_15)){if (!(pin_irq_enable_mask & (GPIO_PIN_4 | GPIO_PIN_5 | GPIO_PIN_6 | GPIO_PIN_7 | GPIO_PIN_8 | GPIO_PIN_9 |GPIO_PIN_10 | GPIO_PIN_11 | GPIO_PIN_12 | GPIO_PIN_13 | GPIO_PIN_14 | GPIO_PIN_15))){HAL_NVIC_DisableIRQ(irqmap->irqno);}}else{HAL_NVIC_DisableIRQ(irqmap->irqno);}
#elseif ((irqmap->pinbit >= GPIO_PIN_5) && (irqmap->pinbit <= GPIO_PIN_9)){if (!(pin_irq_enable_mask & (GPIO_PIN_5 | GPIO_PIN_6 | GPIO_PIN_7 | GPIO_PIN_8 | GPIO_PIN_9))){HAL_NVIC_DisableIRQ(irqmap->irqno);}}else if ((irqmap->pinbit >= GPIO_PIN_10) && (irqmap->pinbit <= GPIO_PIN_15)){if (!(pin_irq_enable_mask & (GPIO_PIN_10 | GPIO_PIN_11 | GPIO_PIN_12 | GPIO_PIN_13 | GPIO_PIN_14 | GPIO_PIN_15))){HAL_NVIC_DisableIRQ(irqmap->irqno);}}else{HAL_NVIC_DisableIRQ(irqmap->irqno);}
#endifrt_hw_interrupt_enable(level);}else{return -RT_ENOSYS;}return RT_EOK;
}

在这里插入图片描述
当配置下降沿触发时,将配置的下拉引脚改为了上拉导致的。

解决办法:
根据需求自行修改此处的代码,或者使用stm32的HAL库进行操作。

参考:

https://club.rt-thread.org/ask/question/f157b3d17b168c24.html

https://club.rt-thread.org/ask/question/921e2288c7c5c7ba.html

https://club.rt-thread.org/ask/question/abff83df48655f40.html


http://www.ppmy.cn/devtools/123307.html

相关文章

【实践】快速学会使用阿里云消息队列RabbitMQ版

文章目录 1.场景简介2.实验架构3.实验流程3.创建实验资源4.创建阿里云AccessKey5.创建静态用户名密码6.创建Vhost、Exchange、Queue并绑定关系6.1、Vhost 的作用6.2、创建Vhost6.3、Exchange 的作用6.4、创建Exchange6.5、Queue 的作用6.6、创建Queue6.7、创建Exchange和Queue的…

Hadoop的三种运行模式:单机模式、伪分布式模式和完全分布式模式

单机模式 单机模式是Hadoop最简单的运行模式。在单机模式下&#xff0c;所有Hadoop组件都运行在单个机器上&#xff0c;包括HDFS、MapReduce等。由于只有一个节点参与计算&#xff0c;单机模式适用于开发和测试阶段&#xff0c;不适合用于处理大规模数据。在单机模式下&#xf…

宠物咖啡馆在线平台:SpringBoot框架的创新设计

3系统分析 3.1可行性分析 通过对本基于Spring Boot的宠物咖啡馆平台的设计与实现实行的目的初步调查和分析&#xff0c;提出可行性方案并对其一一进行论证。我们在这里主要从技术可行性、经济可行性、操作可行性等方面进行分析。 3.1.1技术可行性 本基于Spring Boot的宠物咖啡馆…

利基营销:如何为小众受众制定内容营销策略?AIGC大模型创新思维数字化转型商业模式专家培训讲师谈短视频内容社私域数字经济人工智能

了解利基营销 什么是利基营销&#xff1f; 简单来说&#xff0c;利基营销就是专注于特定范围的潜在客户群&#xff0c;而不是针对广泛的人群。 实际上&#xff0c;利基营销可以比作为拥有露营装备的人而不是所有热爱户外活动的人定制内容。露营爱好者会欣赏专门针对他们的需…

JMeter

通过AI可知&#xff1a; Apache JMeter 是一款开源的、基于Java的压力测试和性能测试工具&#xff0c;它主要用于对软件和服务器进行性能测试和负载测试。JMeter 可以模拟多种用户请求&#xff0c;包括但不限于Web请求、数据库请求、FTP请求等&#xff0c;以评估系统在高负载情…

SQL NULL 值

SQL NULL 值 概述 在SQL(Structured Query Language)中,NULL值是一个特殊的标记,用于表示缺失或未知的值。理解NULL值的概念对于数据库设计和查询非常重要,因为它们可以影响查询的结果和性能。本文将详细介绍SQL中NULL值的概念、使用场景以及如何处理它们。 NULL值的含…

101 公司战略的基本概念

公司战略的概念 传统概念&#xff08;战略是终点途径&#xff09;&#xff1a;计划性、全局性、长期性现代概念&#xff08;战略是途径&#xff09;&#xff1a;应变性、竞争性、风险性综合概念&#xff08;前二者的折中&#xff09;&#xff1a;预先性、反应性公司的使命与目标…

Spring源码二IOC容器源码

文章目录 Spring IOC初始化源码剖析1.prepareRefresh2.obtainFreshBeanFactory3.prepareBeanFactory4.postProcessBeanFactory5.invokeBeanFactoryPostProcessors6.registerBeanPostProcessors7.initMessageSource8.initApplicationEventMulticaster9.onRefresh10.registerList…