当前位置: 代码网 > it编程>硬件开发>stm32 > STM32--中断使用(超详细!)

STM32--中断使用(超详细!)

2024年08月01日 stm32 我要评论
本文主要讲解了STM32单片机的中断使用,主要内容有:中断的概念、NVIC、EXIT的介绍,以及中断使用的步骤。并且利用中断实现了按键控制LED灯实验。

写在前面:前面的学习中,我们接触了stm32的第一个外设gpio,这也是最常用的一个外设;而除了gpio外,中断也是一个十分重要且常用的外设;只有掌握了中断,再处理程序时才能掌握好解决实际问题的逻辑思路。此节我们学习stm32的中断;

    在前面51的学习中,我们也介绍过中断的内容,但是相对于32来说,52的中断十分简单,只有5个中断源,中断的优先级,响应函数也是比较简单的,感兴趣的读者可以看一下下面的这篇博客。

csdnicon-default.png?t=n7t8https://mp.csdn.net/mp_blog/creation/editor/133904885

目录

一、什么是中断

二、 nvic(中断管家)

2.1 nvic基本概念

2.2 nvic相关寄存器 

2.3 nvic工作原理 

2.4 中断优先级 

2.5 nvic使用(stm32)

三、exit(外部中断控制)

3.1 exit基本概念

3.2 exit工作原理

3.3 exit相关寄存器

3.4 exit线与io映射关系

四、中断的使用

4.1中断的使用步骤

4.2exit的配置步骤

4.3通用外设驱动

4.4中断回调机制(hal库)

五、硬件设计 

5.1实现功能

5.2原理图

六、程序设计

6.1程序设计流程图

6.2中断初始化函数 

6.3中断服务函数

6.4中断处理回调函数

6.4源码

6.5实验现象

一、什么是中断

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

举例:当你正在写作业时,做到一半又去吃饭,吃完饭后又回来接着原来的作业继续完成。 

        对于单片机来说,中断是指cpu正在处理某个事件a,发生了另一件事件b,请求cpu迅速去处理(中断发生);cpu暂时停止当前的工作(中断响应),转去处理事件b(中断服务);待cpu处理事件b完成后,再回到原来的事件a(断点)继续执行,这一过程称之为中断。

stm32 gpio外部中断简图:

下面将分别对上述过程中的各个部分进行详细的描述;

二、 nvic(中断管家)

2.1 nvic基本概念

    nvic 即嵌套向量中断控制器,全称 nested vectored interrupt controller。属于是内核的器件,其作用是对stm32中的中断进行管理,因为m3内核中的中断数量很多,当同时出现多个中断时,优先处理哪个中断?以及那些中断不处理等,都要靠nvic 进行控制。m3 内核都是支持 256 个中断,其中包含了 16 个系统中断 240 个外部中断,并且具有 256 级的可编程中断设置。

    nvic支持:256个中断(16个内核+240个外部);支持256个优先级。

   但是对于st公司来说,用不了m3内核中的所有中断以及中断优先级,进而对其进行了一定的裁剪。stm32中共有10个内核中断,60个外部中断,16个中断优先级;

        在中断的使用中还有一个极其重要的一部分为中断服务函数(触发中断后,系统执行的部分,例如上文的吃饭过程)中断服务函数是中断的入口。

2.2 nvic相关寄存器 

nvic相关的寄存器有很多,但是重要的有以下几个,也是需要进行掌握的:

名称位数个数作用
中断使能寄存器(iser)328每一位控制一个中断(打开)
中断失能寄存器(icer)328每一位控制一个中断(关闭)
应用程序中断及复位控制寄存器(aircr)321位[10:8]控制中断优先级分组
中断优先级寄存器ipr82408个位对应一个中断,而stm32只使用高4位

2.3 nvic工作原理 

工作原理图:

2.4 中断优先级 

 stm32中断优先级基本概念:

1、抢占优先级(pre):高抢占优先级可以打断正在执行的低抢占优先级中断;

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

3、抢占优先级和响应优先级都相同的情况下,自然优先级越高的先执行;

4、自然优先级:中断向量表中的优先级;

5、数值越小,表示优先级越高;

stm32中断优先级分组:

       在前面我们说过aircr寄存器,位10、9、8三位用于控制优先级的分组,但是只取其中的五组优先级分组;ipr寄存器,用于控制中断的优先级,包括抢占优先级与响应优先级,高4位控制,如下表所示:

优先级分组aircr[10:8]ipr[7:4]分配分配结果
0111none:[7:4]

抢占优先级(0位、0级)

响应优先级(4位、16级)

1110[7]:[6:4]

抢占优先级(1位、2级)

响应优先级(3位、8级)

2101[7:6]:[6:4]

抢占优先级(2位、4级)

响应优先级(2位、4级)

3100[7:5]:[4]

抢占优先级(3位、8级)

响应优先级(1位、2级)

4011[7:4]:none

抢占优先级(4位、16级)

响应优先级(0位、0级)

        假定设置中断优先级分组为 2,然后设置中断3的抢占优先级为 2,响应优先级为 1。中断6的抢占优先级为 3,响应优先级为0。 中断7的抢占优先级为 2,响应优先级为 0。那么这 3 个中断的优先级顺序为: 中断 7>中断 3>中断 6。 上面例子中的中断 3 和中断 7 都可以打断中断 6 的中断。而中断 7 和中断 3 却不可以相互打断!                

        在一个工程中,一般只设置一次中断优先级分组(aircr寄存器);

2.5 nvic使用(stm32)

1、hal_nvic_setprioritygrouping()

 中断分组的设置在hal_init()函数中配置:

 2、hal_nvic_setpriority()

函数说明:

用于设置中断的抢占优先级和响应优先级(子优先级)

 函数形参

形参 1 是中断号,可以选择范围:irqn_type 定义的枚举类型。

形参 2 是抢占优先级,可以选择范围:0 到 15。

形参 3 是响应优先级,可以选择范围:0 到 15。

 3、hal_nvic_enableirq()

函数描述: 用于使能中断。

 函数形参: 形参 irqn 是中断号,可以选择范围:irqn_type 定义的枚举类型

三、exit(外部中断控制)

3.1 exit基本概念

全称:外部中断事件控制器

    包含20个产生事件/中断请求的边沿检测器,即20条exit线;

        每个输入线可以独立地配置输入类型(脉冲或挂起)和对应的触发事件(上升沿或下降沿或者双边沿都触发)。每个输入线都可以独立地被屏蔽。挂起寄存器保持着状态线的中断请求

3.2 exit工作原理

工作原理图:

3.3 exit相关寄存器

        在上述工作原理图中,所涉及的寄存器共有7个,但是对于外部中断来说,我们只需要掌握其中四个寄存器:上升沿触发选择寄存器(exti_rtsr)、下降沿触发选择寄存器(exti_ftsr)、挂起寄存器(exti_pr)与中断屏蔽寄存器(exti_imr)。

1、上升沿触发选择寄存器(exti_rtsr)

 2、下降沿触发选择寄存器(exti_ftsr)

3、挂起寄存器(exti_pr) 

4、中断屏蔽寄存器(exti_imr)

3.4 exit线与io映射关系

        前面说过, exti 线 0~15:对应外部 io 口的输入中断。但是stm32f1 供给 io 口使用的中断线只有 16 个,但是 stm32f1 的 io 口 却远远不止 16 个,所以 stm32 把 gpio 管脚 gpiox.0~gpiox.15(x=a,b,c,d,e,f,g)分别对应中断线 0~15。这样子每个中断线对应了最多 9 个 io 口,以线 0 为例:它对应了gpioa.0、gpiob.0、 gpioc.0、gpiod.0、gpioe.0、gpiof.0 和 gpiog.0。而中断线每次只能连接到 1 个 io 口上, 这样就需要通过配置决定对应的中断线配置到哪个 gpio 上了。

gpio 和中断线映射关系是在寄存器 afio_exticr1 ~ afio_exticr4 中配置的 

外部中断配置寄存器 1(afio_exticr1)

四、中断的使用

4.1中断的使用步骤

4.2exit的配置步骤

4.3通用外设驱动

这个内容在上一节gpio的使用中已经说明;详细内容请看下面这个博客;

stm32--gpio点亮led灯(手把手,超详细)-csdn博客

4.4中断回调机制(hal库)

五、硬件设计 

5.1实现功能

利用stm32f1精英开发板的独立按键模块key0控制led0灯的亮灭;

5.2原理图

1、led设置       

        在该开发板上的led灯共有3个,本次我们点亮led0,即对pb5进行操作;我们看到led0右端接的是vcc3.3v,那么只需要控制左端的pb5输出即可;(输出0点亮,输出1熄灭);

        我们还需要确定gpiob_5的工作模式;我们采用推挽输出,其特点为:输出引脚电平,高电平为vdd,低电平为vss;

2、key设置

        在该开发板上的key共有三个按键,本次我们使用的是key0,即对pe4进行操作,当按键按下是,pe4输出低电平,当按键未按下时,pe4应为高电平;所以gpioe_4的工作模式为上拉输入。 

六、程序设计

6.1程序设计流程图

6.2中断初始化函数 

6.3中断服务函数

        每开启一个中断,就必须编写其对应的中断服务函数,否则将会导致死机(cpu 将找不到 中断服务函数)。stm32f1 的 io 口外部中断函数只有 7 个上文已经说明。

        中断线 0-4,每个中断线对应一个中断函数,中断线 5-9 共用中断函数exti9_5_irqhandler, 中断线 10-15 共用中断函数 exti15_10_irqhandler。一般情况下,我们可以把中断控制逻辑直 接编写在中断服务函数中,但是 hal 库把中断处理过程进行了简单封装。

6.4中断处理回调函数

        hal 库为了用户使用方便,提供了一个中断通用入口函数 hal_gpio_exti_irqhandler, 在该函数内部直接调用回调函数 hal_gpio_exti_callback。

        该函数实现的作用非常简单,通过入口参数 gpio_pin 判断中断来自哪个 io 口,然后清除 相应的中断标志位,最后调用回调函数 hal_gpio_exti_callback()实现控制逻辑。在所有的外 部中断服务函数中直接调用外部中断共用处理函数 hal_gpio_exti_irqhandler,然后在回调 函数 hal_gpio_exti_callback 中通过判断中断是来自哪个 io 口编写相应的中断服务控制逻 辑。

6.4源码

exti.c文件

#include "./bsp/exti/exti.h"
#include "./system/delay/delay.h"


void  exti_init(void)
{
    gpio_inittypedef  gpio_init_struct;
    __hal_rcc_gpioe_clk_enable();
    gpio_init_struct.pin=gpio_pin_4;
    gpio_init_struct.mode=gpio_mode_it_falling ;
    gpio_init_struct.pull=gpio_pullup ;
    
    hal_gpio_init(gpioe,&gpio_init_struct);
    hal_nvic_setpriority(exti4_irqn,2,0);
    hal_nvic_enableirq(exti4_irqn);
}



    void exti4_irqhandler(void)
    {
     hal_gpio_exti_irqhandler(gpio_pin_4);
     __hal_gpio_exti_clear_it(gpio_pin_4);
    }
    
     void hal_gpio_exti_callback(uint16_t gpio_pin)
     {
      delay_ms(20);
         if( gpio_pin==gpio_pin_4)
         {
              if(hal_gpio_readpin(gpioe,gpio_pin_4)==0)
             {
                hal_gpio_togglepin(gpiob, gpio_pin_5);
             
             }
         }
     
     }


     

6.5实验现象

32中断点灯

总结: 本文主要讲解了stm32单片机的中断使用,主要内容有:中断的概念、nvic、exit的介绍,以及中断使用的步骤。并且利用中断实现了按键控制led灯。大家一定要反复阅读,才能掌握其中的思路,也要对实验部分进行多次尝试。。

创作不易,还请大家多多点赞支持!!!

(0)

相关文章:

版权声明:本文内容由互联网用户贡献,该文观点仅代表作者本人。本站仅提供信息存储服务,不拥有所有权,不承担相关法律责任。 如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 2386932994@qq.com 举报,一经查实将立刻删除。

发表评论

验证码:
Copyright © 2017-2025  代码网 保留所有权利. 粤ICP备2024248653号
站长QQ:2386932994 | 联系邮箱:2386932994@qq.com