STM32 Wakeup aus dem Stop-Modus mit GPIO EXTI-Ereignis

Ich verwende eine MCU der STM32L0-Serie. Ich habe meine MCU so konfiguriert, dass sie während der fallenden Flanke mit einer EXTI-Leitung (EXTI0 bei PORTA0) aus dem Stoppmodus aufwacht. Am Anfang ging es nicht in den Stop-Modus, nachdem ich _WFE() aufgerufen hatte. Nachdem ich mehrere Dinge ausprobiert hatte, rief ich _WFE() zweimal nacheinander auf und das hat funktioniert. Obwohl dies mein Problem gelöst hat, habe ich mich gefragt, ob jemand etwas Licht ins Dunkel bringen kann. Vielleicht fehlt mir etwas.

Hier ist mein Code:

void HW_WakeupPinInit(void)
{
   GPIO_InitTypeDef gpioInitStruct = {0};

   gpioInitStruct.Mode      = GPIO_MODE_INPUT;
   gpioInitStruct.Pull      = GPIO_PULLDOWN;
   gpioInitStruct.Speed = GPIO_SPEED_HIGH;

   HW_GPIO_Init( WAKEUP_PORT, WAKEUP_PIN, &gpioInitStruct );

   LL_APB2_GRP1_EnableClock(LL_APB2_GRP1_PERIPH_SYSCFG);
   LL_SYSCFG_SetEXTISource(LL_SYSCFG_EXTI_PORTA, LL_SYSCFG_EXTI_LINE0);


   LL_EXTI_InitTypeDef EXTIinitStruct = {0};
   EXTIinitStruct.Line_0_31 = LL_EXTI_LINE_0;
   EXTIinitStruct.LineCommand = ENABLE;
   EXTIinitStruct.Mode = LL_EXTI_MODE_EVENT;
   EXTIinitStruct.Trigger = LL_EXTI_TRIGGER_FALLING;
   LL_EXTI_Init(&EXTIinitStruct);
}

void HW_EnterStopMode(void)
{
   uint32_t tmpreg = 0U;
   BACKUP_PRIMASK();
   DISABLE_IRQ();
   HW_IoDeInit();

   /*clear wake up flag*/
   LL_PWR_ClearFlag_WU();

   RESTORE_PRIMASK();
   tmpreg = PWR->CR;

   /* Clear PDDS and LPSDSR bits */
   CLEAR_BIT(tmpreg, (PWR_CR_PDDS | PWR_CR_LPSDSR));

   Set LPSDSR bit according to PWR_Regulator value */
   SET_BIT(tmpreg, LL_PWR_REGU_LPMODES_LOW_POWER);

   /* Store the new value */
   PWR->CR = tmpreg;

   LL_LPM_EnableDeepSleep();

   __WFE();
   __WFE();  // <------- Calling __WFE() second time works.
}

Vielen Dank im Voraus.

Antworten (1)

Ich habe Ihr Problem mit der folgenden Methode gelöst.

/* GPIO Ports Clock Enable */
__HAL_RCC_GPIOA_CLK_ENABLE();

/*Configure GPIO pin : PA10 */
GPIO_InitStruct.Pin = GPIO_PIN_10;
GPIO_InitStruct.Mode = GPIO_MODE_IT_RISING;
GPIO_InitStruct.Pull = GPIO_NOPULL;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);

LL_EXTI_InitTypeDef EXTIinitStruct = {0};
EXTIinitStruct.Line_0_31 = LL_EXTI_LINE_10;
EXTIinitStruct.LineCommand = ENABLE;
EXTIinitStruct.Mode = LL_EXTI_MODE_IT_EVENT;
EXTIinitStruct.Trigger = LL_EXTI_TRIGGER_RISING_FALLING;
LL_EXTI_Init(&EXTIinitStruct);

HAL_PWR_EnterSTOPMode(PWR_MAINREGULATOR_ON,PWR_SLEEPENTRY_WFE); 
LL_EXTI_DeInit();
Es wäre besser, wenn Sie (als Beschreibung) sagen würden, was die Ursache des Fehlers war.
Warum steigende Flanke am GPIO und steigende/fallende Flanke am EXTI?
Interessanterweise ruft die Implementierung von HAL_PWR_EnterSTOPMode tatsächlich zweimal _WFE() auf (was hier zu sehen ist: line899 ). Also ich denke, so sollte es sein, obwohl das Datenblatt nichts sagt! Ich werde das als gelöst markieren.