Почему stm32 сразу же выходит из режима остановки, как только он входит? - PullRequest
0 голосов
/ 13 февраля 2019

В настоящее время я работаю на устройстве, которое требует нажатия кнопки, чтобы перевести устройство в режим STOP с низким энергопотреблением, а затем другое нажатие кнопки, чтобы вызвать прерывание, чтобы снова разбудить устройство.В настоящее время работает первое прерывание нажатия кнопки, и устройство переводится в режим STOP.Однако вместо ожидания нажатия другой кнопки устройство мгновенно выходит из режима STOP.Я попытался выполнить поиск, но не нашел никаких других указателей на вызываемое другое прерывание, которое могло бы вызвать срабатывание и пробуждение WFI устройства.Ниже мой код, который я использую:

/* Includes ------------------------------------------------------------------*/
#include "main.h"
#include "stm32f4xx_hal.h"

#define BUTTON_WAKE_PIN             GPIO_PIN_0
#define BUTTON_WAKE_PORT            GPIOA
#define BUTTON_SLEEP_PIN            GPIO_PIN_9
#define BUTTON_SLEEP_PORT           GPIOE
#define LED_GR_PIN                  GPIO_PIN_0
#define LED_GR_PORT                 GPIOD
#define LED_RG_PIN                  GPIO_PIN_1
#define LED_RG_PORT                 GPIOD

/* Private variables ---------------------------------------------------------*/
static uint8_t buttonPress = 0;

/* Private function prototypes -----------------------------------------------*/
void        SystemClock_Config ( void );
static void Gpio_Sleep_Mode    ( void );

/**
* @brief This function handles (wakeup) interrupts.
*/
void EXTI0_IRQHandler ( void )
{
  /* Clear pending */
  HAL_GPIO_EXTI_IRQHandler(BUTTON_WAKE_PIN); /* IRQ_CH0 */
}

/**
* @brief This function handles (sleep) interrupts.
*/
void EXTI9_5_IRQHandler(void)
{
  if ( EXTI->PR & EXTI_PR_PR9 )         /* IRQ_CH9 */
  {
    HAL_GPIO_EXTI_IRQHandler(BUTTON_SLEEP_PIN);
    buttonPress = 1;
  }
}

/* Turn on LED */
void LED_Off ( void )
{
  HAL_GPIO_WritePin( LED_GR_PORT, LED_GR_PIN, GPIO_PIN_RESET );
  HAL_GPIO_WritePin( LED_RG_PORT, LED_RG_PIN, GPIO_PIN_RESET );
}

/* Turn off LED */
void LED_On ( void )
{
  HAL_GPIO_WritePin( LED_GR_PORT, LED_GR_PIN, GPIO_PIN_SET );
  HAL_GPIO_WritePin( LED_RG_PORT, LED_RG_PIN, GPIO_PIN_RESET );
}

/* Initialize LED GPIOs */
void LED_Init ( void )
{
  GPIO_InitTypeDef GPIO_InitStruct;

  /* Start clock */
  __HAL_RCC_GPIOD_CLK_ENABLE();

  /* Default input settings */
  GPIO_InitStruct.Mode  = GPIO_MODE_OUTPUT_PP;
  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
  GPIO_InitStruct.Pull  = GPIO_NOPULL;

  GPIO_InitStruct.Pin   = LED_GR_PIN;
  HAL_GPIO_WritePin( LED_GR_PORT, LED_GR_PIN, GPIO_PIN_RESET );
  HAL_GPIO_Init(LED_GR_PORT, &GPIO_InitStruct);

  GPIO_InitStruct.Pin   = LED_RG_PIN;
  HAL_GPIO_WritePin( LED_RG_PORT, LED_RG_PIN, GPIO_PIN_RESET );
  HAL_GPIO_Init(LED_RG_PORT, &GPIO_InitStruct);

  LED_On();
  HAL_Delay(50);
  LED_Off();
  HAL_Delay(50);
  LED_On();
  HAL_Delay(50);
  LED_Off();
  HAL_Delay(50);
}

/* Initialize button used for wakeup */
void Wake_Button_Init ( void )
{
  GPIO_InitTypeDef GPIO_InitStruct;

  /* Start clock */
  __HAL_RCC_GPIOA_CLK_ENABLE();

  /* Default input settings */
  GPIO_InitStruct.Mode  = GPIO_MODE_IT_RISING;
  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
  GPIO_InitStruct.Pull  = GPIO_NOPULL;

  GPIO_InitStruct.Pin   = BUTTON_WAKE_PIN;
  HAL_GPIO_WritePin( BUTTON_WAKE_PORT, BUTTON_WAKE_PIN, GPIO_PIN_RESET );
  HAL_GPIO_Init(BUTTON_WAKE_PORT, &GPIO_InitStruct);  

  __HAL_GPIO_EXTI_CLEAR_IT ( BUTTON_WAKE_PIN );
  __HAL_GPIO_EXTI_CLEAR_IT ( BUTTON_SLEEP_PIN );
  HAL_NVIC_SetPriority     ( EXTI0_IRQn, 0, 0);
  HAL_NVIC_ClearPendingIRQ ( EXTI9_5_IRQn );
  HAL_NVIC_ClearPendingIRQ ( EXTI0_IRQn );
  HAL_NVIC_EnableIRQ       ( EXTI0_IRQn );
}

/* Initialize button used for sleep */
void Sleep_Button_Init ( void )
{
  GPIO_InitTypeDef GPIO_InitStruct;

  /* Start clock */
  __HAL_RCC_GPIOE_CLK_ENABLE();

  /* Default input settings */
  GPIO_InitStruct.Mode  = GPIO_MODE_IT_RISING;
  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
  GPIO_InitStruct.Pull  = GPIO_NOPULL;

  GPIO_InitStruct.Pin   = BUTTON_SLEEP_PIN;
  HAL_GPIO_WritePin( BUTTON_SLEEP_PORT, BUTTON_SLEEP_PIN, GPIO_PIN_RESET );
  HAL_GPIO_Init(BUTTON_SLEEP_PORT, &GPIO_InitStruct);

  __HAL_GPIO_EXTI_CLEAR_IT ( BUTTON_SLEEP_PIN );
  HAL_NVIC_SetPriority     ( EXTI9_5_IRQn, 0, 0);
  HAL_NVIC_ClearPendingIRQ ( EXTI9_5_IRQn );
  HAL_NVIC_EnableIRQ       ( EXTI9_5_IRQn );
}

void System_Init ( void )
{  
  /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
  HAL_Init();

  /* Configure the system clock */
  SystemClock_Config();

  buttonPress = 0;

  LED_Init();
  Sleep_Button_Init();
}

/* All GPIOs analog */
void Gpio_Sleep_Mode ( void )
{
  GPIO_InitTypeDef GPIO_InitStruct;

  /* GPIO Ports Clock Enable */
  __HAL_RCC_GPIOA_CLK_ENABLE();
  __HAL_RCC_GPIOB_CLK_ENABLE();
  __HAL_RCC_GPIOC_CLK_ENABLE();
  __HAL_RCC_GPIOD_CLK_ENABLE();
  __HAL_RCC_GPIOE_CLK_ENABLE();
  __HAL_RCC_GPIOH_CLK_ENABLE();

  /* Configure as analog */
  GPIO_InitStruct.Mode  = GPIO_MODE_ANALOG;
  GPIO_InitStruct.Speed = GPIO_SPEED_HIGH;
  GPIO_InitStruct.Pull  = GPIO_NOPULL;
  GPIO_InitStruct.Pin   = GPIO_PIN_All;
  HAL_GPIO_Init( GPIOA, &GPIO_InitStruct );
  HAL_GPIO_Init( GPIOB, &GPIO_InitStruct );
  HAL_GPIO_Init( GPIOC, &GPIO_InitStruct );
  HAL_GPIO_Init( GPIOD, &GPIO_InitStruct );
  HAL_GPIO_Init( GPIOE, &GPIO_InitStruct );
  HAL_GPIO_Init( GPIOH, &GPIO_InitStruct );

  /* Disable GPIOs clock */
  __HAL_RCC_GPIOA_CLK_DISABLE();
  __HAL_RCC_GPIOB_CLK_DISABLE();
  __HAL_RCC_GPIOC_CLK_DISABLE();
  __HAL_RCC_GPIOD_CLK_DISABLE();
  __HAL_RCC_GPIOE_CLK_DISABLE();
  __HAL_RCC_GPIOH_CLK_DISABLE();

  /* Disble all interrupt sources */
  EXTI->IMR = 0;
}


/**
  * @brief  Puts the system into sleep mode
  */
void System_Sleep ( void )
{
  Gpio_Sleep_Mode();

  /* Enable button interrupt */
  Wake_Button_Init();

  /* FLASH Deep Power Down Mode enabled */
  HAL_PWREx_EnableFlashPowerDown();

  /* Enter Stop Mode */
  HAL_PWR_EnterSTOPMode(PWR_LOWPOWERREGULATOR_ON, PWR_STOPENTRY_WFI);

  __HAL_PWR_CLEAR_FLAG(PWR_FLAG_WU); 

  System_Init();
}


/**
  * @brief  The application entry point.
  */
int main(void)
{
  System_Init();
  // Allow debugger to work in stop mode
  DBGMCU->CR = DBGMCU_CR_DBG_STOP;

  /* Infinite loop */
  while (1)
  {
    LED_On();
    HAL_Delay(500);
    LED_Off();
    HAL_Delay(500);

    if ( buttonPress == 1 )
    {
      HAL_Delay ( 500 );
      buttonPress = 0;
      System_Sleep();
    }
  }

}


/**
  * @brief System Clock Configuration
  * @retval None
  */
void SystemClock_Config(void)
{
  RCC_OscInitTypeDef RCC_OscInitStruct;
  RCC_ClkInitTypeDef RCC_ClkInitStruct;

  /* Configure the main internal regulator output voltage */
  __HAL_RCC_PWR_CLK_ENABLE();
  __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1);

  /* Initializes the CPU, AHB and APB busses clocks */
  RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE|RCC_OSCILLATORTYPE_LSE;
  RCC_OscInitStruct.HSEState = RCC_HSE_ON;
  RCC_OscInitStruct.LSEState = RCC_LSE_ON;
  RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
  RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
  RCC_OscInitStruct.PLL.PLLM = 2;
  RCC_OscInitStruct.PLL.PLLN = 96;
  RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV6;
  RCC_OscInitStruct.PLL.PLLQ = 4;
  if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
  {
    _Error_Handler(__FILE__, __LINE__);
  }

  /* Initializes the CPU, AHB and APB busses clocks */
  RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
                              |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
  RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
  RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
  RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;
  RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;

  if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_1) != HAL_OK)
  {
    _Error_Handler(__FILE__, __LINE__);
  }

  /**Configure the Systick interrupt time */
  HAL_SYSTICK_Config(HAL_RCC_GetHCLKFreq()/1000);

  /**Configure the Systick */
  HAL_SYSTICK_CLKSourceConfig(SYSTICK_CLKSOURCE_HCLK);

  /* SysTick_IRQn interrupt configuration */
  HAL_NVIC_SetPriority(SysTick_IRQn, 0, 0);
}


/**
  * @brief  This function is executed in case of error occurrence.
  */
void _Error_Handler(char *file, int line)
{
  /* User can add his own implementation to report the HAL error return state */
  while(1);
}

1 Ответ

0 голосов
/ 14 февраля 2019

Вы включили прерывание SysTick.Может ли прерывание SysTick разбудить процессор?Знаете ли вы, останавливается ли источник часов SysTick или прерывание SysTick отключается при входе в режим остановки?

Попробуйте приостановить и возобновить прерывание SysTick, как показано ниже.

HAL_SuspendTick();
/* Enter Stop Mode */
HAL_PWR_EnterSTOPMode(PWR_LOWPOWERREGULATOR_ON, PWR_STOPENTRY_WFI);
HAL_ResumeTick();
...