STM32的外部中断
实验目的:当按键按下时,让PF10引脚的LED灯亮,
当按键再次按下时,让PF10引脚的LED灯灭;
无论按下与否,PF9引脚的LED灯循环闪烁;
实验步骤:
实验程序:
/***********************************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'
/* 本示例的作用就是,
当按键按下时,蜂鸣器发出声音,
当按键再次按下时,蜂鸣器静音;
*/
/*
中断初始化函数:
主要是关于寄存器的相关配置
*/
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;
}
/*************************************exti.h*******************************/
#ifndef _EXTI_H
#define _EXTI_H
void EXTI3_Init(void);
#endif /*************************************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);
}
}
实验分析:
我们主要分析一下exti.c中的寄存器设置的这几个步骤:
1. RCC->APB2ENR |= 1 << 14;
这一步的作用就是使能SYSCFG时钟,
在使用外部中断的时候一定要先使能SYSCFG时钟; 2. SYSCFG->EXTICR |= 0x4 << 12;
这一步的作用就是设置IO口与中断线的映射关系;
那么问题来了,我如何知道的我的IO口与哪根中断线是关联起来的呢? 而我们是通过KEY1按键,对应的IO口就是PE3,所以由上图的映射关系,我们知道,我们应该选择中断线3与之对应; 在官方提供的头文件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;
结合上述三幅图,我们可以得知:
由于PE3对应的中断线为EXTI3,所以,我们我们这里仅需配置EXTI3,而EXTI3是在SYSCFG_EXTICR1中的;
所以我们仅需配置SYSCFG_EXTICR1寄存器的12位-15位为0100,而SYSCFG_EXTICR1寄存器在配置文件中,
对应的是SYSCFG->EXTICR,所以我们就写成了SYSCFG->EXTICR |= 0x4 << 12; 3. EXTI->IMR |= 1 << 3;
这条语句的作用就是:开启对应中断线上的中断
由于我们操作的中断线是EXTI3,而IMR寄存器各位解释如下:
所以对应的,我们操作EXTI_IMR寄存器的第3位MR3即可;
所以这条语句就写成了:EXTI->IMR |= 1 << 3 4. EXTI->FTSR |= 1 << 3;
这条语句的作用就是设置中断触发条件;
在我的开发板中,当按键按下时,其端口就会变成低电平,在没有按下时,其是为高电平的;
因为我们key.c中,将按键的引脚设置成了上拉;所以在这里,我得将其设置成下降沿触发;
又由于我们这条中断线是中断线3,所以这条语句就写成了:EXTI->FTSR |= 1 << 3 5. SCB->AIRCR |= 0x5 << 8;
这条语句的作用就是:设置分组;
页:
[1]
2