在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; } }
标签:Delay,Task,CH32,--,void,裸机,while,SysTick From: https://www.cnblogs.com/wchmcu/p/17476011.html