您的位置 首页 基础

单片机中的时刻片轮询法解析

单片机中的时间片轮询法解析-时间片轮询法,在很多书籍中有提到,而且有很多时候都是与操作系统一起出现,也就是说很多时候是操作系统中使用了这一方法。不过我们这里要说的这个时间片轮询法并不是挂在操作系统下,而是在前后台程序中使用此法。也是本贴要详细说明和介绍的方法。

时刻片轮询法,在许多书本中有说到,并且有许多时分都是与操作体系一同呈现,也便是说许多时分是操作体系中运用了这一办法。不过咱们这儿要说的这个时刻片轮询法并不是挂在操作体系下,而是在前后台程序中运用此法。也是本贴要详细阐明和介绍的办法。

关于时刻片轮询法,虽然有不少书本都有介绍,但大多说得并不体系,仅仅提提概念罢了。下面自己将详细介绍自己形式,并参阅他人的代码树立的一个时刻片轮询架构程序的办法,我想将给初学者有必定的学习性。

记住在前不久自己发帖《1个守时器多处复用的问题》,因为时刻的问题,并没有详细阐明怎样完结1个守时器多处复用。在这儿咱们先介绍一下守时器的复用功用。

运用1个守时器,可所以恣意的守时器,这儿不做特别阐明,下面假定有3个使命,那么咱们应该做如下作业:

1. 初始化守时器,这儿假定守时器的守时中止为1ms(当然你能够改成10ms,这个和操作体系相同,中止过于频频功率就低,中止太长,实时性差)。

2. 界说一个数值:

仿制内容到剪贴板

代码:

#define TASK_NUM(3)//这儿界说的使命数为3,表明有三个使命会运用此守时器守时。

uint16 TaskCount[TASK_NUM];//这儿为三个使命界说三个变量来寄存守时值

uint8TaskMark[TASK_NUM];//相同对应三个标志位,为0表明时刻没到,为1表明守时时刻到。

3. 在守时器中止服务函数中增加:

仿制内容到剪贴板

代码:

void TImerInterrupt(void)

{

uint8 i;

for (i=0; i

{

if (TaskCount[i])

{

TaskCount[i]–;

if (TaskCount[i] == 0)

{

TaskMark[i] = 0x01;

}

}

}

}

代码解说:守时中止服务函数,在中止中逐一判别,假如守时值为0了,表明没有运用此守时器或此守时器现已完结守时,不着处理。不然守时器减一,知道为零时,相应标志位值1,表明此使命的守时值到了。

4. 在咱们的使用程序中,在需求的使用守时的当地增加如下代码,下面就以使命1为例:

仿制内容到剪贴板

代码:

TaskCount[0] = 20;// 延时20ms

TaskMark[0]= 0x00;// 发动此使命的守时器

到此咱们只需求在使命中判别TaskMark[0]是否为0x01即可。其他使命增加相同,至此一个守时器的复用问题就完结了。用需求的朋友能够试试,作用不错哦。。。。。。。。。。。

经过上面临1个守时器的复用咱们能够看出,在等候一个守时的到来的一起咱们能够循环判别标志位,一起也能够去履行其他函数。

循环判别标志位:

那么咱们能够想想,假如循环判别标志位,是不是就和上面介绍的次序履行程序是相同的呢?一个大循环,仅仅这个延时比一般的for循环准确一些,能够完结准确延时。

履行其他函数:

那么假如咱们在一个函数延时的时分去履行其他函数,充分使用CPU时刻,是不是和操作体系有些相似了呢?可是操作体系的使命办理和切换是十分复杂的。下面咱们就将使用此办法架构一向新的使用程序。

时刻片轮询法的架构:

1.规划一个结构体:

代码:

//使命结构

typedefstruct_TASK_COMPONENTS

{

uint8Run;//程序运转符号:0-不运转,1运转

uint8TImer;//计时

uint8ItvTIme;//使命运转间隔时刻

void(*TaskHook)(void);//要运转的使命函数

}TASK_COMPONENTS;//使命界说

这个结构体的规划十分重要,一个用4个参数,注释说的十分详细,这儿不在描绘。

2. 使命运转标志出来,此函数就相当于中止服务函数,需求在守时器的中止服务函数中调用此函数,这儿独立出来,并于移植和了解。

代码:

voidTaskRemarks(void)

{

uint8i;

for(i=0;i//逐一使命时刻处理

{

if(TaskComps[i].TImer)//时刻不为0

{

TaskComps[i].Timer–;//减去一个节拍

if(TaskComps[i].Timer==0)//时刻减完了

{

TaskComps[i].Timer=TaskComps[i].ItvTime;//康复计时器值,重新下一次

TaskComps[i].Run=1;//使命能够运转

}

}

}

}

咱们仔细比照一下次函数,和上面守时复用的函数是不是相同的呢?

3. 使命处理

代码:

voidTaskProcess(void)

{

uint8i;

for(i=0;i//逐一使命时刻处理

{

if(TaskComps[i].Run)//时刻不为0

{

TaskComps[i].TaskHook();//运转使命

TaskComps[i].Run=0;//标志清0

}

}

}

此函数便是判别什么时分该履行那一个使命了,完结使命的办理操作,使用者只需求在main()函数中调用此函数就能够了,并不需求去别离调用和处理使命函数。

到此,一个时刻片轮询使用程序的架构就建好了,咱们看看是不是十分简略呢?此架构只需求两个函数,一个结构体,为了使用方面下面将再树立一个枚举型变量。

下面我就就说说怎样使用吧,假定咱们有三个使命:时钟显现,按键扫描,和作业状况显现。

1. 界说一个上面界说的那种结构体变量

代码:

staticTASK_COMPONENTSTaskComps[]=

{

{0,60,60,TaskDisplayClock},//显现时钟

{0,20,20,TaskKeySan},//按键扫描

{0,30,30,TaskDispStatus},//显现作业状况

//这儿增加你的使命。。。。

};

在界说变量时,咱们现已初始化了值,这些值的初始化,十分重要,跟详细的履行时刻优先级等都有联系,这个需求自己把握。
来历;21ic

声明:本文内容来自网络转载或用户投稿,文章版权归原作者和原出处所有。文中观点,不代表本站立场。若有侵权请联系本站删除(kf@86ic.com)https://www.86ic.net/zhishi/jichu/344357.html

为您推荐

联系我们

联系我们

在线咨询: QQ交谈

邮箱: kf@86ic.com

关注微信
微信扫一扫关注我们

微信扫一扫关注我们

返回顶部