个人学习理解
在我们学习写代码的过程中,我们配合着开发指南中的程序设计的配置步骤并与我们的学习视频结合着、对比着学习,这能更加让我们对程序设计步骤理解得更加透彻。
硬件了解
1、LED灯
LED0 – PB5
LED1 – PE5
2、独立按键
KEY0 – PE4
KEY1 – PE3
KEY2 – PE2
KEY_UP – PA0
3、原理图
EXTI外部中断配置步骤
STM32f103战舰v4开发指南中的程序设计步骤
1)使能对应GPIO口时钟 本实验用到的GPIO 和按键输入实验是一样的,因此GPIO时钟使能也是一样的,请参考 上一章代码。
2)设置GPIO工作模式,触发条件,开启AFIO时钟,设置IO口与中断线的映射关系 这些步骤HAL库全部封装在HAL_GPIO_Init函数里面,我们只需要设置好对应的参数, 再调用HAL_GPIO_Init函数即可完成配置。
3)配置中断优先级(NVIC),并使能中断。 配置好 GPIO 模式以后,我们需要设置中断优先级和使能中断,中断优先级我们使用 HAL_NVIC_SetPriority 函数设置,中断使能我们使用HAL_NVIC_EnableIRQ函数设置。
4)编写中断服务函数。 每开启一个中断,就必须编写其对应的中断服务函数,否则将导致死机(CPU将找不到中 断服务函数)。中断服务函数接口厂家已经在startup_stm32f103xe.s 中做好了,STM32F1 的 IO 口外部中断函数只有7个,分别为:
void EXTI0_IRQHandler();
void EXTI1_IRQHandler();
void EXTI2_IRQHandler();
void EXTI3_IRQHandler();
void EXTI4_IRQHandler();
void EXTI9_5_IRQHandler();
void EXTI15_10_IRQHandler();
中断线0-4,每个中断线对应一个中断函数,中断线5-9共用中断函数EXTI9_5_IRQHandler, 中断线10-15共用中断函数EXTI15_10_IRQHandler。一般情况下,我们可以把中断控制逻辑直 接编写在中断服务函数中,但是HAL库把中断处理过程进行了简单封装,请看步骤5讲解。
5)编写中断处理回调函数HAL_GPIO_EXTI_Callback HAL库为了用户使用方便,提供了一个中断通用入口函数HAL_GPIO_EXTI_IRQHandler, 在该函数内部直接调用回调函数HAL_GPIO_EXTI_Callback。 我们先看一下HAL_GPIO_EXTI_IRQHandler函数定义:
void HAL_GPIO_EXTI_IRQHandler(uint16_t GPIO_Pin)
{
/* EXTI line interrupt detected */
if (__HAL_GPIO_EXTI_GET_IT(GPIO_Pin) != 0x00u)
{
__HAL_GPIO_EXTI_CLEAR_IT(GPIO_Pin); //清除中断标志位
HAL_GPIO_EXTI_Callback(GPIO_Pin); //外部中断回调函数
}
}
该函数实现的作用非常简单,通过入口参数GPIO_Pin判断中断来自哪个IO口,然后清除 相应的中断标志位,最后调用回调函数HAL_GPIO_EXTI_Callback()实现控制逻辑。在所有的外 部中断服务函数中直接调用外部中断共用处理函数HAL_GPIO_EXTI_IRQHandler,然后在回调函数HAL_GPIO_EXTI_Callback 中通过判断中断是来自哪个 IO 口编写相应的中断服务控制逻 辑。
因此我们可以在HAL_GPIO_EXTI_Callback里面实现控制逻辑编写。
源码
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时钟使能
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() //编写外部中断服务函数
{
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(10);
if(GPIO_Pin == GPIO_PIN_4)
{
if(HAL_GPIO_ReadPin(GPIOE,GPIO_PIN_4) == 0)
{
HAL_GPIO_TogglePin(GPIOB,GPIO_PIN_5); //翻转为PB5
} //因为原来设置的是PE5-LED1灯亮翻转成PB5,PE5就会灭
}
}
exti.h
#ifndef __EXTI_H
#define __EXTI_H
#include "./SYSTEM/sys/sys.h"
void exti_init(void);
#endif
main.c
#include "./SYSTEM/sys/sys.h"
#include "./SYSTEM/delay/delay.h"
#include "./SYSTEM/usart/usart.h"
#include "./BSP/LED/led.h"
#include "./BSP/EXTI/exti.h"
int main(void)
{
HAL_Init(); /* 初始化HAL库 */
sys_stm32_clock_init(RCC_PLL_MUL9); /* 设置时钟,72M */
delay_init(72); /* 初始化延时函数 */
led_init(); /* 初始化LED */
exti_init();
while(1)
{
LED1(1); /* LED1 灭 */
delay_ms(500);
LED1(0); /* LED1 亮 */
delay_ms(500);
}
}
标签:灯亮,HAL,函数,中断,void,STM32,GPIO,EXTI
From: https://blog.csdn.net/2302_79878697/article/details/136786205