cancel
Showing results for 
Search instead for 
Did you mean: 

Button interrupt with time period

TPiri.1
Associate II

Hi,

I want to implement button interrupt with time period to send the mcu to Dee-sleep ,and wake up. For example; When I press button for 5 sec, MCU will go to sleep, when I press the button second time for 5 sec MCU will wakes up. but I don't know from where to tart, any help appreciated.

6 REPLIES 6
Tom Schrauf
Associate II

I think it will not be possible to check if the button was pressed for 5 seconds before waking up from deep sleep. How should the processor check the signal length if it is deep sleeping ?

true, only to go to sleep need to wait 5 sec, not to wake up

Tom Schrauf
Associate II

Well you have to setup EXTI interrupt linked to the Pin your button is attached to in order to wake up from deep sleep. As far as I remember there exist two ways to exit from deep sleep - event based and interrupt based. These modes have to match the EXTI setup.

Don't forget to stop all other interrupt sources (also the sysTic interrupt!) as they would also wakeup your processor.

Example of entering the stop mode:

// disable systics

   SysTick->CTRL &= ~(SysTick_CTRL_TICKINT_Msk);

   EXTI->PR = 0xFFFFFFFF;

   PWR_ClearFlag(PWR_FLAG_WU);

   PWR_EnterSTOPMode(PWR_Regulator_LowPower, PWR_STOPEntry_WFI);

the ..WFI is for wait for interupt

WFE is for wait event

   /* Configure EXTI Line0 to generate an event or an interrupt on rising edge */

   EXTI_ClearITPendingBit(EXTI_Line0);

   EXTI_InitStruct.EXTI_Line = EXTI_Line0;               // for the wakeup pin

   EXTI_InitStruct.EXTI_Mode = EXTI_Mode_Interrupt;

   EXTI_InitStruct.EXTI_Trigger = EXTI_Trigger_Both;

   EXTI_InitStruct.EXTI_LineCmd = ENABLE;

   EXTI_Init(&EXTI_InitStruct);

But for more details it would be necessary to know your processor and whether you use CubeMX (which i don't know), cmsis or pure code.

In my application I use two event sources to wakeup from sleep.

A signal from another MCU indicating the beginning of an SPI transfer and the alarm tic to wake up on a regular basis (let's say every minute).

To check if a signal (the button) is active for a certain period of time before entering sleep mode should be pretty easy. I use a global uint32_t variable being incremented at every sysTic (usually 1mS). You can use an EXTI interrupt service routine to detect most recent make of the signal and measure the "length" in the sysTic interrupt service routine but there exist many ways that would do the trick.

TDK
Guru

Set up a timer to periodically poll the button status. Increment a counter when it's depressed and reset it when released. If that counter reaches 5 seconds, go to deep sleep.

If you feel a post has answered your question, please click "Accept as Solution".

I am using Nucleo-L476GR board with CubeIDE,

I new to tm32 HAL programming, I implemented to toggle the LED with external interrupt button,

void HAL_GPIO_EXTI_Callback (uint16_t GPIO_Pin)

{

if(GPIO_Pin == B1_Pin){

HAL_GPIO_TogglePin(LD2_GPIO_Port,LD2_Pin);

}

else{

__NOP();

}

}

next step is to implement PRESS time, but still couldn't

Tom Schrauf
Associate II

TDK's way is about what I tried to explain.

The timer you can use is the SysTic timer, i think in CUBE you can use

HAL_SYSTICK_IRQHandler();

This is usually triggered every 1 mS (you could setup a different speed but i wouldn't)

in this ISR:

static unsigned int buttonPressedmS;

if (GPIOB->IDR & GPIO_Pin_1) // <- or the HAL way to query a pin status

buttonPressedmS++;

else {

buttonPressedmS=0;

}

if (buttonPressedmS > 5000)

enterDeepSleep();

A button will usually/sometimes cause bouncing so before the real pressing of the button you might encounter some short press/release/press/release states.

But keep your EXTI setup required to come back from deep sleep.

Sorry i never used CubeIDE so maybe the exit of deep sleep is way easier to setup there.