STM32F10X系列GPIO外部中斷
先從最簡(jiǎn)單的問(wèn)題開(kāi)始,用STM32外部中斷的方法實(shí)現(xiàn)PB.0按鍵控制PA.0LED燈:
先總的說(shuō)下實(shí)現(xiàn)中斷的步驟:
1,配置NVIC寄存器(函數(shù)),設(shè)置中斷為第幾組,占先優(yōu)先級(jí)和次優(yōu)先級(jí);
函數(shù)方法:
void NVIC_Configuration()
{
NVIC_InitTypeDef NVIC_InitStruct;
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);
NVIC_InitStruct.NVIC_IRQChannel=EXTI0_IRQn;
NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority=0;
NVIC_InitStruct.NVIC_IRQChannelSubPriority=1;
NVIC_InitStruct.NVIC_IRQChannelCmd=ENABLE;
NVIC_Init(&NVIC_InitStruct);
}
以上為配置優(yōu)先級(jí)的一般步驟:設(shè)置優(yōu)先級(jí)分組,設(shè)置中斷通道,分別設(shè)置先占優(yōu)先級(jí),次占優(yōu)先級(jí),使能等;
2,配置EXTI寄存器及(函數(shù)),設(shè)置中斷線(xiàn),中斷方式,等;
voidEXTI_Configuration()
{
EXTI_InitTypeDefEXTI_InitStructure;
EXTI_ClearITPendingBit(EXTI_Line0);
GPIO_EXTILineConfig(GPIO_PortSourceGPIOB,GPIO_PinSource0);
EXTI_InitStructure.EXTI_Line=EXTI_Line0;
EXTI_InitStructure.EXTI_Mode=EXTI_Mode_Interrupt;
EXTI_InitStructure.EXTI_Trigger=EXTI_Trigger_Falling;
EXTI_InitStructure.EXTI_LineCmd=ENABLE;
EXTI_Init(&EXTI_InitStructure);
}
和配置NVIC一樣,這也是EXTI配置的一般步驟:清除相應(yīng)中斷線(xiàn)標(biāo)志位(這個(gè)很重要,剛開(kāi)始一直沒(méi)找到這個(gè)問(wèn)題),聯(lián)結(jié)端口與中斷線(xiàn)(也可以在GPIO初始化時(shí)配置),選擇中斷線(xiàn),設(shè)置中斷模式,中斷方式,使能等;
3,寫(xiě)中斷服務(wù)函數(shù)
中斷服務(wù)程序一般寫(xiě)在STM32F10X_it.c文件里:
voidEXTI0_IRQHandler(void)
{
if(EXTI_GetITStatus(EXTI_Line0)==SET)
{
EXTI_ClearITPendingBit(EXTI_Line0);
if(GPIO_ReadOutputDataBit(GPIOA,GPIO_Pin_0)==Bit_RESET)
{
GPIO_SetBits(GPIOA,GPIO_Pin_0);
}
else
{
GPIO_ResetBits(GPIOA,GPIO_Pin_0);
}
}
}
其中最重要的一點(diǎn):需要注意進(jìn)入服務(wù)程序后清除中斷標(biāo)志位;
說(shuō)幾點(diǎn)容易忽略的地方:
1.中斷服務(wù)程序一定要清除中斷標(biāo)志位;
2.聯(lián)結(jié)相應(yīng)端口與中斷線(xiàn);
3.按鍵端口設(shè)置成上拉輸入;
4.在配置EXTI時(shí)清除中斷標(biāo)志位;
按鍵部分的短路自己連的:
下面是直接操作寄存器的方法:
1.GPIO初始化:這里只要注意GPIOB.0設(shè)置成上拉輸入(不光要設(shè)置GPIOB->CRL=0X08,還要設(shè)置GPIOB->ODR=0X01,為了和下拉區(qū)分)
voidGPIO_Config()
{
GPIOA->CRL=0X03;
GPIOA->ODR=0X01;
GPIOB->CRL=0X08;
GPIOB->ODR=0X01;
}
2. NVIC 初始化:
直接上代碼:
voidNVIC_Configuration()
{
u32temp;
temp=SCB->AIRCR;
temp&=0x0000f8ff;
temp|=0x05fa0000;
temp|=0x0700;
SCB->AIRCR=temp;
NVIC->ISER[0]=1<<6;
NVIC->IP[1]=0;
}
3. EXTI初始化
和用函數(shù)方法差不多,設(shè)置幾個(gè)寄存器;有點(diǎn)不明白的是這里好像可以不用清除標(biāo)志位;
voidEXTI_Configuration()
{
AFIO->EXTICR[0]=0X0001;
EXTI->IMR=0X01;
EXTI->RTSR=0X01;
}
然后是中斷服務(wù)程序:
voidEXTI0_IRQHandler(void)
{
if(EXTI_GetITStatus(EXTI_Line0)==SET)
{
EXTI->PR=0X01;
if(GPIO_ReadOutputDataBit(GPIOA,GPIO_Pin_0)==Bit_RESET)
{
GPIO_SetBits(GPIOA,GPIO_Pin_0);
}
else
{
GPIO_ResetBits(GPIOA,GPIO_Pin_0);
}
}
}
下面是整個(gè)用函數(shù)代碼:
#include"stm32f10x.h"
voidGPIO_Config();
voidNVIC_Configuration();
voidEXTI_Configuration();
voidSysclkConfiguration();
intmain()
{
SysclkConfiguration();
GPIO_Config();
EXTI_Configuration();
NVIC_Configuration();
while(1);
return0;
}
voidSysclkConfiguration()
{
RCC_DeInit();
RCC_HSEConfig(RCC_HSE_ON);
if(RCC_WaitForHSEStartUp()==SUCCESS)
{
RCC_PLLConfig(RCC_PLLSource_HSE_Div1,RCC_PLLMul_9);
RCC_PLLCmd(ENABLE);
while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY)==RESET);
RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);
while(RCC_GetSYSCLKSource()!=0X08);
RCC_HCLKConfig(RCC_SYSCLK_Div1);
RCC_PCLK1Config(RCC_HCLK_Div2);
RCC_PCLK2Config(RCC_HCLK_Div1);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_GPIOB|RCC_APB2Periph_AFIO,ENABLE);
}
}
voidGPIO_Config()
{
GPIO_InitTypeDefGPIO_InitStructure;
GPIO_InitStructure.GPIO_Pin=GPIO_Pin_0;
GPIO_InitStructure.GPIO_Speed=GPIO_Speed_10MHz;
GPIO