【问题标题】:STM32F4 - Button GPIO input doesn't workSTM32F4 - 按钮 GPIO 输入不起作用
【发布时间】:2017-03-10 00:48:58
【问题描述】:

我正在使用 STM32F469 探索板,并且正在尝试让外部瞬时按钮工作。

它当前连接到 PG11,并且设置为比按下时将引脚连接到 MCU 提供的 +5V。在继续之前,我只想声明我在 stmf4xx_it.c 中使用以下代码来执行 debounce:

#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() 调用移到 HAL_GPIO_EXTI_Callback 中的 if 语句之前,以查看是否是 if 语句的这个函数在调用之前需要大量按钮按下。没有区别,所以问题出在HAL_GPIO_EXTI_Callback 函数的调用上。

【问题讨论】:

    标签: interrupt gpio stm32f4


    【解决方案1】:

    好的,尽管花了几天时间来解决这个问题,但事实证明答案很简单。 EXTI15_10_IRQHandler中调用的函数顺序需要切换。 IE。 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 );
      }
    }
    

    现在这似乎很明显,因为在调用中断函数之前不能清除中断标志,否则它不会执行。但是,我确信我看到了很多例子,它们是按照我最初拥有这些功能的顺序排列的。

    【讨论】:

      猜你喜欢
      • 2023-03-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多