时间片轮询法

在单片机编程中,时间片轮询法是鉴于裸机编程与RTOS编程之间的。如果你熟练使用时间片轮询发的话,RTOS可以肯定也使用很6。

时间片轮询使用

在使用时间片轮询法的话,我们需要创建一个任务结构体:

struct  TaskStruct 
{
	u16	TaskTickNow;//用于计时
	u16	TaskTickMax;//设置计时时间
	u8	TaskStatus;//任务运行标志位
	void (*FC)();//任务函数指针
};


struct TaskStruct taskStruct[] = {
		{ 0,        5000,            0,           OLED_Task},
		{ 0,        2000,            0,           LED_Task},
		{ 0,        20, 			 0,			  Hx711_Task},
		{ 0,        20,				 0,			  key3_Task},
		{ 0,        20,				 0,			  key2_Task},
		{ 0,        20,				 0,			  key1_Task},
		{ 0,        20,			     0,			  key0_Task},
		{ 0, 	    1000,		     0,			  debug_Task},
};

我们需要一个定时器触发中断函数,进行累加。给单片机赋予一个时间概念,时间片一般为1ms。

//定时器中断
void TIM2_IRQHandler(void)
{
	if(TIM_GetITStatus(TIM2,TIM_IT_Update) != RESET)
	{
			OS_Run();
			TIM_ClearITPendingBit(TIM2,TIM_IT_Update);
	}
}

void OS_Run(void)
{
		u8 i;
		for(i=0;i<TaskCount;i++)
		{	
			if(!taskStruct[i].TaskStatus)
			{		
				if(++taskStruct[i].TaskTickNow >= taskStruct[i].TaskTickMax)
				{	
					taskStruct[i].TaskTickNow = 0;
					taskStruct[i].TaskStatus = 1;
				}
			}
		}
}

在while循环中添加:

	int main()
    {
        while(1)
	    {
			if(taskStruct[i].TaskStatus)
			{
				taskStruct[i].FC();
				taskStruct[i].TaskStatus = 0;
			}
			if(++i>=TaskCount)
				i = 0;
	    }
    }

时间片轮询法注意事项

1.由于时间片轮询法延时不是绝对准确,例如,任务A周期100ms,当时间线来到100ms那个节点,现在应该去执行任务A,但如果当前有之前任务还没执行完,将会让任务A执行周期变得不准确,并不是100ms,可能是103ms。

这样也引出Freertos里面一些任务需要用绝对延时vTaskDelayUntil()与vTaskDelay()

2.时间片轮询里面不能使用delay_ms(),将CPU卡死。可以使用

//task任务执行周期是100ms
void task()
{
    static u8 u8cnt1 = 0;
    if(u8cnt1++ >= 2)  // 200ms执行里面
    {
    
    }

}

3.裸机时间片轮询编程中有些任务不能太长,需要切开step1,step2,step3比较好

  • 5
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值