2017-03-10 91 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

請注意,您可以將您的答案標記爲已接受。 –