
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状态并判断按键状态。这是外部中断机制的一大特点。
发表评论
最新留言
不错!
[***.144.177.141]2025年05月06日 01时29分02秒
关于作者

喝酒易醉,品茶养心,人生如梦,品茶悟道,何以解忧?唯有杜康!
-- 愿君每日到此一游!
推荐文章
项目计划甘特图绘制说明
2019-03-12
C/C++:线性表之顺序表
2019-03-12
嵌入式系统试题库(CSU)
2019-03-12
图神经网络7日打卡营学习心得
2019-03-12
electronJS 开发linux App
2019-03-12
MbedOS 设备中的模数转换(ADC)
2019-03-12
【vue】setInterval的嵌套实例
2019-03-12
【SpringBoot】如何配置热部署
2019-03-12
【rabbitMQ】04 如何实现高可用?
2019-03-12
【自考】之信息资源管理(一)
2019-03-12
C# 文本框限制大全
2019-03-12
setup facatory9.0打包详细教程(含静默安装和卸载)
2019-03-12
ionic4 路由跳转传值
2019-03-12
CSDN 怎么写出好看的博客
2019-03-12
pwn题shellcode收集
2019-03-12
python中的序列化
2019-03-12
django中使用celery执行异步任务实现
2019-03-12
lora技术在无线抄表行业应用
2019-03-12