STM32F407HAL库(脱库)中断

什么是中断

  • 打断CPU执行正常的程序,转而处理紧急程序,然后返回原暂停的程序继续运行

中断的作用意义

  • 高效处理紧急程序,不会占用CPU资源

  • 实时控制:在确定时间内对相应事件作出响应,如:温度监控

  • 故障处理:检测到故障,需要第一时间处理,如:电梯门夹人了

  • 数据传输:不确定数据何时会来,如:串口数据接收

NVIC基本概念

Nested vectored interrupt controller,嵌套向量中断控制器,属于内核

NVIC支持:256个中断(16内核 + 240外部),支持:256个优先级

中断优先级基本概念

  1. 抢占优先级:高抢占优先级可以打断正在执行的低抢占优先级中断

  2. 响应优先级:当抢占优先级相同时,响应优先级高的先执行,但是不能相互打断

  3. 数值越小,优先级越高

  4. 优先级分组AIRCR[10:8]IPRx bit[7:4]分配分配结果
    0111None :[7:4]0位抢占优先级,4位响应优先级 24,16个响应优先级
    1110[7] :[6:4]1位抢占优先级,3位响应优先级
    2101[7:6] :[5:4]2位抢占优先级,2位响应优先级
    3100[7:5] :[4]3位抢占优先级,1位响应优先级
    4011[7:4] :None4位抢占优先级,0位响应优先级
编号自然优先级对应外设抢占响应执行顺序
310RTC212
613EXTI0304
714EXTI1201
-16Systick303

NVIC的配置方法

1.设置中断分组 HAL_NVIC_SetPriorityGrouping

2.设置中断优先级 HAL_NVIC_SetPriority

3.使能中断 HAL_NVIC_EnableIRQ

上面相关函数是定义在stm32f1xx_hal_cortex.c里面的

注意:void HAL_NVIC_SetPriority(IRQn_Type IRQn, uint32_t PreemptPriority, uint32_t SubPriority)

IRQn_Type IRQn 中断名,这个形参是个枚举类型,直接把要用的宏复制过来就行(双击他然后右键go to过去可以查看)

uint32_t PreemptPriority 抢断优先级

uint32_t SubPriority 响应优先级

EXTI基本概念

External(Extended) interrupt/event Controller,外部(扩展)中断事件控制器

外部中断,是指一些涉及GPIO引脚电平变化或者RTC和USB等外设唤醒事件所触发的中断,由外部中断控制器EXTI管理

中断和事件的理解:

中断:要进入NVIC,有相应的中断服务函数,需要CPU处理

事件:不进入NVIC,仅用于内部硬件自动控制的,如:TIM、DMA、ADC

  • 中断触发方式有三种:上升沿触发、下降沿触发和双边沿触发。我们把通过GPIO引脚产生的中断简称为外部中断

  • STM32将GPIO引脚进行了分组:尾号相同的引脚作为一组,通过1个多路选择器连接到1个EXTI外部中断线。同组的引脚只能由1个与外部中断线连接,其他引脚就不能作为外部引脚,本质上可供用户同时使用的外部中断引脚最多只有16个

  • NVIC为EXTI所管理的16个外部中断线提供了7个中断通道。EXTI0~EXTI4 连接到独立的中断通道,有单独的ISR。EXTI5~EXTI9 共享1个中断通道,EXTI10~EXTI15共享1个中断通道。

EXTI的HAL库设置步骤(外部中断)

  1. 使能GPIO时钟 __HAL_RCC_GPIOx_CLK_ENABLE

  2. GPIO/AFIO(SYSCFG)/EXTI HAL_GPIO_Init,一步到位

  3. 设置中断分组 HAL_NVIC_SetPriorityGrouping,此函数仅需设置一次!(在HAL_Init里已经设置)

  4. 设置中断优先级 HAL_NVIC_SetPriority

  5. 使能中断 HAL_NVIC_EnableIRQ

  6. 设计中断服务函数 EXTIx_IRQHandler,中断服务函数,清中断标志!

HAL库中断回调处理机制

HAL库中断处理公用函数 HAL_GPIO_EXTI_IRQHandler

HAL库数据处理回调函数 HAL_GPIO_EXTI_Callback

在led.c里得加一个灯,及用PA0和PA1

exti.c

 #include "exti.h"
 #include "delay.h"
 ​
 void EXTI_init(void)
 {
     GPIO_InitTypeDef GPIO_Init;                     //声明结构体,命名为GPIO_Init
     
     __HAL_RCC_GPIOE_CLK_ENABLE();                   //使能时钟
     
     GPIO_Init.Pin = GPIO_PIN_0;                       //引脚号
     GPIO_Init.Mode = GPIO_MODE_IT_FALLING;  //具有下降沿触发检测的外部中断模式
     GPIO_Init.Pull = GPIO_PULLUP;
     GPIO_Init.Speed = GPIO_SPEED_FREQ_VERY_HIGH;//可配可不配
     
     HAL_GPIO_Init(GPIOE,&GPIO_Init);    //第二个参数是结构体指针,所以要取个地址
     
     //HAL_NVIC_SetPriorityGrouping该函数在hal.c文件的HAL_Init里已经定义F1分组为2,F4分组为4
     HAL_NVIC_SetPriority(EXTI0_IRQn,2,0);
     HAL_NVIC_EnableIRQ(EXTI0_IRQn);
 }
 ​
 void EXTI0_IRQHandler(void)
 {
     HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_0);
 }
 ​
 void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
 {
     delay_ms (20);  //消抖 注意在上添加"delay.h"头文件
     if(GPIO_Pin==GPIO_PIN_0)//判断是哪个中断线进来了
     {
         if(HAL_GPIO_ReadPin(GPIOE,GPIO_PIN_0)==0)
         {
             HAL_GPIO_TogglePin(GPIOA,GPIO_PIN_1);
         }
     }
 }
 ​

exti.h

#ifndef _EXTI_H_
 #define _EXTI_H_
 ​
 #include "main.h"
 void EXTI_init(void);
 ​
 #endif
 ​

main.c

#include "main.h"
 ​
 int main(void)
 {
     HAL_Init();                     /*初始化HAL库*/
     delay_init();                   /*延时初始化*/
     Stm32_Clock_Init();     /*设置时钟*/
     led_init();                     /*LED初始化*/
     EXTI_init();
     while(1)
     {
         HAL_GPIO_WritePin(GPIOA,GPIO_PIN_0,GPIO_PIN_SET);//置1熄灭
         delay_ms(500);                                                                  //延时500ms
         HAL_GPIO_WritePin(GPIOA,GPIO_PIN_0,GPIO_PIN_RESET);//置0亮
         delay_ms(500);
 //      LED_Ctrl(LED_PIN_0, LED_OFF);
 //      delay_ms(500);
 //      LED_Ctrl(LED_PIN_0, LED_ON);
 //      delay_ms(500);
     }
 }

main.h

 #ifndef __MAIN_H
 #define __MAIN_H
 ​
 #include "stm32f4xx_hal.h"
 ​
 #include "led.h"
 #include "delay.h"
 #include "sys.h"
 #include "exti.h"
 ​
 #endif
 ​

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

不动小松

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值