如何保证主函数被中断函数打断后正常运行? 先看如下的例子:

static volatile uint8_t g_ucIntCnt = 0;

void RTC_ISR(void) interrupt 5
{
    g_ucIntCnt++;
}

void loop(void)                      |  void loop(void)
{                                    |  {
    while (1)                        |      while (1)
    {                                |      {
        do_something1();             |          do_something1();
                                     |
        if (g_ucIntCnt == 100)       |          if (g_ucIntCnt >= 100)
        {                            |          {
            do_something2();         |              do_something2();
        }                            |              g_ucIntCnt = 0;
                                     |          }
        g_ucIntCnt = 0;              |
        do_something3();             |          do_something3();
    }                                |      }
}                                    |  }

void main(void)
{
    init();
    loop();
}

请思考一下,程序中的 do_something2 会按预期每隔 100 个 rtc 单位运行一次吗?
左边的代码中:

  1. 由于 do_something1 的代码复杂度未知,很大概率无法撞上 g_ucIntCnt = 100 的条件;
  2. 另一方面,如果 do_something1 很短,在主循环中,在 g_ucIntCnt 还很小时过早清 0,也会导致无法满足条件;
  3. 即使刚好凑巧,可以运行到 do_something2,假如函数内部有用到 g_ucIntCnt 也会导致程序错误。

右边的代码中:

  1. 如果 do_something1 过于复杂,导致运行完之后 g_ucIntCnt 已经溢出,也无法运行 do_something2;
  2. 同样有左边代码 3 的问题。
static volatile uint8_t g_ucIntCntFlag = 0;

void RTC_ISR(void) interrupt 5
{
    static volatile uint8_t g_ucIntCnt = 0;

    if (++g_ucIntCnt > 100)
    {
        g_ucIntCnt = 0;
        g_ucIntCntFlag = 1;
    }
}

void loop(void)
{
    while (1)
    {
        do_something1();

        if (g_ucIntCntFlag)
        {
            do_something2();
            g_ucIntCntFlag = 0;
        }

        do_something3();
    }
}

void main(void)
{
    init();
    loop();
}