在下面的代码中,我可以看到定时器正常工作,因为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;
}
}
我尝试过另一个发现板,但问题还在继续。 请帮忙。我疯了!
答案 0 :(得分:1)
您应该将count
声明为volatile
,因此:
volatile uint8_t count;
在编译main
时,编译器能够证明count
未在循环体中被修改,因此它可能将其值缓存在寄存器中,甚至可能优化{{1}声明。您可以通过查看反汇编来验证。编译器根据标准不知道中断,因此允许执行此类优化。将if
限定为count
将禁止编译器进行这些优化,强制它在每次使用时从内存重新加载变量。
在这个简单的情况下volatile
就足够了但请注意它并不能保证操作的原子性,并且它不会阻止编译器和CPU重新排序访问指令变量。它只强制编译器在每次使用变量时生成内存访问指令。对于原子性,你需要锁定,并且为了防止重新排序,你需要内存障碍。