STM32 静态全局变量值不正常问题

   今天在调试按键驱动的过程中,使用Systick 定时器中断中每10ms 调用一次按键检测程序,在按键检测程序中按下时有一个定时器计时,具体程序如下所示。

 void buttonScan(void)
{

static u8 	sLastButtonState = BUTTON_RELEASE;//初始状态为松开
static u8 	sButtonState;
static u8 	sButtonPreCnt;

	if(isButtonPressed())
	{
		sButtonTick++;
		sLastButtonState = BUTTON_PRESSED;
	}else //按键松开
	{
		gButtonState =BUTTON_RELEASE;
		if(BUTTON_PRESSED == sLastButtonState)
		{
			if(sButtonTick > 5 && sButtonTick < 100)
			{
				gButtonState = BUTTON_PRESSED;// 按键按下一次
				sButtonPreCnt++;
			}else if(sButtonTick > 200)
			{
				gButtonState = BUTTON_HOLD_2S;// 按键长按
			};
		}
		sButtonTick = 0;
		sLastButtonState = BUTTON_RELEASE;
	}
	
}

      按照正常的逻辑,每10ms 进入到该程序中,如果按键一直处于按下状态,那么sButtonTick的值会正常的每10ms增加1,但是在仿真的过程中,将按键长按不松开,在变量窗口中动态显示却发现该值的变化速度特别快,而且值大于系统滴答计时器的计时时间,该值使用u16 类型进行定义,经常会跑到溢出的状态。

   发现该问题时,进行了以下尝试

 (1) 将该变量使用volatile 修饰

(2) 修改Keil的优化等级为0

但是该值还是不正常。最后回归到该函数调用,发现该函数在中断中调用了一次,如下所示

void SysTick_Handler(void)
{
static u8 sButtonHandlerTick = 0;

	gSystick++; // add 1ms
	sButtonHandlerTick++;
	if(sButtonHandlerTick > 9)
	{
		buttonScan();
		sButtonHandlerTick = 0;
	}
		
}

之后在主程序中又进行了一次调用,如下所示。

    while(1)
	{
		gButtonState = buttonScan();
		if(BUTTON_PRESSED == gButtonState)
		{
			printf("button pressed 1 times\r\n");
		}else if(BUTTON_PRESSED_3X == gButtonState)
		{
			printf("button presed 3 times \r\n");
		}else if(BUTTON_HOLD_2S ==  gButtonState)
		{
			printf("button long hold 2 second \r\n");
		};
	}

   突然意识到一个函数在中断中被调用又在主函数中被调用,导致该值在出入栈的过程中发生了异常。随后去掉在主函数中对该函数的调用,再进行同样的动态debug,发现该值已经正常。问题得到解决。

   对于这个问题我当前并未找到最合理的解释,但是可以明确的是在编译过程中keil是没有报出警告的。但是其实这也是一个编程习惯的问题,以前在使用8051的一些单片机的时候编译器是会明确的告诉我同一个函数不能在中断中调用又在主函数中调用。

   想了想还是记录下来,给自己一个警告,让自己在以后的开发中多注意这样的问题。

 

你可能感兴趣的:(STM32)