键盘手没手 发表于 2022-3-29 15:22

STM32的外部中断

实验目的:

当按键按下时,让PF10引脚的LED灯亮,
当按键再次按下时,让PF10引脚的LED灯灭;
无论按下与否,PF9引脚的LED灯循环闪烁;

键盘手没手 发表于 2022-3-29 15:23

实验步骤:

键盘手没手 发表于 2022-3-29 15:23

实验程序:
/***********************************led.c*********************************/
#include 'stm32f4xx.h'//在SYSTEM目录下可以找到
#include 'sys.h'
void LED_Init(void){
        RCC->AHB1ENR = 1<<5;//使能GPIO端口的F时钟
        GPIO_Set(GPIOF,PIN9|PIN10,GPIO_MODE_OUT,GPIO_OTYPE_PP,GPIO_SPEED_25M,GPIO_PUPD_PU);
        PFout(9) = 1;
        PFout(10) = 1;
}

/***********************************led.h*********************************/
#ifndef _LED_H
#define _LED_H
void LED_Init(void);
#endif

/********************************************key.c***************************************/
#include 'sys.h'
void Key_Init(void){
        RCC->AHB1ENR|=1<<4;   //使能PORTE时钟
        //void GPIO_Set(GPIO_TypeDef* GPIOx,u32 BITx,u32 MODE,u32 OTYPE,u32 OSPEED,u32 PUPD);//GPIO设置函数
        GPIO_Set(GPIOE,PIN3,GPIO_MODE_IN,0,0,GPIO_PUPD_PU);        //PE3设置上拉输入,这样的话,
                                                                //当按键没有按下时,默认电平为高;
}


/********************************************key.h***************************************/
#ifndef _KEY_H
#define _KEY_H
void Key_Init(void);
#endif


/************************************exti.c********************************/
#include 'sys.h'
#include 'delay.h'
#include 'stm32f4xx.h'
/*

键盘手没手 发表于 2022-3-29 15:25

本示例的作用就是,
当按键按下时,蜂鸣器发出声音,
当按键再次按下时,蜂鸣器静音;
*/
/*
中断初始化函数:
主要是关于寄存器的相关配置
*/
void EXTI3_Init(void){
        //方法一:
        RCC->APB2ENR |= 1 << 14;//开启SYSCFG时钟
        SYSCFG->EXTICR |= 0x4 << 12;//设置IO口与中断线的映射关系;
        EXTI->IMR |= 1 << 3;//开启对应中断线上的中断
        EXTI->FTSR |= 1 << 3;//设置中断触发条件
        //SCB和NVIC,可参考STM32F3与STM32F4系列Cortex M4内核编程手册.pdf
        SCB->AIRCR |= 0x5 << 8; //设置分组
        NVIC->IP |= 0; //设置优先级,具体可分析MY_NVIC_Init()函数;
        NVIC->ISER |= 1 << 9;//使能中断;
        //方法二:
/************************************
        使用SYSTEM目录下提供的API来实现,
        具体可参考正点原子示例
************************************/
}
void EXTI3_IRQHandler(void){
        /*
        此按键,在按键按下时,处理不是很到位,
        有待进一步改进,主要是在连按那一个环节。
        */
        delay_ms(20);//消抖
        if(PEin(3) == 0){
                PFout(10) = !PFout(10);
        }
        /*
        在中断里边最后记得清中断:
        */
        EXTI->PR |= 1 << 3;
}

键盘手没手 发表于 2022-3-29 15:26

/*************************************exti.h*******************************/
#ifndef _EXTI_H
#define _EXTI_H
void EXTI3_Init(void);
#endif

键盘手没手 发表于 2022-3-29 15:27

/*************************************test.c*******************************/
#include 'sys.h'
#include 'delay.h'
#include 'key.h'
#include 'beep.h'
#include 'exti.h'
#include 'led.h'
//int i = 0;
int main(void){
        Stm32_Clock_Init(336,8,2,7);//设置时钟,168Mhz
        delay_init(168);                //初始化延时函数
        Beep_Init();
        Key_Init();
        EXTI3_Init();
        LED_Init();
        while(1){
                PFout(9) = 0;
                delay_ms(500);
                PFout(9) = 1;
                delay_ms(500);
        }
}

键盘手没手 发表于 2022-3-29 15:27

实验分析:

我们主要分析一下exti.c中的寄存器设置的这几个步骤:

1. RCC->APB2ENR |= 1 << 14;

这一步的作用就是使能SYSCFG时钟,

在使用外部中断的时候一定要先使能SYSCFG时钟;

键盘手没手 发表于 2022-3-29 15:28

2. SYSCFG->EXTICR |= 0x4 << 12;

这一步的作用就是设置IO口与中断线的映射关系;

那么问题来了,我如何知道的我的IO口与哪根中断线是关联起来的呢?

键盘手没手 发表于 2022-3-29 15:29

键盘手没手 发表于 2022-3-29 15:30

而我们是通过KEY1按键,对应的IO口就是PE3,所以由上图的映射关系,我们知道,我们应该选择中断线3与之对应;

键盘手没手 发表于 2022-3-29 16:35

在官方提供的头文件stm32f4xx.h中,我们可以看到:

typedef struct
{
__IO uint32_t MEMRMP;       /*!< SYSCFG memory remap register,                      Address offset: 0x00      */
__IO uint32_t PMC;          /*!< SYSCFG peripheral mode configuration register,   Address offset: 0x04      */
__IO uint32_t EXTICR;    /*!< SYSCFG external interrupt configuration registers, Address offset: 0x08-0x14 */
uint32_t      RESERVED;/*!< Reserved, 0x18-0x1C                                                          */
__IO uint32_t CMPCR;      /*!< SYSCFG Compensation cell control register,         Address offset: 0x20      */
} SYSCFG_TypeDef;

键盘手没手 发表于 2022-3-29 16:36

键盘手没手 发表于 2022-3-29 16:38

结合上述三幅图,我们可以得知:

由于PE3对应的中断线为EXTI3,所以,我们我们这里仅需配置EXTI3,而EXTI3是在SYSCFG_EXTICR1中的;

所以我们仅需配置SYSCFG_EXTICR1寄存器的12位-15位为0100,而SYSCFG_EXTICR1寄存器在配置文件中,

对应的是SYSCFG->EXTICR,所以我们就写成了SYSCFG->EXTICR |= 0x4 << 12;

键盘手没手 发表于 2022-3-29 16:40

3. EXTI->IMR |= 1 << 3;

这条语句的作用就是:开启对应中断线上的中断

由于我们操作的中断线是EXTI3,而IMR寄存器各位解释如下:

键盘手没手 发表于 2022-3-29 16:41

所以对应的,我们操作EXTI_IMR寄存器的第3位MR3即可;

所以这条语句就写成了:EXTI->IMR |= 1 << 3

键盘手没手 发表于 2022-3-29 16:42

4. EXTI->FTSR |= 1 << 3;

这条语句的作用就是设置中断触发条件;

在我的开发板中,当按键按下时,其端口就会变成低电平,在没有按下时,其是为高电平的;

因为我们key.c中,将按键的引脚设置成了上拉;所以在这里,我得将其设置成下降沿触发;

键盘手没手 发表于 2022-3-29 16:42

键盘手没手 发表于 2022-3-29 16:43

又由于我们这条中断线是中断线3,所以这条语句就写成了:EXTI->FTSR |= 1 << 3

键盘手没手 发表于 2022-3-29 16:44

5. SCB->AIRCR |= 0x5 << 8;

这条语句的作用就是:设置分组;

键盘手没手 发表于 2022-3-29 16:45

页: [1] 2
查看完整版本: STM32的外部中断