STM32_HAL库_外部中断

一、设置分组 

stm32f1xx_hal_cortex.c

查看分组

五个形参,分组0~4

stm32f1xx_hal.c

设置了分组为2, 此工程就不需要再设置了

再回到stm32f1xx_hal_cortex.c

查看NVIC_SetPriorityGrouping的定义,若无法跳转,先编译一下,

继续找定义

这段代码是用于设置 NVIC 的优先级分组的内联函数。关键部分:

  • SCB->AIRCR = reg_value;: 最后,将更新后的寄存器值写入 SCB_AIRCR 寄存器,完成对 NVIC 优先级分组的设置。

总的来说,这个函数的目的是安全地设置 NVIC 的优先级分组,确保在进行任何更改之前正确地处理了旧的配置值,并且将写入操作限制在允许的范围内。

二、设置优先级

stm32f1xx_hal_cortex.c

没有返回值,三个形参

这段代码是用于设置特定中断的优先级的函数。

  1. void HAL_NVIC_SetPriority(IRQn_Type IRQn, uint32_t PreemptPriority, uint32_t SubPriority): 这是一个函数声明,用于设置特定中断的优先级。它接受三个参数,分别是中断号 IRQn,抢占优先级 PreemptPriority,以及响应优先级 SubPriority

  2. uint32_t prioritygroup = 0x00U;: 这一行定义了一个变量 prioritygroup 并初始化为 0x00U,该变量用于存储当前 NVIC 的优先级分组。

  3. assert_param(IS_NVIC_SUB_PRIORITY(SubPriority));assert_param(IS_NVIC_PREEMPTION_PRIORITY(PreemptPriority));: 这两行是参数检查,确保传递给函数的 SubPriorityPreemptPriority 在有效范围内。如果参数不在有效范围内,这些断言将会触发。

  4. prioritygroup = NVIC_GetPriorityGrouping();: 这一行调用了 NVIC_GetPriorityGrouping() 函数,获取当前 NVIC 的优先级分组。

  5. NVIC_SetPriority(IRQn, NVIC_EncodePriority(prioritygroup, PreemptPriority, SubPriority));: 这一行调用了 NVIC_SetPriority() 函数,设置指定中断的优先级。它使用了 NVIC_EncodePriority() 函数将抢占优先级和子优先级编码为一个优先级值,并将其传递给 NVIC_SetPriority() 函数来设置中断的优先级。

这个函数的目的是设置特定中断的优先级,确保传递给函数的优先级参数在有效范围内,并将优先级值编码后传递给 NVIC。

查看IRQn_Type定义

跳转到stm32f103xe.h

举个例子

RTC_IRQn

中断号是3

NVIC_SetPriority

看定义 

跳转到这里,再去看定义

 跳转到:

用于设置特定中断的优先级的内联函数。每个部分的作用:

  1. __STATIC_INLINE void __NVIC_SetPriority(IRQn_Type IRQn, uint32_t priority): 这是一个内联函数的声明,用于设置特定中断的优先级。它接受两个参数,一个是中断号 IRQn,另一个是优先级 priority

  2. if ((int32_t)(IRQn) >= 0): 这个条件语句检查中断号是否为非负值,如果是非负值,则说明是可编程中断,需要设置 NVIC->IP 寄存器的相应位置;如果是负值,则说明是固定优先级中断,需要设置 SCB->SHP 寄存器的相应位置。

  3. NVIC->IP[((uint32_t)IRQn)] = (uint8_t)((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL);: 如果是可编程中断,就将优先级值左移以便正确放置到 NVIC->IP 寄存器相应位置。这里通过移位来确保优先级值的正确性,同时保留了 __NVIC_PRIO_BITS 指定的位数,这是由硬件定义的。

  4. SCB->SHP[(((uint32_t)IRQn) & 0xFUL)-4UL] = (uint8_t)((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL);: 如果是固定优先级中断,则将优先级值左移并设置到 SCB->SHP 寄存器的相应位置。由于固定优先级中断的索引不是从零开始的,因此需要进行一些偏移和掩码操作。

这个函数的目的是根据中断类型设置对应中断的优先级,确保优先级值在正确的范围内,并将其正确地写入到相应的寄存器中。

stm32f1xx_hal_cortex.c对cortex_cm3.h文件里的函数进行了封装

这段代码是一个内联函数,用于检查特定中断是否已经被使能。让我们逐步解释每个部分的作用:

  1. __STATIC_INLINE uint32_t __NVIC_GetEnableIRQ(IRQn_Type IRQn): 这是一个内联函数的声明,用于获取特定中断是否已经被使能。它接受一个参数,即中断号 IRQn

  2. if ((int32_t)(IRQn) >= 0): 这个条件语句检查中断号是否为非负值,如果是非负值,则说明是可编程中断,需要检查 NVIC->ISER 寄存器的相应位;如果是负值,则说明是固定优先级中断,这些中断无法被使能,直接返回 0。

  3. return((uint32_t)(((NVIC->ISER[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL));: 如果是可编程中断,则检查 NVIC->ISER 寄存器中相应位是否被置位,如果被置位则返回 1,否则返回 0。这里通过对中断号进行移位和掩码操作来确定具体的位位置。

  4. return(0U);: 如果是固定优先级中断,则直接返回 0,表示该中断无法被使能。

这个函数的目的是根据中断类型检查特定中断是否已经被使能,并返回相应的结果。

三、EXTI

p60

P61

两种中断

四、GPIO外部中断

复制跑马灯实验,BSP新建EXTI文件夹,keil5中新建exti.c与exti.h并添加到EXTI文件夹,添加到工程里

复制拿过来用

 若无法跳转定义,参考这份博客

http://t.csdnimg.cn/RCJyL

重新编译程序

再次执行Go To Definition of ''的操作,可以了

参考

需选用外部中断下降沿触发,且输入上拉

#define  GPIO_MODE_IT_RISING                    0x10110000u   /*!< External Interrupt Mode with Rising edge trigger detection          */
#define  GPIO_MODE_IT_FALLING                   0x10210000u   /*!< External Interrupt Mode with Falling edge trigger detection         */
#define  GPIO_MODE_IT_RISING_FALLING            0x10310000u   /*!< External Interrupt Mode with Rising/Falling edge trigger detection  */#define  GPIO_MODE_EVT_RISING                   0x10120000u   /*!< External Event Mode with Rising edge trigger detection               */
#define  GPIO_MODE_EVT_FALLING                  0x10220000u   /*!< External Event Mode with Falling edge trigger detection              */
#define  GPIO_MODE_EVT_RISING_FALLING           0x10320000u   /*!< External Event Mode with Rising/Falling edge trigger detection       */

这些宏定义了用于 GPIO(通用输入/输出)引脚的不同模式,用于处理外部中断和事件,根据触发边沿的不同来触发。具体而言:

  • GPIO_MODE_IT_RISING:表示外部中断模式,检测上升沿触发。
  • GPIO_MODE_IT_FALLING:表示外部中断模式,检测下降沿触发。
  • GPIO_MODE_IT_RISING_FALLING:表示外部中断模式,同时检测上升沿和下降沿触发。

类似地:

  • GPIO_MODE_EVT_RISING:表示外部事件模式,检测上升沿触发。
  • GPIO_MODE_EVT_FALLING:表示外部事件模式,检测下降沿触发。
  • GPIO_MODE_EVT_RISING_FALLING:表示外部事件模式,同时检测上升沿和下降沿触发。

这些宏通常与 GPIO 配置函数一起使用,以设置 GPIO 引脚的所需模式,以便根据特定边沿触发来处理外部中断或事件。

上下拉配置

#define  GPIO_NOPULL        0x00000000u   /*!< No Pull-up or Pull-down activation  */
#define  GPIO_PULLUP        0x00000001u   /*!< Pull-up activation                  */
#define  GPIO_PULLDOWN      0x00000002u   /*!< Pull-down activation                */

这些宏定义了用于 GPIO 引脚的不同上拉和下拉配置选项。具体来说:

  • GPIO_NOPULL:表示不启用上拉或下拉。
  • GPIO_PULLUP:表示启用上拉。
  • GPIO_PULLDOWN:表示启用下拉。

这些选项通常用于配置 GPIO 引脚的电气特性,以确保引脚在特定条件下的正确操作,如减少干扰、提高信号质量等。

选择输入上拉

中断优先级:HAL_NVIC_SetPriority()

go to definition

选择中断号

笔者选用的是B1,选择EXTI1_IRQn

设置抢断优先级与响应优先级

笔者设置的是2和0

使能中断:HAL_NVIC_EnableIRQ()

笔者的是EXTI1_IRQn

设计中断服务函数:

去到配置文件查找

选择EXTI1_IRQHandler

 

void HAL_GPIO_EXTI_IRQHandler(uint16_t GPIO_Pin)
{/* EXTI line interrupt detected */if (__HAL_GPIO_EXTI_GET_IT(GPIO_Pin) != 0x00u){__HAL_GPIO_EXTI_CLEAR_IT(GPIO_Pin);HAL_GPIO_EXTI_Callback(GPIO_Pin);}
}

这段代码是一个 HAL(Hardware Abstraction Layer,硬件抽象层)的 GPIO(通用输入/输出)外部中断处理函数。让我来解释它:

  • HAL_GPIO_EXTI_IRQHandler 是一个函数,用于处理外部中断事件。它接收一个参数 GPIO_Pin,表示触发了外部中断的 GPIO 引脚。

  • 在函数内部,首先检测是否检测到了 EXTI(外部中断)线的中断事件。

  • 如果 GPIO_Pin 对应的 EXTI 中断事件标志被置位(不为 0),则说明该 GPIO 引脚触发了外部中断。

  • 接着,通过 __HAL_GPIO_EXTI_CLEAR_IT(GPIO_Pin) 清除相应的中断标志。

  • 最后,调用 HAL_GPIO_EXTI_Callback(GPIO_Pin),这是一个回调函数,用于在外部中断触发时执行用户定义的操作。这个函数的实现应该由用户在程序的其他地方提供。

用于在外部中断事件发生时执行相应的操作,如清除中断标志并调用用户定义的回调函数。

回调函数

__weak void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
{/* Prevent unused argument(s) compilation warning */UNUSED(GPIO_Pin);/* NOTE: This function Should not be modified, when the callback is needed,the HAL_GPIO_EXTI_Callback could be implemented in the user file*/
}

用于处理 GPIO 外部中断回调的弱定义函数 HAL_GPIO_EXTI_Callback

  • __weak 关键字表示这是一个弱定义的函数,它可以被用户在程序的其他地方重新定义以满足特定需求。

  • 这个函数的目的是处理 GPIO 外部中断事件。它接收一个参数 GPIO_Pin,表示触发了外部中断的 GPIO 引脚。

  • 函数内部通过调用 UNUSED(GPIO_Pin) 来避免编译器产生未使用参数的警告。这是因为在某些情况下,用户可能不需要使用该参数。

  • 注释部分指出,如果需要在外部中断发生时执行特定的操作,用户应该在自己的代码文件中实现 HAL_GPIO_EXTI_Callback 函数,并在其中编写所需的处理逻辑。

这个函数提供了一个默认的外部中断处理回调函数,并允许用户根据需要进行修改或扩展。

中断信号到来,去翻转led引脚的信号,在led.h中查看引脚是B5

4.1使能GPIO时钟

__HAL_RCC_GPIOB_CLK_ENABLE();

4.2 HAL_GPIO_init

	GPIO_InitTypeDef gpio_init_struct;__HAL_RCC_GPIOB_CLK_ENABLE();gpio_init_struct.Pin = LED0_GPI1_PIN;                   /* 引脚B1 */gpio_init_struct.Mode = GPIO_MODE_IT_FALLING;            /* 推挽输出 */gpio_init_struct.Pull = GPIO_PULLUP;                    /* 上拉 */gpio_init_struct.Speed = GPIO_SPEED_FREQ_HIGH;          /* 高速 */HAL_GPIO_Init(GPIOB, &gpio_init_struct);       /* 初始化 */

4.3 设置中断分组

配置文件已设置分组为2 

4.4 设置中断优先级

HAL_NVIC_SetPriority(EXTI1_IRQn,2,0);

4.5 使能中断

HAL_NVIC_EnableIRQ(EXTI1_IRQn);

4.6 设计中断服务函数

void EXTI1_IRQHandler(void)
{HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_1);}void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
{delay_ms(20);if(GPIO_Pin=GPIO_Pin_1){if(HAL_GPIO_ReadPin(GPIOB,GPIO_Pin_1) ==0){HAL_GPIO_TogglePin(GPIOB,GPIO_Pin_5);}}}

exti.h

函数声明

void exti_init(void);

EXTI1_IRQHandler与HAL_GPIO_EXTI_Callback已经在配置文件里声明过

startup_stm32f103xe.s

stm32f1xx_hal_gpio.h

五、源码

exti.h

#ifndef _EXTI_H
#define _EXTI_H
#include "./SYSTEM/sys/sys.h"void exti_init(void);#endif

exit.c

#include "./BSP/EXTI/exti.h"void exti_init(void)
{GPIO_InitTypeDef gpio_init_struct;__HAL_RCC_GPIOB_CLK_ENABLE();gpio_init_struct.Pin = GPIO_PIN_1;                   /* 引脚B1 */gpio_init_struct.Mode = GPIO_MODE_IT_FALLING;            /* 推挽输出 */gpio_init_struct.Pull = GPIO_PULLUP;                    /* 上拉 */gpio_init_struct.Speed = GPIO_SPEED_FREQ_HIGH;          /* 高速 */HAL_GPIO_Init(GPIOB, &gpio_init_struct);       /* 初始化 */HAL_NVIC_SetPriority(EXTI1_IRQn,2,0);HAL_NVIC_EnableIRQ(EXTI1_IRQn);
}void EXTI1_IRQHandler(void)
{HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_1);}void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
{delay_ms(20);if(GPIO_Pin == GPIO_PIN_1){if(HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_1) ==0){HAL_GPIO_TogglePin(GPIOB,GPIO_PIN_5);}}}

main.c


#include "./SYSTEM/sys/sys.h"
#include "./SYSTEM/delay/delay.h"
#include "./SYSTEM/usart/usart.h"
#include "./BSP/LED/led.h"
#include "./BSP/EXTI/exti.h"int main(void)
{HAL_Init();                                 /* 初始化HAL库 */sys_stm32_clock_init(RCC_PLL_MUL9);         /* 设置时钟,72M */delay_init(72);                             /* 初始化延时函数 */led_init();                                 /* 初始化LED */exti_init();while(1){HAL_GPIO_TogglePin(GPIOB,GPIO_PIN_5);delay_ms(5000);}
}

参考

【【正点原子】手把手教你学STM32 HAL库开发全集【真人出镜】STM32入门教学视频教程 单片机 嵌入式】https://www.bilibili.com/video/BV1bv4y1R7dp?p=56&vd_source=be33b1553b08cc7b94afdd6c8a50dc5a

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/bicheng/24677.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

山东大学软件学院项目实训-创新实训-基于大模型的旅游平台(二十七)- 微服务(7)

11.1 : 同步调用的问题 11.2 异步通讯的优缺点 11.3 MQ MQ就是事件驱动架构中的Broker 安装MQ docker run \-e RABBITMQ_DEFAULT_USERxxxx \-e RABBITMQ_DEFAULT_PASSxxxxx \--name mq \--hostname mq1 \-p 15672:15672 \-p 5672:5672 \-d \rabbitmq:3-management 浏览器访问1…

在网上赚钱,可以自由掌控时间,灵活的兼职副业选择

朋友们看着周围的人在网上赚钱&#xff0c;自己也会为之心动&#xff0c;随着电子设备的普及&#xff0c;带动了很多的工作、创业以及兼职副业选择的机会&#xff0c;作为普通人的我们&#xff0c;如果厌倦了世俗的朝九晚五&#xff0c;想着改变一下自己的生活&#xff0c;可以…

uc/OS移植到stm32实现三个任务

文章目录 一、使用CubeMX创建工程二、uc/OS移植三、添加代码四、修改代码五、实践结果六、参考文章七、总结 实践内容 学习嵌入式实时操作系统&#xff08;RTOS&#xff09;,以uc/OS为例&#xff0c;将其移植到stm32F103上&#xff0c;构建至少3个任务&#xff08;task&#xf…

就业班 第四阶段(k8s) 2401--6.4 day2 Dashboard+国产kuboard(好用)+简单命令

可视化部署Dashboard 昨天做一主两从飞高可用&#xff0c;出现浏览器那一行&#xff0c;是为啥 thisisunsafe kubectl get 获取资源 pod node svc -A 所有名称空间 -n 指定名称空间 -w 动态显示 kubectl edit 资源 pod node svc 官方的&#xff0c;毛坯房 国产 在哪找的…

数字证书和CA

CA&#xff08;Certificate Authority&#xff09;证书颁发机构 验证数字证书是否可信需要使用CA的公钥 操作系统或者软件本身携带一些CA的公钥&#xff0c;同时也可以向提供商申请公钥 数字证书的内容 数字证书通常包含以下几个主要部分&#xff1a; 主体信息&#xff08…

uc/OS-III多任务程序

文章目录 一、实验内容二、实验步骤&#xff08;一&#xff09;基于STM32CubeMX建立工程&#xff08;二&#xff09;获取uc/OS-III源码&#xff08;三&#xff09;代码移植 三、修改mai.c文件四、实验现象 一、实验内容 学习嵌入式实时操作系统&#xff08;RTOS&#xff09;,以…

检测五个数是否一样的算法

目录 算法算法的输出与打印效果输出输入1输入2 打印打印1打印2 算法的流程图总结 算法 int main() {int arr[5] { 0 };int i 0;int ia 0;for (i 0; i < 5; i) { scanf("%d", &arr[i]); }for (i 1; i < 5; i) {if (arr[0] ! arr[i]) {ia 1;break;} }…

2024全国大学生数据统计与分析竞赛B题【电信银行卡诈骗的数据分析】思路详解

电信诈骗是指通过电话、网络和短信方式&#xff0c;编造虚假信息&#xff0c;设置骗局&#xff0c;对受害人实施远程、非接触式诈骗&#xff0c;诱使受害人打款或转账的犯罪行为&#xff0c;通常以冒充他人及仿冒、伪造各种合法外衣和形式的方式达到欺骗的目的&#xff0c;如冒…

C# 异步方法async / await 任务超时处理

一、需求 如果调用一个异步方法后&#xff0c;一直不给返回值结果怎么办呢&#xff1f;这就涉及到怎么取消任务了。 二、Task取消任务 static CancellationTokenSource source new CancellationTokenSource();static void Main(string[] args){Task.Run(() >{for (int i …

Responder工具

简介 Responder是一种网络安全工具&#xff0c;用于嗅探和抓取网络流量中的凭证信息&#xff08;如用户名、密码等&#xff09;。它可以在本地网络中创建一个伪造的服务&#xff08;如HTTP、SMB等&#xff09;&#xff0c;并捕获客户端与该服务的通信中的凭证信息。 Responder工…

路由器作为网络扩展器——设置桥接、路由模式

下面提到的路由器都是家用路由器 一、有线桥接(交换模式) 1.连接示意图 (副路由器只看交换模式部分) 副路由器充当交换机的角色 二、无线桥接(与有线类似) &#xff08;副路由器的无线信号 连接 主路由器的无线信号&#xff09; 三、路由模式 1.连接示意图 (副路由器只看…

扩散模型条件生成——Classifier Guidance和Classifier-free Guidance原理解析

1、前言 从讲扩散模型到现在。我们很少讲过条件生成&#xff08;Stable DIffusion曾提到过一点&#xff09;&#xff0c;所以本篇内容。我们就来具体讲一下条件生成。这一部分的内容我就不给原论文了&#xff0c;因为那些论文并不只讲了条件生成&#xff0c;还有一些调参什么的…

【python】python电影评论数据抓取分析可视化(源码+数据+课程论文)【独一无二】

&#x1f449;博__主&#x1f448;&#xff1a;米码收割机 &#x1f449;技__能&#x1f448;&#xff1a;C/Python语言 &#x1f449;公众号&#x1f448;&#xff1a;测试开发自动化【获取源码商业合作】 &#x1f449;荣__誉&#x1f448;&#xff1a;阿里云博客专家博主、5…

探索教研在线平台的系统架构

教研在线平台作为一家致力于教育技术领域的企业&#xff0c;其系统架构扮演着至关重要的角色。本文将深入探讨教研在线平台的系统架构&#xff0c;从技术架构、数据架构和安全架构等方面进行分析&#xff0c;以期帮助读者更好地理解这一教育科技平台的运作模式。 技术架构是教研…

银河麒麟操作系统通过首批软件供应链安全能力认证

麒麟软件产品供应链安全能力获双重肯定&#xff01;5月30日&#xff0c;经北京赛迪认证中心评估&#xff0c;银河麒麟高级服务器操作系统V10和银河麒麟桌面操作系统V10成为首批获得软件供应链安全能力认证产品&#xff0c;并在操作系统类产品中名列前茅。 软件供应链安全能力评…

09-spring的bean创建流程(一)

文章目录 spring中bean的创建流程finishBeanFactoryInitialization(beanFactory)beanFactory.preInstantiateSingletons();getMergedLocalBeanDefinition(beanName);流程实现FactoryBean接口,里面的对象实例化过程 spring中bean的创建流程 finishBeanFactoryInitialization(be…

【Unity UGUI】Screen.safeArea获取异形屏数据失败

Screen.safeArea获取不到异形屏的尺寸位置等数据 检查AndroidManifest.xml文件是否有设置&#xff1a;android:theme"style/UnityThemeSelector"&#xff0c;没有加上即可 android:theme"style/UnityThemeSelector"

【学习笔记】Windows GDI绘图(十二)双缓冲管理(用GIF动画测试)

文章目录 引言默认双缓冲SetStyle 手动管理双缓冲图形BufferedGraphicsManager缓冲图形管理器BufferedGraphicsContext 缓冲图形上下文BufferedGraphics 图形缓冲区验证双缓冲的效果(Gif动画显示非正常速度)结束语性能对比 引言 图形编程中一个常见的问题就是闪烁&#xff0c;…

SpringBoot高手之路-springboot原理篇

配置文件优先级 SpringBoot原理篇-多环境配置

[职场] 社保和商业保险有什么区别?可以只买商保不买社保吗? #微信#经验分享#媒体

社保和商业保险有什么区别&#xff1f;可以只买商保不买社保吗&#xff1f; 我们在提到社保和商业保险时&#xff0c;经常会听到这样一句话&#xff1a;“社保是基础&#xff0c;商保是补充。” 为什么会这样说呢&#xff1f;社保和商保有什么区别呢&#xff1f;今天&#xf…