首页 > 其他分享 >使用定时器中断进行延时,可能会遇到的一个小bug

使用定时器中断进行延时,可能会遇到的一个小bug

时间:2024-03-15 22:29:25浏览次数:28  
标签:... cnt 定时器 flag state 延时 time 清零 bug

之前分享过一篇“使用定时器中断进行延时,取代delay”的文章:
(https://blog.csdn.net/qq_44139306/article/details/136481381?spm=1001.2014.3001.5501)

在后续的使用过程中,发现了一个bug:
即:定时器标志不要在刚使用完一次时就清零,可以在下一次赋值计数值前把它清零。特别是在使用状态机的过程中

问题如下:

可以看看下面的代码:假设定时器的周期是500ms,那我们的逻辑是,在每个阶段停留1s,再进入下一个阶段。 state=1执行完之后,把time_cnt置为2,就会开始1s的计时(定时器中会time_cnt–,直到time_cnt=0就把time_flag置为1)。
如果我们在刚进入state= =2、time_flag= =1时就把time_flag清零(这是我的习惯,用完就把标志位清零。。),这就会导致一个问题:1s的时间到了(即:time_cnt=0,time_flag=1 ),第一次进来state= =2时,把time_flag 置0,然后condition不满足,就会跳去else执行。 这个时候应该是留在state2,直到condition满足,就会进入下一个1的计时(即:time_cnt = 2)。
而下次进来state= =2时,因为time_flag为0,就进不去了。这就导致我们一直停留在else的状态,显然是不符合我们预期的。

if(state == 1)
{
	...
	time_cnt = 2;
	state = 2;
}
if(state == 2)
{
	if(time_flag == 1)
	{
		time_flag = 0;
		if(condition)
		{
			...
			time_cnt = 2;
			state = 3;
		} else{
			...
		}

	}
} 

解决方法

time_flag不要在刚使用完一次时就清零,可以在下一次赋值计数值之前把它清零,这样就可以保证time_flag始终是有效的。特别是在使用状态机的过程中。代码如下

if(state == 1)
{
	...
	time_cnt = 2;
	state = 2;
}
if(state == 2)
{
	if(time_flag == 1)
	{
		//time_flag = 0;
		if(condition)
		{
			...
			time_flag = 0;
			time_cnt = 2;
			state = 3;
		} else{
			...
		}

	}
} 

标签:...,cnt,定时器,flag,state,延时,time,清零,bug
From: https://blog.csdn.net/qq_44139306/article/details/136751008

相关文章