STM32F103HAL库学习3——外部中断EXTI使用

第三章 STM32F103C8T6的HAL库外部中断EXTI使用


前言

本章开始学习外部中断EXTI的使用,掌握外部中断的触发方式,中断线,优先级,中断号,回调函数以及如何配置EXTI。末尾附带源代码供参考学习。


一、EXTI是什么?

EXTI是 允许将来自不同外设的中断 / 事件请求信号连接到微控制器的中断系统,实现对外设事件的快速响应。它可以检测外部输入信号的变化,如按键按下、传感器信号变化等,并触发相应的中断处理程序。

二、EXTI主要特点

1.支持多种触发方式

外部信号的形式一般都是以高低电平的形式发送,1为高电平,0为低电平,在低电平向高电平转变时会出现上升沿,在高电平向低电平转变时会出现下降沿,如下图所示,引脚初始化时处于上拉或者下拉状态,可根据不同使用情况进行配合,例如当输入信号是低电平时,可以采用上拉下降沿触发,当输入信号为高电平是,可采用下拉上升沿触发,当需要上升沿和下降沿都出触发时,模式选择无上拉或下拉。
在这里插入图片描述
上升沿触发:当外部信号从低电平变为高电平时触发中断。

gpio_init_struct.Mode = GPIO_MODE_IT_RISING;       

下降沿触发:当外部信号从高电平变为低电平时触发中断。

gpio_init_struct.Mode = GPIO_MODE_IT_FALLING;         

双边沿触发:外部信号的上升沿和下降沿都能触发中断。

gpio_init_struct.Mode = GPIO_MODE_IT_RISING_FALLING;        

2.中断优先级配置

抢占优先级:高抢占优先级可以打断正在执行的低抢占优先级中断。
响应优先级:当抢占优先级相同时,响应优先级高的先执行,但是不能互相打断。
数值越小,优先级越高。
在这里插入图片描述
通过设置中断优先级,可以确定不同中断源的响应顺序,高优先级的中断可以抢占低优先级的中断执行。如下面两条语句,0的优先级比1的优先级高,所以在同时产生中断时肯定第一条语句的中断服务函数先执行。

HAL_NVIC_SetPriority(EXTI9_5_IRQn, 0, 2);               /* 抢占0,子优先级2 */

HAL_NVIC_SetPriority(EXTI0_IRQn, 1, 2);               /* 抢占1,子优先级2 */

3.中断线

所有相同数字的引脚共用一条中断线,例如PA0和PB0共用一条中断线,一个中断线一次只能响应一个引脚的中断,当两个同时进入中断时,优先级高的先响应。
在这里插入图片描述

4.中断号

每个引脚有相应的中断号,0到4有自己一一对应的中断号,5到9共用一个中断号,10到15共用一个中断号。
在这里插入图片描述

5.中断服务函数及回调函数

当外部触发中断时会进入中断服务程序清楚中断标志位,同时会进入外部中断回调函数,在回调函数中执行相应的指令,回调函数括号中为该中断引脚号,所有中断服务函数都会调用回调函数,所以需要在回调函数中进行引脚号的判断。例如PA8的中断服务函数与回调函数。

/*中断服务函数*/
void EXTI9_5_IRQHandler(void)
{ 
    HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_8);        /* 调用中断处理公用函数 清除PA8所在中断线的中断标志位*/
}

/*外部中断回调函数*/
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
{  
	if(GPIO_Pin == GPIO_PIN_8)
	{
	HAL_GPIO_WritePin(GPIOB, GPIO_PIN_5, GPIO_PIN_SET);
	delay_ms(500);
	HAL_GPIO_WritePin(GPIOB, GPIO_PIN_5, GPIO_PIN_RESET);
	}
}

三、程序编写

了解完EXTI的一些含义和特点就可以对外部中断进行配置,包括exti初始化配置,中断服务函数配置,回调函数指令编写。
首先可以先创建个exti.c和.h文件保存在工程文件夹下,此次仅以PA8引脚为例写一个配置函数,同样多次引用外部中断时可以在此基础上添加。
下面是exti.c库文件程序

#include "main.h"

/*中断服务函数*/
void EXTI9_5_IRQHandler(void)
{
    HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_8);        /* 调用中断处理公用函数 清除PA8所在中断线的中断标志位*/
}
    
/*外部中断回调函数*/
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
{  
	if(GPIO_Pin == GPIO_PIN_8)
   {
	HAL_GPIO_WritePin(GPIOB, GPIO_PIN_5, GPIO_PIN_SET);
	delay_ms(500);
	HAL_GPIO_WritePin(GPIOB, GPIO_PIN_5, GPIO_PIN_RESET);
   }
}

void exti_init(void)
{
    GPIO_InitTypeDef gpio_init_struct;
    __HAL_RCC_GPIOA_CLK_ENABLE();                              
    gpio_init_struct.Pin = GPIO_PIN_8;
    gpio_init_struct.Mode = GPIO_MODE_IT_FALLING;            /* 下升沿触发 */
    gpio_init_struct.Pull = GPIO_PULLUP;                    /* 上拉 */                 
    HAL_GPIO_Init(GPIOA, &gpio_init_struct);  

    HAL_NVIC_SetPriority(EXTI9_5_IRQn, 0, 2);               /* 抢占0,子优先级2 */
    HAL_NVIC_EnableIRQ(EXTI9_5_IRQn);                       /* 使能中断线8 */
}

下面是exti.h文件

#ifndef __exti_H
#define __exti_H
void exti_init(void);
#endif

主函数main.c中对exti函数进行初始化,回调函数中要使用到delay延时,所以需要添加时钟配置,下一篇文章将讲解时钟配置相关内容,while可以进行空循环,等待外部中断信号。

#include "main.h"

int main(void)
{
   HAL_Init();                         /* 初始化HAL库 */
   sys_stm32_clock_init(RCC_PLL_MUL9); /* 设置时钟, 72Mhz */
   delay_init(72);                     /* 延时初始化 */
   led_init();
   key_init();  
   exti_init();
 
    while(1)
    {  

    }
}

最后是主函数main.h文件,将exti.h文件放入其中,方便其他函数调用。

#ifndef __main_H
#define __mian_H
#include "stm32f1xx.h"
#include "stm32f1xx_hal.h"
#include "stm32f1xx_it.h"
#include "delay.h"
#include "sys.h"
#include "led.h"
#include "key.h"
#include "exti.h"
#endif


总结

以上就是今天要讲的内容,本文简单介绍了外部中断exti的使用,掌握exti的触发方式,优先级,在使用外部中断功能时需要了解该引脚的中断线,中断号,防止引脚使用同一个中断线,掌握exti的配置,中断服务函数与回调函数的使用,如果有疑问的地方可以私信我,若有讲错的地方还请批评指正,让我们一起学习,一起进步。
源代码链接:https://pan.baidu.com/s/1hzCq_nN06fB_h3cj6ShVmQ
提取码:zstu

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值