MCU学习笔记
外部中断/事件控制器
1. IO口外部中断原理概述
2. IO口外部中断HAL库配置方法
3. IO口外部中断HAL库配置例子
1. IO口外部中断原理概述
- STM32控制器支持的外部中断/事件请求
- IO口外部中断
STM32每个IO口都可以作为外部中断输入
每个外部中断线可以独立的配置触发方式(上升沿,下降沿,双边沿触发),触发/屏蔽,专用的状态位。
STM32供IO使用的中断线只有16个,但STM32F系列的IO口多达上百个 - GPIO和中断线映射的关系
M3/M7:配置寄存器SYSCFG_EXTIRx
MS3:配置寄存器AFIO_EXTIRx
注意:
不是16个中断线,就对应着16个中断函数;IO口中断在中断向量表中只分配了7个中断向量,即只能使用7个中断函数
- 中断函数列表
EXTI0_IRQHandler
EXTI1_IRQHandler
EXTI2_IRQHandler
EXTI3_IRQHandler
EXTI4_IRQHandler
EXTI9_5_IRQHandler
EXTI15_10_IRQHandler
2. IO口外部中断HAL库配置方法
-
外部中断的配置步骤:
- 使能IO口时钟
- 初始化IO口,设置触发方式:HAL_GPIO_Init();
- 设置中断优先级,并使能中断通道
- 编写中断服务函数:
函数中调用外部中断通用处理函数HAL_GPIO_EXTI0_IRQHandler - 编写外部中断回调函数:HAL_GPIO_EXTI0_Callback
-
外部中断配置
外部中断的中断线映射配置和触发方式都是在GPIO初始化函数中完成。
GPIO_InitTypeDef GPIO_Initure;
GPIO_Initure.Pin= GPIO_Pin_0;//PA0
GPIO_Initure.Mode= GPIO_Mode_IT_RISING;//上升沿触发
GPIO_Initure.Pull= GPIO_PULLDOWN;
HAL_GPIO_Init(GPIOA,&GPIO_Initure);
- 外部中断通用处理函数
在外部中断服务函数中调用HAL_GPIO_EXTI0_IRQHandler函数处理中断;
HAL_GPIO_EXTI0_IRQHandler函数内部通过判断中断来源引脚,最终调用外部中断回调函数HAL_GPIO_EXTI0_Callback来处理中断;
HAL_GPIO_EXTI0_IRQHandler;//
HAL_GPIO_EXTI0_Callback;//外部中断回调函数
3. IO口外部中断HAL库配置例子
按键控制LED灯显示
#include "exti.h"
#include "led.h"
#include "delay.h"
#include "key.h"
#include "exti.h"
/*********************************
使能IO口时钟,初始化IO口,设置触发方式
*********************************/
void EXTI_Init(void)
{
GPIO_InitTypeDef GPIO_Initure;
__HAL_RCC_GPIOA_CLK_ENABLE(); //使能GPIOA时钟
__HAL_RCC_GPIOC_CLK_ENABLE(); //使能GPIOC时钟
__HAL_RCC_GPIOH_CLK_ENABLE(); //使能GPIOH时钟
GPIO_Initure.Pin= GPIO_Pin_0;//PA0
GPIO_Initure.Mode= GPIO_Mode_IT_RISING;//上升沿触发
GPIO_Initure.Pull= GPIO_PULLDOWN;//下拉
GPIO_Initure.Speed= GPIO_SPEED_HIGH;//高速
HAL_GPIO_Init(GPIOA,&GPIO_Initure);
GPIO_Initure.Pin= GPIO_Pin_3;//PH3
GPIO_Initure.Mode= GPIO_Mode_IT_FALLING;//下降沿触发
GPIO_Initure.Pull= GPIO_PULLUP;//上拉
GPIO_Initure.Speed= GPIO_SPEED_HIGH;//高速
HAL_GPIO_Init(GPIOA,&GPIO_Initure);
GPIO_Initure.Pin= GPIO_Pin_2|GPIO_Pin_3;//PH2,3
HAL_GPIO_Init(GPIOA,&GPIO_Initure);
/*********************************
设置后中断优先级
*********************************/
HAL_NVIC_EnableIRQ(EXIT0_IRQn); //
HAL_NVIC_SetPriority(EXIT0_IRQn,2,0);//
HAL_NVIC_EnableIRQ(EXIT2_IRQn); //
HAL_NVIC_SetPriority(EXIT2_IRQn,2,1);//
HAL_NVIC_EnableIRQ(EXIT0_IRQ3); //
HAL_NVIC_SetPriority(EXIT0_IRQ3,2,2);//
HAL_NVIC_EnableIRQ(EXIT15_10_IRQn); //
HAL_NVIC_SetPriority(EXIT15_10_IRQn,2,3);//
}
/*********************************
编写中断服务函数
*********************************/
void EXTI0_IRQHandler()
{
HAL_GPIO_EXTI0_IRQHandler(GPIO_PIN_0);
}
void EXTI2_IRQHandler()
{
HAL_GPIO_EXTI0_IRQHandler(GPIO_PIN_2);
}
void EXTI3_IRQHandler(void)
{
HAL_GPIO_EXTI0_IRQHandler(GPIO_PIN_3);
}
void EXTI5_10_IRQHandler(void)
{
HAL_GPIO_EXTI0_IRQHandler(GPIO_PIN_13);
}
/*********************************
编写外部中断回调函数
*********************************/
void HAL_GPIO_EXTI0_Callback()
{
switch(GPIO_Pin)
{
case:GPIO_Pin_0:
if(WK_UP==1)
{
LED1=!LED1;//控制逻辑
LED0=!LED1;
}
break;
case:GPIO_Pin_13:
if(KEY2==0)
{
LED0=!LED0;//控制逻辑
}
break;
case:GPIO_Pin_2:
if(KEY1==0)
{
LED1=!LED1;//控制逻辑
}
break;
case:GPIO_Pin_3:
if(KEY0==0)
{
LED0=!LED0;//控制逻辑
LED1=!LED1;
}
break;
}
}
/*********************************
主函数
*********************************/
int main(void)
{
HAL_Int();//初始化HAL库
Stm32_Clocu_Init(360,25,2,8);//设置时钟
delay_init(180);//初始化延时
uart_int(115200);//初始化USART
LED_Init();//初始化LED
EXTI_Init();
while(1)
{
printf("OK\r\n");
delay_ms(1000);
}
}
参考资料:正点原子视频 Thanks^^
【注】:个人学习笔记,如有错误,望不吝赐教,这厢有礼了~~~