2015-09-28 1 views
4

Я написал код, который должен включать светодиоды один за другим (в раунде) при каждом нажатии кнопки, но иногда одним нажатием кнопки загорается а не следующий, но один случайный из четырех светодиодов. Это что-то вроде одного или нескольких светодиодов, пропускающих свою очередь. Я думаю, проблема связана с неправильной настройкой тактовой частоты или неправильной настройкой триггеров Rising/Falling EXTI. Совет: 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

Не перепробовать свою кнопку с помощью 'GPIO_ReadInputDataBit' в обработчике прерываний Exti. Сам факт, что обработчик прерывания запускал, означает, что на линии GPIO был нарастающий фронт. Все, что вы делаете, позволяет игнорировать кнопку, если она была выпущена достаточно быстро. –

ответ

5

Возможно, это связано с дебютом (или его отсутствием).

См. http://www.labbookpages.co.uk/electronics/debounce.html для краткого руководства по решению этого вопроса.

См. Также http://www.emcu.it/STM32/STM32Discovery-Debounce/STM32Discovery-InputWithDebounce_Output_UART_SPI_SysTick.html для чего-то конкретно о STM32Discovery.

Все это было найдено через google.

Смежные вопросы