OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 259|回复: 1

STM32F103中断开启失败(寄存器写法)

[复制链接]

2

主题

3

帖子

0

精华

新手入门

积分
6
金钱
6
注册时间
2026-8-3
在线时间
2 小时
发表于 7 天前 | 显示全部楼层 |阅读模式
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)
{
    // &#9989; 步骤1:先检查中断标志
    if(EXTI->PR & EXTI_PR_PR3)
    {
        // &#9989; 步骤2:清除中断标志(立即清除,防止重复进入)
        EXTI->PR |= EXTI_PR_PR3;

        // &#9989; 步骤3:简单硬件消抖(不使用Delay_ms)
        for(volatile int i = 0; i < 10000; i++);

        // &#9989; 步骤4:再次读取GPIO电平,确认按键确实按下
        if((GPIOE->IDR & GPIO_IDR_IDR3) == 0)  // 低电平表示按下
        {
            LED_Toggle(LED0);  // 翻转红色LED
        }
    }
}

// ========== KEY0 (PE4) 中断服务函数 ==========
void EXTI4_IRQHandler(void)
{
    // &#9989; 步骤1:先检查中断标志
    if(EXTI->PR & EXTI_PR_PR4)
    {
        // &#9989; 步骤2:清除中断标志
        EXTI->PR |= EXTI_PR_PR4;

        // &#9989; 步骤3:简单硬件消抖
        for(volatile int i = 0; i < 10000; i++);

        // &#9989; 步骤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控制都在中断中完成
    }
}

Elite_DNF103 V2.6.pdf

1.3 MB, 下载次数: 0

回复

使用道具 举报

2

主题

3

帖子

0

精华

新手入门

积分
6
金钱
6
注册时间
2026-8-3
在线时间
2 小时
 楼主| 发表于 7 天前 | 显示全部楼层
对不起,对不起,是我发现我写错了,因为我这里都用了很多led,但是我发现我没有引用led的头文件,我忘记引用了
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



关闭

原子哥极力推荐上一条 /1 下一条

正点原子公众号

如发现本坛存在违规或侵权内容, 请点击这里发送邮件举报 (或致电020-38271790)。请提供侵权说明和联系方式。我们将及时审核依法处理,感谢配合。

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2026-8-25 19:02

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

快速回复 返回顶部 返回列表