2017-03-10 10 views
0

STM32F469 디스커버리 보드를 사용 중이며 작동 할 외부 순간 누름 버튼을 얻으려고합니다.STM32F4 - 버튼 GPIO 입력이 작동하지 않습니다.

현재 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 
); 

내을 main.c 파일에서 다음

#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); 
    } 
} 

나는 다음과 같은 한 : 그리고 inout.c에서 나는 버튼 GPIO 핀의 설정에 다음과 같은 코드가

/* 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으로 인식됩니다.

그런 다음 버튼을 계속 누르고 있으면 결국은 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을 먼저 호출해야하며 플래그를 지워야합니다. 그래서이 :

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

답변을 수락 한 것으로 표시 할 수 있습니다. –