|
@@ -116,7 +116,7 @@ STM32F103 有 20 个 EXTI 通道(EXTI0~EXTI19),每个 GPIO 引脚都可以
|
|
|
|
|
|
|
|
#include "stm32f10x.h"
|
|
#include "stm32f10x.h"
|
|
|
|
|
|
|
|
-void KEY_Init(void);
|
|
|
|
|
|
|
+void Key_Init(void);
|
|
|
|
|
|
|
|
#endif
|
|
#endif
|
|
|
```
|
|
```
|
|
@@ -129,40 +129,23 @@ void KEY_Init(void);
|
|
|
#include "led.h"
|
|
#include "led.h"
|
|
|
|
|
|
|
|
// KEY初始化:配置PF10为上拉输入 + EXTI中断
|
|
// KEY初始化:配置PF10为上拉输入 + EXTI中断
|
|
|
-void KEY_Init(void)
|
|
|
|
|
|
|
+void Key_Init(void)
|
|
|
{
|
|
{
|
|
|
- /* ========== 1. 开启时钟 ========== */
|
|
|
|
|
- // GPIOF时钟(操作PF10需要)
|
|
|
|
|
- RCC->APB2ENR |= RCC_APB2ENR_IOPFEN; // |=: IOPFEN位置1
|
|
|
|
|
- // AFIO时钟(配置中断线重映射需要)
|
|
|
|
|
- RCC->APB2ENR |= RCC_APB2ENR_AFIOEN; // |=: AFIOEN位置1
|
|
|
|
|
-
|
|
|
|
|
- /* ========== 2. 配置PF10为上拉输入 ========== */
|
|
|
|
|
- // MODE10[1:0] = 00 → 输入模式
|
|
|
|
|
- GPIOF->CRH &= ~GPIO_CRH_MODE10; // &=~: MODE10位清0
|
|
|
|
|
- // CNF10[1:0] = 10 → 上拉/下拉输入
|
|
|
|
|
- GPIOF->CRH |= GPIO_CRH_CNF10_1; // |=: CNF10_1位置1
|
|
|
|
|
- GPIOF->CRH &= ~GPIO_CRH_CNF10_0; // &=~: CNF10_0位清0
|
|
|
|
|
- // 开启上拉电阻(ODR对应位置1 = 上拉)
|
|
|
|
|
- // PF10 ODR位=1 → 上拉;ODR位=0 → 下拉
|
|
|
|
|
- GPIOF->ODR &= ~GPIO_ODR_ODR10; // 选择下拉(按键未按时低电平)
|
|
|
|
|
-
|
|
|
|
|
- /* ========== 3. AFIO选择EXTI中断线 ========== */
|
|
|
|
|
- // EXTI10连接到PF10(EXTICR[2]的第8~11位控制EXTI10~EXTI13)
|
|
|
|
|
|
|
+ RCC->APB2ENR |= RCC_APB2ENR_IOPFEN;
|
|
|
|
|
+ RCC->APB2ENR |= RCC_APB2ENR_AFIOEN;
|
|
|
|
|
+
|
|
|
|
|
+ GPIOF->CRH &= ~GPIO_CRH_MODE10;
|
|
|
|
|
+ GPIOF->CRH |= GPIO_CRH_CNF10_1;
|
|
|
|
|
+ GPIOF->CRH &= ~GPIO_CRH_CNF10_0;
|
|
|
|
|
+ GPIOF->ODR &= ~GPIO_ODR_ODR10;
|
|
|
|
|
+
|
|
|
AFIO->EXTICR[2] |= AFIO_EXTICR3_EXTI10_PF;
|
|
AFIO->EXTICR[2] |= AFIO_EXTICR3_EXTI10_PF;
|
|
|
|
|
|
|
|
- /* ========== 4. 配置EXTI ========== */
|
|
|
|
|
- // RTSR: 上升沿触发选择寄存器 — PF10从低变高(按键按下)时触发
|
|
|
|
|
- EXTI->RTSR |= EXTI_RTSR_TR10; // |=: EXTI10上升沿触发使能
|
|
|
|
|
- // IMR: 中断屏蔽寄存器 — 允许EXTI10产生中断
|
|
|
|
|
- EXTI->IMR |= EXTI_IMR_MR10; // |=: EXTI10中断不屏蔽
|
|
|
|
|
|
|
+ EXTI->RTSR |= EXTI_RTSR_TR10;
|
|
|
|
|
+ EXTI->IMR |= EXTI_IMR_MR10;
|
|
|
|
|
|
|
|
- /* ========== 5. 配置NVIC ========== */
|
|
|
|
|
- // 设置优先级分组为Group_3:3位抢占(8级) + 1位子优先(2级)
|
|
|
|
|
NVIC_SetPriorityGrouping(3);
|
|
NVIC_SetPriorityGrouping(3);
|
|
|
- // 设置EXTI15_10中断的抢占优先级=2
|
|
|
|
|
- NVIC_SetPriority(EXTI15_10_IRQn, 2);
|
|
|
|
|
- // 使能EXTI15_10中断通道
|
|
|
|
|
|
|
+ NVIC_SetPriority(EXTI15_10_IRQn, 3);
|
|
|
NVIC_EnableIRQ(EXTI15_10_IRQn);
|
|
NVIC_EnableIRQ(EXTI15_10_IRQn);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
@@ -175,7 +158,7 @@ void EXTI15_10_IRQHandler(void)
|
|
|
EXTI->PR |= EXTI_PR_PR10; // |=: PR10写1清除
|
|
EXTI->PR |= EXTI_PR_PR10; // |=: PR10写1清除
|
|
|
|
|
|
|
|
/* 2. 软件消抖 */
|
|
/* 2. 软件消抖 */
|
|
|
- Delay_ms(15); // 等待15ms避开抖动期
|
|
|
|
|
|
|
+ Delay_ms(10); // 等待10ms避开抖动期
|
|
|
|
|
|
|
|
/* 3. 再次确认按键确实按下 */
|
|
/* 3. 再次确认按键确实按下 */
|
|
|
// 读取IDR判断PF10是否仍为高电平(屏蔽状态)
|
|
// 读取IDR判断PF10是否仍为高电平(屏蔽状态)
|
|
@@ -196,7 +179,7 @@ void EXTI15_10_IRQHandler(void)
|
|
|
int main(void)
|
|
int main(void)
|
|
|
{
|
|
{
|
|
|
LED_Init(); // LED初始化
|
|
LED_Init(); // LED初始化
|
|
|
- KEY_Init(); // KEY初始化(含中断配置)
|
|
|
|
|
|
|
+ Key_Init(); // KEY初始化(含中断配置)
|
|
|
|
|
|
|
|
while (1)
|
|
while (1)
|
|
|
{
|
|
{
|
|
@@ -230,12 +213,12 @@ HAL 库中断处理流程:
|
|
|
// HAL库的中断回调函数(由HAL_GPIO_EXTI_IRQHandler调用)
|
|
// HAL库的中断回调函数(由HAL_GPIO_EXTI_IRQHandler调用)
|
|
|
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
|
|
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
|
|
|
{
|
|
{
|
|
|
- if (GPIO_Pin == KEY1_Pin) // 判断是哪个引脚触发的中断
|
|
|
|
|
|
|
+ if (GPIO_Pin == KEY3_Pin) // PF10 对应 KEY3_Pin
|
|
|
{
|
|
{
|
|
|
- HAL_Delay(15); // 消抖
|
|
|
|
|
- if (HAL_GPIO_ReadPin(KEY1_GPIO_Port, KEY1_Pin) == GPIO_PIN_SET) // 再次确认
|
|
|
|
|
|
|
+ HAL_Delay(10); // 消抖
|
|
|
|
|
+ if (HAL_GPIO_ReadPin(GPIOF, KEY3_Pin) == GPIO_PIN_SET)
|
|
|
{
|
|
{
|
|
|
- HAL_GPIO_TogglePin(LED1_GPIO_Port, LED1_Pin); // 翻转LED
|
|
|
|
|
|
|
+ HAL_GPIO_TogglePin(GPIOA, GPIO_PIN_0); // 翻转 LED1
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
@@ -252,7 +235,7 @@ void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
|
|
|
|
|
|
|
|
| 函数/操作 | 代码 | 说明 |
|
|
| 函数/操作 | 代码 | 说明 |
|
|
|
|-----------|------|------|
|
|
|-----------|------|------|
|
|
|
-| KEY初始化 | `KEY_Init()` | 时钟+GPIO+AFIO+EXTI+NVIC |
|
|
|
|
|
|
|
+| KEY初始化 | `Key_Init()` | 时钟+GPIO+AFIO+EXTI+NVIC |
|
|
|
| 清除中断标志 | `EXTI->PR |= EXTI_PR_PR10` | 写1清除挂起位 |
|
|
| 清除中断标志 | `EXTI->PR |= EXTI_PR_PR10` | 写1清除挂起位 |
|
|
|
| 读取引脚 | `GPIOF->IDR & GPIO_IDR_IDR10` | &测试:测量PF10电平 |
|
|
| 读取引脚 | `GPIOF->IDR & GPIO_IDR_IDR10` | &测试:测量PF10电平 |
|
|
|
| 软件消抖 | `Delay_ms(15)` | 避开机械抖动期 |
|
|
| 软件消抖 | `Delay_ms(15)` | 避开机械抖动期 |
|