STM32學(xué)習(xí)筆記之外部中斷實(shí)驗(yàn)
實(shí)驗(yàn)?zāi)康模?/p>
當(dāng)按鍵按下時(shí),讓PF10引腳的LED燈亮,
當(dāng)按鍵再次按下時(shí),讓PF10引腳的LED燈滅;
無(wú)論按下與否,PF9引腳的LED燈循環(huán)閃爍;
實(shí)驗(yàn)步驟:
實(shí)驗(yàn)程序:
/***********************************led.c*********************************/
#include"stm32f4xx.h"http://在SYSTEM目錄下可以找到
#include"sys.h"
voidLED_Init(void){
RCC->AHB1ENR=1<<5;//使能GPIO端口的F時(shí)鐘
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
voidLED_Init(void);
#endif
[cpp]view plaincopy
/********************************************key.c***************************************/
#include"sys.h"
voidKey_Init(void){
RCC->AHB1ENR|=1<<4;//使能PORTE時(shí)鐘
//voidGPIO_Set(GPIO_TypeDef*GPIOx,u32BITx,u32MODE,u32OTYPE,u32OSPEED,u32PUPD);//GPIO設(shè)置函數(shù)
GPIO_Set(GPIOE,PIN3,GPIO_MODE_IN,0,0,GPIO_PUPD_PU);//PE3設(shè)置上拉輸入,這樣的話,
//當(dāng)按鍵沒(méi)有按下時(shí),默認(rèn)電平為高;
}
/********************************************key.h***************************************/
#ifndef_KEY_H
#define_KEY_H
voidKey_Init(void);
#endif
/************************************exti.c********************************/
#include"sys.h"
#include"delay.h"
#include"stm32f4xx.h"
/*
本示例的作用就是,
當(dāng)按鍵按下時(shí),蜂鳴器發(fā)出聲音,
當(dāng)按鍵再次按下時(shí),蜂鳴器靜音;
*/
/*
中斷初始化函數(shù):
主要是關(guān)于寄存器的相關(guān)配置
*/
voidEXTI3_Init(void){
//方法一:
RCC->APB2ENR|=1<<14;//開啟SYSCFG時(shí)鐘
SYSCFG->EXTICR[0]|=0x4<<12;//設(shè)置IO口與中斷線的映射關(guān)系;
EXTI->IMR|=1<<3;//開啟對(duì)應(yīng)中斷線上的中斷
EXTI->FTSR|=1<<3;//設(shè)置中斷觸發(fā)條件
//SCB和NVIC,可參考STM32F3與STM32F4系列CortexM4內(nèi)核編程手冊(cè).pdf
SCB->AIRCR|=0x5<<8;//設(shè)置分組
NVIC->IP[9]|=0;//設(shè)置優(yōu)先級(jí),具體可分析MY_NVIC_Init()函數(shù);
NVIC->ISER[0]|=1<<9;//使能中斷;
//方法二:
/************************************
使用SYSTEM目錄下提供的API來(lái)實(shí)現(xiàn),
具體可參考正點(diǎn)原子示例
************************************/
}
voidEXTI3_IRQHandler(void){
/*
此按鍵,在按鍵按下時(shí),處理不是很到位,
有待進(jìn)一步改進(jìn),主要是在連按那一個(gè)環(huán)節(jié)。
*/
delay_ms(20);//消抖
if(PEin(3)==0){
PFout(10)=!PFout(10);
}
/*
在中斷里邊最后記得清中斷:
*/
EXTI->PR|=1<<3;
}
/*************************************exti.h*******************************/
#ifndef_EXTI_H
#define_EXTI_H
voidEXTI3_Init(void);
#endif
/*************************************test.c*******************************/
#include"sys.h"
#include"delay.h"
#include"key.h"
#include"beep.h"
#include"exti.h"
#include"led.h"
//inti=0;
intmain(void){
Stm32_Clock_Init(336,8,2,7);//設(shè)置時(shí)鐘,168Mhz
delay_init(168);//初始化延時(shí)函數(shù)
Beep_Init();
Key_Init();
EXTI3_Init();
LED_Init();
while(1){
PFout(9)=0;
delay_ms(500);
PFout(9)=1;
delay_ms(500);
}
}
實(shí)驗(yàn)分析:
我們主要分析一下exti.c中的寄存器設(shè)置的這幾個(gè)步驟:
1. RCC->APB2ENR |= 1 << 14;
這一步的作用就是使能SYSCFG時(shí)鐘,
在使用外部中斷的時(shí)候一定要先使能SYSCFG時(shí)鐘;
2. SYSCFG->EXTICR[0] |= 0x4 << 12;
這一步的作用就是設(shè)置IO口與中斷線的映射關(guān)系;
那么問(wèn)題來(lái)了,我如何知道的我的IO口與哪根中斷線是關(guān)聯(lián)起來(lái)的呢?
而我們是通過(guò)KEY1按鍵,對(duì)應(yīng)的IO口就是PE3,所以由上圖的映射關(guān)系,我們知道,我們應(yīng)該選擇中斷線3與之對(duì)應(yīng);
在官方提供的頭文件stm32f4xx.h中,我們可以看到:
typedefstruct
{
__IOuint32_tMEMRMP;/*! __IOuint32_tPMC;/*! __IOuint32_tEXTICR[4];/*! uint32_tRESERVED[2];/*! [cpp]view plaincopy __IOuint32_tCMPCR;/*! SYSCFG_TypeDef; 結(jié)合上述三幅圖,我們可以得知: 由于PE3對(duì)應(yīng)的中斷線為EXTI3,所以,我們我們這里僅需配置EXTI3,而EXTI3是在SYSCFG_EXTICR1中的; 所以我們僅需配置SYSCFG_EXTICR1寄存器的12位-15位為01