我需要以固定的时间间隔执行一个程序。该过程需要很长时间才能执行,在此期间其他中断必须处于活动状态。此外,在每次定时器溢出时执行该过程至关重要。
看看这个伪代码:
ISR(timer_overflow)
{
timer_flag = 1;
}
main_loop()
{
if (timer_flag)
{
long_time_consuming_procedure();
timer_flag = 0;
}
(* if a timer interrupt fires here, will the procedure be executed? *)
sleep();
}
如果以上内容不起作用,下面的代码会让事情变得坚如磐石吗?
main_loop()
{
cli();
if (timer_flag)
{
sei();
long_time_consuming_procedure();
timer_flag = 0;
}
sei();
sleep();
}
或者这可能会更好,因为其他中断处理得非常快:
ISR(timer_overflow)
{
sei();
long_time_consuming_procedure();
}
main_loop()
{
sleep();
}
我正在使用avr-gcc
修改
看起来我分享的细节太少了。我害怕这种最糟糕的情况:
if (timerflag)
和sleep()
之间),计时器溢出long_time_consuming_procedure
,因为我们已经通过if (timerflag)
这种方式有两个定时器中断,只有一个long_time_consuming_procedure
执行。发生这种情况的可能性非常小,但如果出现问题,情况会更糟。
答案 0 :(得分:0)
通常,数字1是最常见的解决方案。因为它允许您的程序执行,而其他中断仍然处理。
应该避免使用2号,因为打开和关闭中断不是很好的做法。有边缘情况,但需要更多的细节,为什么数字1不起作用。
在执行长时间运行的过程时,数字3不允许其他中断处于活动状态,因此应该避免它,因为其他中断不会在ISR中处理。
答案 1 :(得分:0)
您没有为特定答案提供足够的信息。如果要求是,你的long_time_consuming_procedure()只是每个间隔执行一次,但是当它在那段时间完成时它是无关紧要的,我会去找解决方案#1。
确保在long_time_consuming_procedure()处理期间可能发生的所有中断的long_time_consuming_procedure()+执行时间的执行时间短于计时器间隔。
即使一般概念非常简单,但有时候使基于中断的代码完全符合要求也是非常重要的。您必须仔细评估每个中断和个别要求。
答案 2 :(得分:0)
如果你想在每次定时器溢出时执行程序,并且在执行过程中有可能发生中断,请使用:
ISR(timer_overflow)
{
timer_flag = 1;
}
main_loop()
{
if (timer_flag)
{
cli();
timer_flag = 0;
sei();
long_time_consuming_procedure();
}
sleep();
}
答案 3 :(得分:0)
在AVR Libc用户手册中,sleep.h
的详细说明中我找到了一个例子:
set_sleep_mode(<mode>); cli(); if (some_condition) { sleep_enable(); sei(); sleep_cpu(); sleep_disable(); } sei();
此序列确保在禁用中断的情况下对some_condition进行原子测试。如果满足条件,则将准备睡眠模式,并且将在SEI指令之后立即调度SLEEP指令。 由于SEI保证在中断触发之前执行,因此可以确保设备真正进入休眠状态。
在sleep_enable()
和朋友