中断执行模式
针对于上面的问题,很多人就会使用中断来解决。对于一些需要立即响应的操作,将其放在中断中,从而避免其被主程序中的其他逻辑所影响,此时代码可能如下所示:
<p>
</p><p>//按键中断</p><p>void key_isr(void){</p><p> do_b(); //按键按下的操作</p><p>}</p><p>
</p><p>int main(void) {</p><p> while(1){</p><p> do_a();</p><p> do_c();</p><p> }</p><p>}</p>
主循环中还是正常执行非交互式的逻辑,而对于上例中按键交互的逻辑 do_b,则放到对应的按键信号捕获中断中(如 GPIO 外部中断)。此时即使在执行主循环中的其他逻辑,由于中断会打断主循环立即运行,所以按键信号会被立刻检测到并响应。
无法及时得到响应的问题解决了,对于一些非常简单的逻辑,这种模式就足够了,但如果主循环中的逻辑有一定的周期性要求,如 do_a 需要每隔 100 毫秒执行一次, do_c 需要 50 毫秒执行一次,于是 do_a 和 do_c 下就会存在 delay(100) 和 delay(50) 的代码:
<p>// 按键中断</p><p>void key_isr(void) {</p><p> do_b(); // 按键按下的操作</p><p>}</p><p>
</p><p>void do_a(void) {</p><p> delay(100); // 延时100ms</p><p> // do_a 逻辑</p><p>}</p><p>
</p><p>void do_c(void) {</p><p> delay(50); // 延时50ms</p><p> // do_c 逻辑</p><p>}</p><p>
</p><p>int main(void) {</p><p> while (1) {</p><p> do_a();</p><p> do_c();</p><p> }</p><p>}</p>
此时无论 do_a 和 do_c 谁前谁后,他们的执行周期都会拉长到至少 150 毫秒!因为顺序执行的原因,你必须等待上一个逻辑执行完才能执行下一个逻辑。
这种情况下 do_a 和 do_c 任何一个逻辑的周期都无法被满足,这种模式的缺陷也就显现出来了。
|