cancel
Showing results for 
Search instead for 
Did you mean: 

Why variable changes to old value?

Alexios
Associate

I have stm32vldiscovery board. I generated project by stm32cubemx.

I want to switch down led by external interrupt (PA0 button).

I have this in main.c

#include "main.h"
...
uint8_t ldOn = 1;
 
int main(void)
{
  HAL_Init();
  SystemClock_Config();
  MX_GPIO_Init();
 
  HAL_GPIO_WritePin(LD4_GPIO_Port, LD4_Pin, GPIO_PIN_SET);
 
  while (1)
  {
        if(ldOn == 0)
            HAL_GPIO_WritePin(LD4_GPIO_Port, LD4_Pin, GPIO_PIN_RESET);
  }
}

stm32f4xx_it.c

#include "main.h"
...
extern uint8_t ldOn;
void EXTI0_IRQHandler(void)
{
  ldOn = 0;
  HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_0);
}

When I click on the button, I see in the debugger that the value of the variable changes to 0, and then immediately again to 1.

If I try this code on the stm32f4-disc1 board it works perfectly.

Where I went wrong?

3 REPLIES 3
S.Ma
Principal

I guess something now shown is causing side effect.

What's the pin name for LD4?

Any other piece of code manipulating this pin? Maybe other interrupts?

Another way to get the variable back to 1 is the MCU was reset (watchdog, etc....)

Using EXTI for button maynot be ideal. Mecanical buttons have debouncing and signal is glitchy.

You can just poll the pin every 50msec and triple check the level before calling it... unless you want to WAKEUP from sleep mode, and this is another possible root for hidden bugs if implemented.

Try with volatile:

volatile uint8_t ldOn = 1;

You are changing the variable from the interrupt handler, if you don't declare it as volatile the compiler optimizer in main.c can rightfully "cache" the ldOn value inside the while loop or even assume that ldOn is always 1 and completely eliminate this code as unnecessary:

if(ldOn == 0)
            HAL_GPIO_WritePin(LD4_GPIO_Port, LD4_Pin, GPIO_PIN_RESET);

Alexios
Associate

Now i tested the board... In debugger I saw when controller runs HAL_Delay function it goes reset... 

Why it happens?