新手入门
- 积分
- 6
- 金钱
- 6
- 注册时间
- 2026-8-3
- 在线时间
- 2 小时
|
8金钱
为,求帮助
什么不对呀
(๑•́ ₃ •̀๑)
现象是两个灯亮了两次,然后按按键没有反应
#include "Key.h"
#include "Delay.h"
// 添加这个函数
void SystemClock_Init(void)
{
// 1. 开启HSE(外部8MHz晶振)
RCC->CR |= RCC_CR_HSEON;
while(!(RCC->CR & RCC_CR_HSERDY));
// 2. 配置PLL: HSE 8MHz * 9 = 72MHz
RCC->CFGR |= RCC_CFGR_PLLSRC_HSE | RCC_CFGR_PLLMULL9;
// 3. 配置AHB/APB预分频
RCC->CFGR |= RCC_CFGR_HPRE_DIV1; // AHB = SYSCLK
RCC->CFGR |= RCC_CFGR_PPRE1_DIV2; // APB1 = HCLK/2
RCC->CFGR |= RCC_CFGR_PPRE2_DIV1; // APB2 = HCLK
// 4. 开启PLL
RCC->CR |= RCC_CR_PLLON;
while(!(RCC->CR & RCC_CR_PLLRDY));
// 5. 切换系统时钟到PLL
RCC->CFGR |= RCC_CFGR_SW_PLL;
while((RCC->CFGR & RCC_CFGR_SWS) != RCC_CFGR_SWS_PLL);
}
void Key_Init(void)
{
// 开启GPIOE和AFIO时钟
RCC->APB2ENR |= RCC_APB2ENR_IOPEEN;
RCC->APB2ENR |= RCC_APB2ENR_AFIOEN;
// PE3 (KEY1), PE4 (KEY0) 输入上拉
GPIOE->CRL &= ~(GPIO_CRL_MODE3 | GPIO_CRL_CNF3);
GPIOE->CRL |= GPIO_CRL_CNF3_1; // 上拉输入
GPIOE->CRL &= ~(GPIO_CRL_MODE4 | GPIO_CRL_CNF4);
GPIOE->CRL |= GPIO_CRL_CNF4_1; // 上拉输入
// AFIO映射 - PE3 -> EXTI3, PE4 -> EXTI4
AFIO->EXTICR[0] &= ~(0xF << 12);
AFIO->EXTICR[0] |= (0x4 << 12); // PE3 -> EXTI3
AFIO->EXTICR[1] &= ~(0xF << 0);
AFIO->EXTICR[1] |= (0x4 << 0); // PE4 -> EXTI4
// EXTI配置 - 下降沿触发(按键按下)
EXTI->FTSR |= EXTI_FTSR_TR3 | EXTI_FTSR_TR4;
EXTI->IMR |= EXTI_IMR_MR3 | EXTI_IMR_MR4;
// NVIC配置
NVIC_SetPriorityGrouping(3);
NVIC_SetPriority(EXTI3_IRQn, 2);
NVIC_EnableIRQ(EXTI3_IRQn);
NVIC_SetPriority(EXTI4_IRQn, 2);
NVIC_EnableIRQ(EXTI4_IRQn);
}
// ========== KEY1 (PE3) 中断服务函数 ==========
void EXTI3_IRQHandler(void)
{
// ✅ 步骤1:先检查中断标志
if(EXTI->PR & EXTI_PR_PR3)
{
// ✅ 步骤2:清除中断标志(立即清除,防止重复进入)
EXTI->PR |= EXTI_PR_PR3;
// ✅ 步骤3:简单硬件消抖(不使用Delay_ms)
for(volatile int i = 0; i < 10000; i++);
// ✅ 步骤4:再次读取GPIO电平,确认按键确实按下
if((GPIOE->IDR & GPIO_IDR_IDR3) == 0) // 低电平表示按下
{
LED_Toggle(LED0); // 翻转红色LED
}
}
}
// ========== KEY0 (PE4) 中断服务函数 ==========
void EXTI4_IRQHandler(void)
{
// ✅ 步骤1:先检查中断标志
if(EXTI->PR & EXTI_PR_PR4)
{
// ✅ 步骤2:清除中断标志
EXTI->PR |= EXTI_PR_PR4;
// ✅ 步骤3:简单硬件消抖
for(volatile int i = 0; i < 10000; i++);
// ✅ 步骤4:再次读取GPIO电平,确认按键确实按下
if((GPIOE->IDR & GPIO_IDR_IDR4) == 0) // 低电平表示按下
{
LED_Toggle(LED1); // 翻转绿色LED
}
}
}
#include "Key.h"
#include "Delay.h"
#include "LED.h"
int main(void)
{
// 初始化LED和按键
void SystemClock_Init();
LED_Init();
Key_Init();
// 开机指示:两个LED闪烁一下
LED_AllOn();
Delay_ms(500);
LED_AllOff();
Delay_ms(500);
LED_AllOn();
Delay_ms(500);
LED_AllOff();
while(1)
{
// 主循环可以执行其他任务
// 所有LED控制都在中断中完成
}
}
|
|