STM32F429第十七篇之外部中断实验详解
发布日期:2021-05-14 11:31:31 浏览次数:21 分类:精选文章

本文共 3952 字,大约阅读时间需要 13 分钟。

前言

本文介绍了正点原子外部中断实验的实现方式。代码基于正点原子开发,主要功能包括: - key0:控制LED0和LED1的点亮与熄灭 - key1:控制LED1的点亮与熄灭 - key2:控制LED0的点亮与熄灭 - key3:实现LED0与LED1的交替点亮

本文参考文献主要为:

  • ST.STM32F429开发指南-HAL库版本_V1.1

文章中使用的代码工程可见以下文档:

硬件

实验硬件由正点原子控制器及相关输入输出端连接组成。各导线与控制器GPIO连接方式如下:
导线名称 GPIO端口
WKUP PA0
key0 PH3
key1 PH2
key2 PC13

软件

主程序

```c #include "stm32f4xx.h" #include "sys.h" #include "exti.h" #include "led.h" #include "usart.h"

int main()

{
HAL_Init();
SystemClock_Config();
LedInit();
UartInit();
ExtiInit();
printf("hello,zhy!");
while(1)
{
}
}

本程序主要进行模块初始化,重点关注外部中断初始化功能ExtiInit(),其余模块在其他文章已详细介绍。  

初始化

ExtiInit函数

```c
void ExtiInit()
{
/* GPIO时钟使能 */
__HAL_RCC_GPIOA_CLK_ENABLE();
__HAL_RCC_GPIOC_CLK_ENABLE();
__HAL_RCC_GPIOH_CLK_ENABLE();
/* GPIO初始化 */
GPIO_InitTypeDef gpioInit;
gpioInit.Pin = GPIO_PIN_0; /* PA0 */
gpioInit.Mode = GPIO_MODE_IT_RISING; /* 上升沿 */
gpioInit.Pull = GPIO_PULLDOWN; /* 下拉 */
HAL_GPIO_Init(GPIOA, &gpioInit);
gpioInit.Pin = GPIO_PIN_2 | GPIO_PIN_3; /* PH2和PH3 */
gpioInit.Mode = GPIO_MODE_IT_FALLING; /* 下降沿 */
HAL_GPIO_Init(GPIOH, &gpioInit);
gpioInit.Pin = GPIO_PIN_13;
HAL_GPIO_Init(GPIOC, &gpioInit);
/* 中断优先级与使能 */
HAL_NVIC_SetPriority(EXTI0_IRQn, 2, 0);
HAL_NVIC_EnableIRQ(EXTI0_IRQn);
HAL_NVIC_SetPriority(EXTI2_IRQn, 2, 1);
HAL_NVIC_EnableIRQ(EXTI2_IRQn);
HAL_NVIC_SetPriority(EXTI3_IRQn, 2, 2);
HAL_NVIC_EnableIRQ(EXTI3_IRQn);
HAL_NVIC_SetPriority(EXTI15_10_IRQn, 2, 3);
HAL_NVIC_EnableIRQ(EXTI15_10_IRQn);
}

HAL_GPIO_Init函数

```c void HAL_GPIO_Init(GPIO_TypeDef *GPIOx, GPIO_InitTypeDef *GPIO_Init) { /* 省略前面部分代码 */
/*--------------------- EXTI Mode Configuration ------------------------*/  
/* Configure the External Interrupt or event for the current IO */
if((GPIO_Init-&>Mode & EXTI_MODE) == EXTI_MODE)
{
/* 系统时钟使能 */
__HAL_RCC_SYSCFG_CLK_ENABLE();
temp = SYSCFG->EXTICR[position >> 2U];
temp &= ~(((uint32_t)0x0FU) << (4U * (position & 0x03U))];
temp |= ((uint32_t)(GPIO_GET_INDEX(GPIOx)) << (4U * (position & 0x03U))];
SYSCFG->EXTICR[position >> 2U] = temp;
/* 清空EXTI配置 */
temp = EXTI->IMR;
temp &= ~((uint32_t)iocurrent)];
if((GPIO_Init-&>Mode & GPIO_MODE_IT) == GPIO_MODE_IT)
{
temp |= iocurrent];
}
EXTI->IMR = temp;
temp = EXTI->EMR;
temp &= ~((uint32_t)iocurrent)];
if((GPIO_Init-&>Mode & GPIO_MODE_EVT) == GPIO_MODE_EVT)
{
temp |= iocurrent];
}
EXTI->EMR = temp;
/* 清空边缘配置 */
temp = EXTI->RTSR;
temp &= ~((uint32_t)iocurrent)];
if((GPIO_Init-&>Mode & RISING_EDGE) == RISING_EDGE)
{
temp |= iocurrent];
}
EXTI->RTSR = temp;
temp = EXTI->FTSR;
temp &= ~((uint32_t)iocurrent)];
if((GPIO_Init-&>Mode & FALLING_EDGE) == FALLING_EDGE)
{
temp |= iocurrent];
}
EXTI->FTSR = temp;
}

}

中断响应

EXTIx_IRQHandler

```c
void EXTI0_IRQHandler()
{
flagExti0 = 1;
HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_0);
}

HAL_GPIO_EXTI_IRQHandler

```c void HAL_GPIO_EXTI_IRQHandler(uint16_t GPIO_Pin) { if(__HAL_GPIO_EXTI_GET_IT(GPIO_Pin) != RESET) { __HAL_GPIO_EXTI_CLEAR_IT(GPIO_Pin); HAL_GPIO_EXTI_Callback(GPIO_Pin); } } ```

HAL_GPIO_EXTI_Callback

```c void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin) { delay_ms(100); // 消抖
switch (GPIO_Pin)  
{
case GPIO_PIN_0:
if (WKUP == 1)
{
LED1 = LED0;
LED0 = !LED0;
}
break;
case GPIO_PIN_2:
if (KEY1 == 0)
{
LED1 = !LED1;
}
break;
case GPIO_PIN_3:
if (KEY0 == 0)
{
LED1 = !LED1;
LED0 = LED1;
}
break;
case GPIO_PIN_13:
if (KEY2 == 0)
{
LED0 = !LED0;
}
break;
}

}

注意:

本实验通过外部中断模式配置按键输入端,尽管如此,我们仍然可以读取GPIO状态并判断按键状态。这是外部中断机制的一大特点。
上一篇:STM32F429第十八篇之基本定时器
下一篇:STM32F429第十六篇之外部中断

发表评论

最新留言

不错!
[***.144.177.141]2025年05月06日 01时29分02秒