STM32F4 Discovery上的中断未更新变量值

时间:2016-04-07 17:15:12

标签: c stm32 keil

在下面的代码中,我可以看到定时器正常工作,因为LED始终闪烁。但count变量的值永远不会在第二个while内发生变化。

我不知道可能出现什么问题?

// 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;
    }   
}

我尝试过另一个发现板,但问题还在继续。 请帮忙。我疯了!

1 个答案:

答案 0 :(得分:1)

您应该将count声明为volatile,因此:

volatile uint8_t count;

在编译main时,编译器能够证明count未在循环体中被修改,因此它可能将其值缓存在寄存器中,甚至可能优化{{1}声明。您可以通过查看反汇编来验证。编译器根据标准不知道中断,因此允许执行此类优化。将if限定为count将禁止编译器进行这些优化,强制它在每次使用时从内存重新加载变量。

在这个简单的情况下volatile就足够了但请注意它并不能保证操作的原子性,并且它不会阻止编译器和CPU重新排序访问指令变量。它只强制编译器在每次使用变量时生成内存访问指令。对于原子性,你需要锁定,并且为了防止重新排序,你需要内存障碍。