2015-09-28 121 views
4

我已經寫了一些代碼,每次點擊按鈕都必須打開一個LED燈(一輪),但有時只需點擊一下按鈕指示燈不是下一個,而是四個LED中的一個。這就像一個或多個LED跳過輪到它。我認爲這個問題是由於時鐘頻率設置錯誤或者瑞星/下降EXTI trigers錯誤設置造成的。 局:STM32DISCOVERY按鈕處理兩次(按上升/下降沿)按鈕中斷

periph.h

#ifndef PERIPH_H 
#define PERIPH_H 

#include "stm32f4xx_gpio.h" 
#include "stm32f4xx_rcc.h" 
#include "misc.h" 
#include "stm32f4xx_exti.h" 
#include "stm32f4xx_syscfg.h" 

void Initialize_GPIO_LEDS(void); 
void Initialize_GPIO_Button(void); 
void Initialize_EXTI0_PA(void); 
void Initialize_NVIC(void); 

typedef enum 
{ 
    GPIO_LED_Green   = GPIO_Pin_12, 
    GPIO_LED_Yellow  = GPIO_Pin_13, 
    GPIO_LED_Red   = GPIO_Pin_14, 
    GPIO_LED_Blue   = GPIO_Pin_15 
}GPIO_LED_TypeDef; 

void GPIO_LED_On(GPIO_LED_TypeDef GPIO_LED_x); 
void GPIO_LED_Off(GPIO_LED_TypeDef GPIO_LED_x); 
void GPIO_LED_All_On(void); 
void GPIO_LED_All_Off(void); 

#endif /* PERIPH_H */ 

PERIPH.C

#include "periph.h" 

GPIO_InitTypeDef GPIO_LEDS; 
GPIO_InitTypeDef GPIO_Button; 
EXTI_InitTypeDef EXTI0_PA; 
NVIC_InitTypeDef NVIC_Struct; 

void Initialize_GPIO_LEDS(void) 
{ 
    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD, ENABLE); 

    GPIO_LEDS.GPIO_Pin = GPIO_Pin_15 | GPIO_Pin_14 | GPIO_Pin_13 | GPIO_Pin_12; 
    GPIO_LEDS.GPIO_Mode = GPIO_Mode_OUT; 
    GPIO_LEDS.GPIO_Speed = GPIO_Speed_2MHz; 
    GPIO_LEDS.GPIO_OType = GPIO_OType_PP; 
    GPIO_LEDS.GPIO_PuPd = GPIO_PuPd_NOPULL; 

    GPIO_Init(GPIOD, &GPIO_LEDS); 
} 

void Initialize_GPIO_Button(void) 
{ 
    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE); 

    GPIO_Button.GPIO_Pin = GPIO_Pin_0; 
    GPIO_Button.GPIO_Mode = GPIO_Mode_IN; 
    GPIO_Button.GPIO_Speed = GPIO_Speed_2MHz; 
    GPIO_Button.GPIO_OType = GPIO_OType_PP; 
    GPIO_Button.GPIO_PuPd = GPIO_PuPd_DOWN; 

    GPIO_Init(GPIOA, &GPIO_Button); 
} 

void Initialize_EXTI0_PA(void) 
{ 
    EXTI0_PA.EXTI_Line = EXTI_Line0; 
    EXTI0_PA.EXTI_Mode = EXTI_Mode_Interrupt; 
    EXTI0_PA.EXTI_Trigger = EXTI_Trigger_Rising; 
    EXTI0_PA.EXTI_LineCmd = ENABLE; 

    EXTI_Init(&EXTI0_PA); 
} 

void Initialize_NVIC(void) 
{ 
    NVIC_Struct.NVIC_IRQChannel = EXTI0_IRQn; 
    NVIC_Struct.NVIC_IRQChannelCmd = ENABLE; 

    NVIC_Init(&NVIC_Struct); 
} 

void GPIO_LED_On(GPIO_LED_TypeDef GPIO_LED_x) 
{ 
    GPIO_SetBits(GPIOD, GPIO_LED_x); 
} 

void GPIO_LED_Off(GPIO_LED_TypeDef GPIO_LED_x) 
{ 
    GPIO_ResetBits(GPIOD, GPIO_LED_x); 
} 

void GPIO_LED_All_On(void) 
{ 
    GPIO_SetBits(GPIOD, GPIO_LED_Green | GPIO_LED_Yellow | GPIO_LED_Red | GPIO_LED_Blue); 
} 

void GPIO_LED_All_Off(void) 
{ 
    GPIO_ResetBits(GPIOD, GPIO_LED_Green | GPIO_LED_Yellow | GPIO_LED_Red | GPIO_LED_Blue); 
} 

的main.c

#include "cmsis_os.h" 
#include "periph.h" 

uint8_t led_num = 0; 

void EXTI0_IRQHandler(void) 
{ 
    if (EXTI_GetITStatus(EXTI_Line0) != RESET) 
    { 
     if (GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_0)) 
     { 
      led_num++; 
      if (led_num == 4) led_num = 0; 
     } 
     EXTI_ClearITPendingBit(EXTI_Line0); 
    } 
} 

int main (void) 
{ 
    Initialize_GPIO_LEDS(); 
    Initialize_GPIO_Button(); 
    SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOA, EXTI_PinSource0); 
    Initialize_EXTI0_PA(); 
    Initialize_NVIC(); 

    while(1) 
    { 
     switch(led_num) 
     { 
      case 0 : GPIO_LED_On(GPIO_LED_Green); break; 
      case 1 : GPIO_LED_On(GPIO_LED_Yellow); break; 
      case 2 : GPIO_LED_On(GPIO_LED_Red); break; 
      case 3 : GPIO_LED_On(GPIO_LED_Blue);  break; 
     } 

     GPIO_LED_All_Off(); 
    } 
} 
+0

不要在Exti中斷處理程序中用'GPIO_ReadInputDataBit'重新採樣按鈕。事實上,中斷處理程序的啓動意味着GPIO線上有一個上升沿。所有你正在做的事情是讓它可以忽略按鈕,如果它足夠快地釋放。 –

回答