STM32外部中断实验

STM32外部中断简介

  首先,stm32每个IO口都可以作为作为外部中断的中断输入口STM32F103 的中断控制器支持 19 个外部中断/事件请求。每个中断设有状态位,每个中断/事件都有独立的触发和屏蔽设置。
STM32F103的 19 个外部中断为:
(1)线 0~15:对应外部 IO 口的输入中断。
(2)线 16:连接到 PVD 输出。
(3)线 17:连接到 RTC 闹钟事件。
(4)线 18:连接到 USB 唤醒事件。

  STM32 供 IO 口使用的中断线只有 16 个,但是 STM32 的 IO 口却远远不
止 16 个,那么 STM32 是怎么把 16 个中断线和 IO 口一一对应起来的呢?于是 STM32 就这样设计,GPIO 的管教 GPIOx.0~GPIOx.15(x=A,B,C,D,E,F,G)分别对应中断线 15~0。这样每个中断线对应了最多 7 个 IO 口,以线 0 为例:它对应了 GPIOA.0、GPIOB.0、GPIOC.0、GPIOD.0、GPIOE.0、GPIOF.0、GPIOG.0。而中断线每次只能连接到 1 个 IO 口上,这样就需要通过配置来决定对应的中断线配置到哪个 GPIO 上了。

GPIO跟中断线的映射图

  接下来,做的实验是应用板载的按键与LED来实现外部中断。
实验步骤如下:

1)初始化 IO 口为输入。
这一步设置你要作为外部中断输入的 IO 口的状态,可以设置为上拉/下拉输入,也可以设置为浮空输入,但浮空的时候外部一定要带上拉,或者下拉电阻。否则可能导致中断不停的触发。在干扰较大的地方,就算使用了上拉/下拉,也建议使用外部上拉/下拉电阻,这样可以一定程度防止外部干扰带来的影响。
2)开启 IO 口复用时钟,设置 IO 口与中断线的映射关系。STM32 的 IO 口与中断线的对应关系需要配置外部中断配置寄存器 EXTICR,这样我们要先开启复用时钟,然后配置 IO 口与中断线的对应关系。才能把外部中断与中断线连接起来。
3)开启与该 IO 口相对的线上中断/事件,设置触发条件。这一步,我们要配置中断产生的条件,STM32 可以配置成上升沿触发,下降沿触发,或者任意电平变化触发,但是不能配置成高电平触发和低电平触发。这里根据自己的实际情况来配置,同时要开启中断线上的中断。这里需要注意的是:如果使用外部中断,并设置该中断的 EMR位的话,会引起软件仿真不能跳到中断,而硬件上是可以的。而不设置 EMR,软件仿真就可以进入中断服务函数,并且硬件上也是可以的。建议不要配置 EMR 位。
4)配置中断分组(NVIC),并使能中断。
这一步,我们就是配置中断的分组,以及使能,对 STM32 的中断来说,只有配置了 NVIC的设置,并开启才能被执行,否则是不会执行到中断服务函数里面去的。关于 NVIC 的详细介绍,请参考 5.2.6 节。 5)编写中断服务函数。
这是中断设置的最后一步,中断服务函数,是必不可少的,如果在代码里面开启了中断,但是没编写中断服务函数,就可能引起硬件错误,从而导致程序崩溃!所以在开启了某个中断后,一定要记得为该中断编写服务函数。在中断服务函数里面编写你要执行的中断后的操作。
通过以上几个步骤的设置,我们就可以正常使用外部中断了。
这里我们使用的是中断来检测按键,还是KEY0 控制 DS0,按一次亮,再按一次,就灭。KEY1 控制 DS1,效果同 KEY0。WK_UP 按键则同时控制 DS0 和 DS1,按一次,他们的状态就翻转一次。


#include "exti.h"
#include "led.h"
#include "key.h"
#include "delay.h"
#include "usart.h"
//外部中断 0 服务程序
void EXTI0_IRQHandler(void)
{
delay_ms(10); //消抖
if(WK_UP==1) //WK_UP 按键
{
LED0=!LED0;
LED1=!LED1; }
EXTI->PR=1<<0; //清除 LINE0 上的中断标志位
}
//外部中断 9~5 服务程序
void EXTI9_5_IRQHandler(void)
{
delay_ms(10); //消抖
if(KEY0==0) LED0=!LED0; //按键 0 
EXTI->PR=1<<5; //清除 LINE5 上的中断标志位
}
//外部中断 15~10 服务程序
void EXTI15_10_IRQHandler(void)
{
delay_ms(10); //消抖
if(KEY1==0) LED1=!LED1; //按键 1 
EXTI->PR=1<<15;//清除 LINE15 上的中断标志位
}
//外部中断初始化程序
//初始化 PA0,PC5,PA15 为中断输入.
void EXTI_Init(void)
{
KEY_Init(); //按键初始化
Ex_NVIC_Config(GPIO_A,0,RTIR); //上升沿触发
Ex_NVIC_Config(GPIO_C,5,FTIR); //下降沿触发
Ex_NVIC_Config(GPIO_A,15,FTIR); //下降沿触发
MY_NVIC_Init(2,2,EXTI0_IRQn,2); //抢占 2,子优先级 2,组 2
MY_NVIC_Init(2,1,EXTI9_5_IRQn,2); //抢占 2,子优先级 1,组 2
MY_NVIC_Init(2,0,EXTI15_10_IRQn,2); //抢占 2,子优先级 0,组 2 }

函数 void EXTI_Init(void)是用来初始化外部中断。

EXTI0_IRQHandler(void)
void EXTI9_5_IRQHandler(void)
void EXTI15_10_IRQHandler(void)
这三个函数时各个按键的中断服务函数。

  这里向大家说明一下,STM32 的外部中断 0~4 都有单独的中断服务函数,但是从 5 开始,他们就没有单独的服务函数了,而是多个中断共用一个服务函数,比如外部中断 5~9 的中断服务函数为:void EXTI9_5_IRQHandler(void),类似的,void EXTI15_10_IRQHandler(void)就是外部中断 10~15 的中断服务函数。

  该函数为 Ex_NVIC_Config,该函数有 3 个参数:GPIOx 为 GPIOAG(06),在 sys.h 里面有定义。代表要配置的 IO 口。BITx则代表这个 IO 口的第几位。TRIM 为触发方式,低 2 位有效(0x01 代表下降触发;0x02 代表上升沿触发;0x03 代表任意电平触发)。

  • 1
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值