2017-03-10 45 views
0

我使用的是STM32F469发现板,而我试图让外部瞬时按钮上班按钮GPIO输入不起作用。STM32F4 -

它当前连接到PG11,它被设定为使比当它压在销连接到由MCU供给+ 5V。我继续之前,我只是想指出,我用下面的代码在stmf4xx_it.c执行防反跳:

#define REFdebounce 200 

int In1 = 3; 
int In1_0 = 0; 
int In1_1 = 0; 
int StatoIn1 = 3; 

void SysTick_Handler(void) 
{ 
    In1 = HAL_GPIO_ReadPin(GPIOG, GPIO_PIN_11); 

    if (In1 == 0) 
    { 
    In1_0++; 
    In1_1 = 0; 
    if (In1_0 >= REFdebounce) 
    { 
     In1_0 = REFdebounce + 1; 
     StatoIn1 = 0; 
    } 
    } 
    else 
    { 
    In1_0 = 0; 
    In1_1++; 
    if (In1_1 >= REFdebounce) 
    { 
     In1_1 = REFdebounce + 1; 
     StatoIn1 = 1; 
    } 
    } 
} 

我有一个头文件inout.h下面的代码:

typedef void (* TSelectCallback) (int aSelectSignal); 

void ConfigSelectPin 
(
    TSelectCallback    aSelectCallback 
); 

然后在inout.c我有以下代码按钮GPIO引脚设置:

#define SELECT_SIGNAL_PIN     GPIO_PIN_11 
#define SELECT_SIGNAL_GPIO_PORT    GPIOG 
#define SELECT_SIGNAL_GPIO_CLK_ENABLE()  __HAL_RCC_GPIOG_CLK_ENABLE() 
#define SELECT_SIGNAL_GPIO_CLK_DISABLE() __HAL_RCC_GPIOG_CLK_DISABLE() 
#define SELECT_SIGNAL_EXTI_IRQn    EXTI15_10_IRQn 

void ConfigSelectPin(TSelectCallback aSelectCallback) 
{ 
    GPIO_InitTypeDef GPIO_InitStructure; 

    /* Enable GPIOC clock */ 
    SELECT_SIGNAL_GPIO_CLK_ENABLE(); 

    /* Configure washer signal pin as input floating */ 
    GPIO_InitStructure.Mode = GPIO_MODE_IT_RISING; 
    GPIO_InitStructure.Pull = GPIO_PULLDOWN; 
    GPIO_InitStructure.Pin = SELECT_SIGNAL_PIN; 
    HAL_GPIO_Init(SELECT_SIGNAL_GPIO_PORT, &GPIO_InitStructure); 

    /* Enable and set EXTI lines 0 Interrupt to the lowest priority */ 
    HAL_NVIC_SetPriority(SELECT_SIGNAL_EXTI_IRQn, 8, 0); 
    HAL_NVIC_EnableIRQ(SELECT_SIGNAL_EXTI_IRQn); 

    SelectCallback = aSelectCallback; 
} 

void EXTI15_10_IRQHandler(void) 
{ 
    if (__HAL_GPIO_EXTI_GET_IT(SELECT_SIGNAL_PIN) != RESET) 
    { 
    RedLedOn(); 
    __HAL_GPIO_EXTI_CLEAR_IT(SELECT_SIGNAL_PIN); 
    HAL_GPIO_EXTI_IRQHandler(SELECT_SIGNAL_PIN); 
    } 
} 

void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin) 
{ 
    if (GPIO_Pin == SELECT_SIGNAL_PIN) 
    { 
    YellowLedOn(); 
    GPIO_PinState pinState; 

    //pinState = HAL_GPIO_ReadPin(SELECT_SIGNAL_GPIO_PORT, GPIO_Pin); 
    pinState = 1; 

    if (SelectCallback) 
     SelectCallback (pinState); 
    } 
} 

然后在我的main.c文件,我有以下几点:

/* variable to detect that hardware button is pressed */ 
static int Select = 0; 
extern int StatoIn1; 

void SelectIsrCallback(int aSelectSignal) 
{ 
    if (StatoIn1 == 1) 
    { 
    OrangeLedOn(); 
    Select = 1; 
    } 
} 

然后我用下面的代码,如果按钮被按下来检测并执行我的要求的动作

if (Select) 
{ 
    BlueLedOn(); 
    Select = 0; 
} 

现在每次我按下按钮时,EXTI15_10_IRQHandler被称为用红色作为公认的LED转向上。

如果我继续按下按钮,很多很多很多次,HAL_GPIO_EXTI_Callback最终将所承认的,黄色LED灯打开调用。

如果我继续按下按钮的次数更多,那么最终会调用SelectIsrCallback,并且我的期望动作将被执行,如橙色和蓝色LED导通所确认的。

为什么做HAL_GPIO_EXTI_CallbackSelectIsrCallback不会被调用的第一个按钮按下?为什么SelectIsrCallback一旦调用HAL_GPIO_EXTI_Callback就不会被调用?

注:我刚搬了YellowLedOn()电话,if语句之前HAL_GPIO_EXTI_Callback,看它是否是if语句需要按下按钮的加载它被调用之前的这个功能。它没有什么区别,所以问题在于调用HAL_GPIO_EXTI_Callback函数。

回答

1

好了,所以尽管花费几天摸不着头脑,原来答案是很简单的。需要切换EXTI15_10_IRQHandler中调用的功能的顺序。即HAL_GPIO_EXTI_IRQHandler需要先调用b,然后标志需要清除。所以这个:

void EXTI15_10_IRQHandler(void) 
{ 
    if (__HAL_GPIO_EXTI_GET_IT(SELECT_SIGNAL_PIN) != RESET) 
    { 
    RedLedOn(); 
    **__HAL_GPIO_EXTI_CLEAR_IT(SELECT_SIGNAL_PIN); 
    HAL_GPIO_EXTI_IRQHandler(SELECT_SIGNAL_PIN);** 
    } 
} 

需要切换到这一点:

void EXTI15_10_IRQHandler(void) 
{ 
    if (__HAL_GPIO_EXTI_GET_IT(SELECT_SIGNAL_PIN) != RESET) 
    { 
    RedLedOn(); 
    HAL_GPIO_EXTI_IRQHandler(SELECT_SIGNAL_PIN); 
    __HAL_GPIO_EXTI_CLEAR_IT(SELECT_SIGNAL_PIN); 
    } 
} 

现在这似乎是显而易见的,因为你不能调用中断功能,否则它不会执行之前清除中断标志。不过,我确信我看到很多例子,它们是我最初的功能。

+0

请注意,您可以将您的答案标记为已接受。 –