两次处理(通过上升/下降沿)按钮中断

时间:2015-09-28 17:21:30

标签: interrupt keil stm32f4discovery debouncing

我已经编写了一些代码,每次点击按钮都必须一个接一个地打开LED(在一个圆形中),但有时只需点击一下按钮就可以点亮下一个LED但是从四个LED随机点亮一个。这就像一个或多个LED跳过它。我认为这个问题是由于时钟速率的错误设置或上升/下降EXTI triger的错误设置引起的。 董事会: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();
    }
}

1 个答案:

答案 0 :(得分:5)

这可能是由于去抖(或缺乏)。

有关如何解决此问题的简短入门,请参阅http://www.labbookpages.co.uk/electronics/debounce.html

另请参阅http://www.emcu.it/STM32/STM32Discovery-Debounce/STM32Discovery-InputWithDebounce_Output_UART_SPI_SysTick.html了解有关STM32Discovery的具体内容。

这一切都是通过谷歌找到的。