stm32 外部中断

1.每个IO都可以配置外部中断,中断的出发方式有上升沿、下降沿、双边沿。这个是在EXTI里配置。

2.所有IO总共分成了16组,(PA0,PB0...)、(PA1,PB1...)、(PA2,PB2...),...,(PA15,PB15...),这个不用配置。

3.虽然每个IO都可以配置外部中断,但是每个组只能选择一个使能,对于(PA0,PB0...)这个组来说,PA0、PB0、PC0、PD0...、PG0同一时刻只能有1个是使能有作用的。 具体选择哪一个需要配置AFIO。

4.stm32里的中断有抢占优先级和响应优先级的概念,高抢占优先级可以打断低抢占优先级,在抢占优先级相同的情况下,高响应优先级不能打断低响应优先级。 外部中断的优先级在NVIC里控制。

5.16个外部中断"按理"说应该有16个外部中断服务函数,实际上只有6个服务函数,其中EXTI5到EXTI9共用一个服务函数,EXTI10到EXTI15共用一个服务函数。抢断优先级和响应优先级具体能分成多少个级别,需要设置,分成NVIC_PRIORITYGROUP_2这种类型,抢占优先级取值范围0-3,响应也是0-3。

中断信号传输流程:GPIO口有电平信号的改变,AFIO判断该GPIO口有没有中断使能,如果有传入EXTI,EXTI检测该电平信号是上升沿还是下降沿,如果是规定的中断触发信号,传入NVIC,NVIC根据该中断的优先级在合适和时间传给CPU,CPU进入外部中断服务函数,如EXTI0亦或是EXTI15_10。

6.配置流程(配置PA0外部中断)

1.使能GPIO时钟

c 复制代码
__HAL_RCC_GPIOA_CLK_ENABLE(); //使能时钟

2.设置GPIO输入模式

3.设置AFIO(开启时钟、IO映射)

4.设置EXTI(屏蔽、上\下沿)

c 复制代码
GPIO_InitTypeDef gpioinit_struct;
gpioinit_struct.Mode = GPIO_MODE_IT_FALLING;  //下降沿触发
gpioinit_struct.Pin = GPIO_PIN_0;
gpioinit_struct.Pull = GPIO_PULLUP;
HAL_GPIO_Init(GPIOA, &gpioinit_struct);//输入模式、下降沿触发、IO映射 

5.设置NVIC(优先级分组--->设置优先级--->使能中断)

c 复制代码
HAL_NVIC_SetPriorityGrouping(NVIC_PRIORITYGROUP_2);//优先级分组,在HAL_Init()函数中修改,默认是NVIC_PRIORITYGROUP_4

HAL_NVIC_SetPriority(EXTI0_IRQn, 2, 0); //设置抢占和响应的优先级
HAL_NVIC_EnableIRQ(EXTI0_IRQn);//使能EXTI0这根线

6.设计中断服务函数

c 复制代码
void EXTI0_IRQHandler()//固定名称。在startup_....xb.s中
{
	HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_0);//清除中断标志位,调用HAL_GPIO_EXTI_Callback函数
}
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)//重构函数  __weak需要重构
{
	delay_ms(20);//消抖,为演示而演示,实际中断中不建议用delay, 
	if(GPIO_Pin == GPIO_PIN_0)
	{
		if(HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_0) == GPIO_PIN_RESET)
			led1_toggle();
	}
}

7.完整的EXTI.c和.h文件

c 复制代码
#include "sys.h"
#include "exti.h"
#include "led.h"
#include "delay.h"
void exti_init(void)
{
    __HAL_RCC_GPIOA_CLK_ENABLE(); //使能时钟
	
		GPIO_InitTypeDef gpioinit_struct;
		gpioinit_struct.Mode = GPIO_MODE_IT_FALLING;  //下降沿触发
		gpioinit_struct.Pin = GPIO_PIN_0;
		gpioinit_struct.Pull = GPIO_PULLUP;
		gpioinit_struct.Speed = GPIO_SPEED_FREQ_HIGH;
	
		HAL_GPIO_Init(GPIOA, &gpioinit_struct);
	
		HAL_NVIC_SetPriority(EXTI0_IRQn, 2, 0);
		HAL_NVIC_EnableIRQ(EXTI0_IRQn);

}

void EXTI0_IRQHandler()//startup_....xb.s中
{
	HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_0);//复位中断位,调用HAL_GPIO_EXTI_Callback函数
}

void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)//重构函数
{
	delay_ms(20);
	if(GPIO_Pin == GPIO_PIN_0)
	{
		if(HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_0) == GPIO_PIN_RESET)
			led1_toggle();
	}
}
c 复制代码
#ifndef __EXTI_H__
#define __EXTI_H__

void exti_init(void);

#endif
相关推荐
红花与香菇2____1 小时前
【学习笔记】Cadence电子设计全流程(二)原理图库的创建与设计(上)
笔记·嵌入式硬件·学习·pcb设计·cadence·pcb工艺
Jerry.yl2 小时前
关于 BK3633 上电时受串口 UART2 影响而无法启动的问题说明
嵌入式硬件·物联网·bk3633
苏慕TRYACE3 小时前
RT-Thread+STM32L475VET6实现红外遥控实验
stm32·单片机·嵌入式硬件·rt-thread
小幽余生不加糖5 小时前
deepseek帮我设计物理量采集单片机口保护电路方案
单片机·嵌入式硬件
Ronin-Lotus6 小时前
蓝桥杯篇---IAP15F2K61S2串口
单片机·嵌入式硬件·职场和发展·蓝桥杯·c·iap15f2k61s2
xiaohai@Linux6 小时前
ESP32 在IDF_V5.3.1版本下实现AP无线热点模式!(带WIFI事件处理)
c语言·嵌入式硬件·tcp/ip·wifi·esp32
yyqzjw7 小时前
【STM32】外部时钟|红外反射光电开关
stm32·单片机·嵌入式硬件
charlie1145141917 小时前
(萌新入门)如何从起步阶段开始学习STM32 —— 0.碎碎念
c语言·stm32·单片机·嵌入式硬件·学习·教程
苏慕TRYACE7 小时前
RT-Thread+STM32L475VET6——ADC采集电压
stm32·单片机·嵌入式硬件·rt-thread
jmlinux8 小时前
STM32 HAL库USART串口中断编程:环形缓冲区防止数据丢失
stm32·单片机·嵌入式硬件