之前分享过一篇“使用定时器中断进行延时,取代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