简体   繁体   中英

Variable value not updated by interrupt on STM32F4 Discovery

In the code below, I can see that the timer is working normally as the LED is always blinking. But the value of the count variable never changes inside the second while .

I don't know what could possibly go wrong?

// count variable used only in main and TIM2_IRQHandler.
uint8_t count=0;

int main(void)
{
    count=0;
    SystemInit();
    GPIOInit();
    NVIC_Configuration();
    TIM_Configuration();
    init_USART3(115200);
    // All initialization is ok.
    USART_puts(USART3, "\r\nConnection ok.\r\n");// Working normally
    while (1)
    {
        if(asterixok==1)// No problem. This code if ok ->>process continue next step.
        {
            GPIO_SetBits(GPIOD , GPIO_Pin_12); // Led on (ok)
            count=0;// count going to zero, timer working, must be change in there
            while(1)
            {
                //Led blinking continue
                //Timer query working normal led (13) blink.
                //There is a problem
                if(count>5) // Timer working, count never change in timer interrupt query (WHY)
                {
                    GPIO_SetBits(GPIOD , GPIO_Pin_14); // LED OFFFFFFFFFFFFFFFF
                    USART_puts(USART3, "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\r\n");
                    goto nextstate;
                }
            }
            nextstate:
            GPIO_SetBits(GPIOD , GPIO_Pin_15); // Led never going on because code step in while loop.
        }
    }
}

void USART3_IRQHandler(void)
{
    if( USART_GetITStatus(USART3, USART_IT_RXNE) )
    {
        unsigned char t = USART3->DR;
        if(t=='*')
        {
            asterixok=1;
        }
    }
}

void TIM2_IRQHandler(void)
{
    if ( TIM_GetITStatus(TIM2 , TIM_IT_Update) != RESET ) 
    {
        TIM_ClearITPendingBit(TIM2 , TIM_FLAG_Update);
        count++;
        if(count>100)
            count=0;
        if( display ) 
        { 
            GPIO_ResetBits(GPIOD , GPIO_Pin_13);
        }  
        else 
        { 
            GPIO_SetBits(GPIOD , GPIO_Pin_13);
        }
        display = ~display;
    }   
}

I have tried with another Discovery board but the problem continues. Please help. I'm going crazy!

You should declare count as volatile , as such :

volatile uint8_t count;

While compiling main the compiler was able to prove that count was not modified in the loop body, and so it probably cached its value in a register and maybe even optimized out the if statement. You could verify that by looking at a disassembly. The compiler does not know about interrupts as per the standard and so is permitted to perform such optimizations. Qualifying count as volatile will forbid the compiler from making these optimizations, forcing it to reload the variable from memory each time it is used.

In this simple case volatile will be enough but please be aware that it doesn't guarantee atomicity of operations, and it doesn't prevent the compiler and CPU from reordering instructions around accesses to the variable. It only forces the compiler to generate memory access instructions each time the variable is used. For atomicity you need locks, and to prevent reordering you need memory barriers.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM