STM32 通过寄存器外部中断 EXTI

文章详细介绍了如何在STM32F103ZET6芯片上通过配置RCC_APB2ENR启用AFIO,设置AFIO_EXTICR2选择GPIOE4作为外部中断输入,以及配置EXTI寄存器进行中断屏蔽、触发边沿选择和中断处理。代码示例展示了如何初始化GPIO并响应中断改变LED状态。
摘要由CSDN通过智能技术生成

芯片为STM32F103ZET6,STM32FXX手册

1.按键控制小灯泡(外部中断)

 

 

RCC_APB2ENR:位0是启用AFIO,不启用不能开启中断!,RCC的寄存器地址是 0x4002 1000 - 0x4002 13FF,APB2的偏移值为0x18,所以配置的地址就是0x4002 1018。

AFIO:事件寄存器没在用,跳过不管,外部中断配置寄存器有四个,分别是AFIO_EXTICR1,2,3,4,他们分别对应着GPIOABCDEFG的四个引脚,比如EXTICR1就是对应着0-4脚的GPIOABCDEFG,四个寄存器加起来刚好是16个脚的中断,每个位数的引脚同时只能有一个启用中断,如GPIOA的1脚启用了外部中断,GPIOBCDEFG的1脚就不能启用外部中断,当前使用的是PE4,所以用的是AFIO_EXTICR2,AFIO的地址是0x4001 0000,EXTICR2的偏移值是0x0C,所以配置地址就是0x4001 000C。

EXTI:目前用到的有 中断屏蔽寄存器(EXTI_IMR),上升沿触发选择寄存器(EXTI_RTSR),下降沿触发选择寄存器(EXTI_FTSR),挂起寄存器(EXTI_PR) ,EXTI的地址是0x4001 0400,偏移地址分别是0x00,0x08,0x0C,0x14,。没用到的寄存器分别是事件屏蔽寄存器(EXTI_EMR),软件中断事件寄存器(EXTI_SWIER) ,偏移地址分别是0x04,0x10。

//.h文件
typedef unsigned        int uint32_t;

#define PERIPH_BASE                    ((uint32_t)0x40000000)

#define GPIOB_CRL                    *(unsigned int*)(0x40010C00)
#define GPIOB_ODR                    *(unsigned int*)(0x40010C0C)
#define GPIOE_CRL                    *(unsigned int*)(0x40011800)
#define GPIOE_ODR                    *(unsigned int*)(0x4001180c)

#define APB2PERIPH_BASE                    ((uint32_t)PERIPH_BASE+0x10000)

#define RCC_APB2ENR                    *(unsigned int*)(0x40021018)

#define AFIO_EXTICR2                    *(unsigned int*)(0x4001000C)

#define EXTI_BASE                    ((uint32_t)APB2PERIPH_BASE+0x0400)
#define EXTI_IMR                    *(unsigned int*)(EXTI_BASE)
#define EXTI_EMR                    *(unsigned int*)(EXTI_BASE+0x04)
#define EXTI_RTSR                    *(unsigned int*)(EXTI_BASE+0x08)
#define EXTI_FTSR                    *(unsigned int*)(EXTI_BASE+0x0C)
#define EXTI_SWIER                    *(unsigned int*)(EXTI_BASE+0x10)
#define EXTI_PR                        *(unsigned int*)(EXTI_BASE+0x14)

//main.c
#include "GPIO.h"
#include "stm32f10x.h"

void SystemInit(void)
{
    
}

unsigned char a =2;

typedef unsigned int u32;

void delay(u32 i)
{
    while(i--);
}

int main()
{
        RCC_APB2ENR |= 1;    //启用AFIO,之前就是没启用网上找了半天,笑死了
        AFIO_EXTICR2 |= 0x04;    //选择将GPIOE4脚选为EXTI的外部中断输入源。
        EXTI_IMR = 1<<4;    //开放4脚上的中断请求
        EXTI_FTSR = 1<<4;
    //设置4脚为下降沿触发(因为原理图上按钮另一端是接地)
        //EXTI_RTSR = 1<<4;    //设置4脚为上升沿触发中断可以和下降沿触发一起配置,这样子就是按下去一个变化抬起来一个变化。
    
        RCC_APB2ENR |= (1<<3);    //初始化GPIOB的时钟
        RCC_APB2ENR |= (1<<6);    //初始化GPIOE的时钟
    
        GPIOB_CRL &= ~(0xf<<4*5);    //清空PB5的端口配置
        GPIOB_CRL |= (1<<4*5);    //设置PB5为通用推挽输出模式,输出速率为10MHZ
        GPIOB_ODR |= (1<<5);    //因为LED是共阳,所以要将PB5设置为低电平
        GPIOE_CRL &= ~(0xf<<4*4);    //清空PE4的端口配置
        GPIOE_CRL |= 0x1<<(4*4+3);    //设置PE4为上拉输入模式
        GPIOE_ODR |= (1<<4);    //因为是上拉输入模式,所以要将PE4设置为高电平(这个一定要配哦(应该吧),不然的话好像不能触发中断,因为一直是下降沿)
        delay(1000);
    while(1)
    {
            if(EXTI_PR & 1<<4)    //判断是否触发中断
            {
                GPIOB_ODR = ~(GPIOB_ODR&1<<5);    //触发了中断就将LED置反
                EXTI_PR |= 1<<4;    //将中断位重置
            }
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值