CH32--裸机系统实现多任务

发布时间 2023-06-12 20:14:29作者: WCH_CH32

在ram和flash资源足够的芯片中,我们通常通过跑操作系统来实现多任务,但此方法有个弊端,那就是对ram要求高,那么对于比如003这种只有2K  ram的小容量芯片可能就不太够用了。

这时就需要裸机来实现多任务了,方法如下:

在裸机中,通常都是在一个 while 循环中,通过判断相应的标志位,来按照顺序执行相应的代码。为了加快响应速度,

较为常见的做法是中断中修改标志位,代码中判断标志位,如下:

int main(void)
{
  XX_Init();

  /* while 中判断标志位 */
  while (1)
  {
    if (flag1 == 1)
    {
      code1;
      flag1 = 0;
    }

    if (flag2 == 1)
    {
      code2;
      flag2 = 0;
    }

    /************/
  }
}

/* 中断服务函数中修改标志位 */
void interrupt1(void)
{
  flag1 = 1;
}

void interrupt2void)
{
  flag2 = 1;
}

 上述处理在裸机系统中比较常用,也足以实现很多的功能。但一种更为高级的处理方式,就是利用 SysTick 来实现类似于实时操作系统的调度,来看一下是怎么实现的:

注:此例程以203为例,要改为003的只需要注意下003与203不同的是systic是32位的,203是64位的

1.定义任务数量,以及任务时基

#define NumOfTask     2
unsigned int Task_Delay[NumOfTask]={ 0 };

2.systic的初始化

static uint32_t SysTick_Config(uint32_t ticks)
{
    SysTick->CTLR = 0x00000000;             //控制寄存器复位

    SysTick->SR = 0x00000000;               //状态寄存器复位

    SysTick->CNT = 0x00000000;              //计数器复位,设置初始值为0

    SysTick->CMP = ticks;                   //给重加载寄存器赋值

    NVIC_SetPriority(SysTicK_IRQn, 15);     //设置SysTick中断优先级

    NVIC_EnableIRQ(SysTicK_IRQn);           //使能开启Systick中断

    SysTick->CTLR |= 0x0000000B;            //启动系统计数器STK(HCLK/8时基),向上计数到比较值后重新从 0 开始计数

    return (0);
}

void Systick_Init(void)
{
    //此处在进行初始化的时候设置比较寄存器的值
    SysTick_Config(SystemCoreClock / 8000);//1ms            72M/8000/9000000 = 1/1000 = 1ms
}

void SysTick_Handler(void) __attribute__((interrupt("WCH-Interrupt-fast")));
void SysTick_Handler(void)
{
    SysTick->SR  = 0;//清标志
    unsigned char i;
      for (i = 0; i < NumOfTask; i++)
      {
        if (Task_Delay[i])
        {
          Task_Delay[i]--;
        }
      }


}

3.while(1)中的任务处理(想要更多任务参考下面格式来即可)

while (1)
      {
        if (Task_Delay[0] == 0)
        {
          /* 任务 0 主体 */
            printf("test_0\r\n");
          /* 任务 0 延时 1000ms */
          Task_Delay[0] = 1000;
        }

        if (Task_Delay[1] == 0)
        {
          /* 任务 1 主体 */
            printf("test_1\r\n");
          /* 任务 1 延时 500ms */
          Task_Delay[1] = 500;
        }

      }