晨光医疗拟在创业板上市,现正在接受西部证券股份有限公司辅导,
06-18
时间片轮询法在很多书籍中都提到过,而且很多时候是和操作系统一起出现的,也就是说操作系统中经常会用到它。
这个方法。
不过我们这里要讲的时间片轮询方式并不是挂在操作系统下的,而是用在前后端程序中的。
这也是本文将要详细解释和介绍的方法。
虽然介绍时间片轮询方法的书籍很多,但大多不系统,只是提概念。
接下来我会详细介绍一下我自己的模型,并参考别人的代码创建一个时间片轮询架构程序。
我想对于初学者来说可以有一定的参考价值。
我记得不久前发过帖子《1个定时器多处复用的问题》。
由于时间问题,我没有详细解释如何在多个地方重用一个定时器。
这里先介绍一下定时器的复用功能。
。
。
使用1个定时器,可以是任何定时器。
这里没有给出特殊说明。
假设有以下3个任务,那么我们应该做以下工作: 1。
初始化定时器。
这里我们假设定时器调度的中断是1ms(当然你可以改成10ms。
这个和操作系统是一样的,如果中断太频繁,效率就会低,如果中断太长,实时性会较差)。
2。
定义一个值: 复制内容到剪贴板代码: #define TASK_NUM(3)//这里定义的任务数量为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,当为0时,对应的标志值为1,表示该任务的计时值已完成。
4. 在我们的应用程序中,需要应用程序计时的地方添加以下代码: 将内容复制到剪贴板代码: 。
TaskCount[0] = 20;//延迟20ms TaskMark[0]= 0x00;//启动该任务的定时器 此时我们只需判断任务中TaskMark[0]是否为0x01即可能。
以同样的方式添加其他任务,现在就实现了一个定时器的复用问题。
有需要的朋友可以尝试一下,效果不错。
。
。
。
。
。
。
。
。
。
。
通过上面定时器的复用,我们可以看到,在等待定时器到来的同时,我们可以循环判断标志位,同时执行其他函数。
循环判断标志: 那么我们可以想一下,如果使用了循环判断标志,是不是和上面介绍的顺序执行程序一样呢?一个很大的循环,但是这个延迟比普通的for循环更精确,可以实现精确的延迟。
执行其他函数: 那么如果我们在某个函数延迟的同时执行其他函数,充分利用CPU时间,是不是和操作系统类似呢?但任务管理和操作系统的切换非常复杂。
下面我们将使用这种方法来构建一个新的应用程序。
时间片轮询方式的架构: 1.设计一个结构体: 代码: //任务结构体 typedefstruct_TASK_COMPONENTS { uint8Run;//程序运行标记:0-不运行,1运行 uint8Timer;//定时器 uint8ItvTime;//任务运行间隔 void(*TaskHook)(void);//要运行的任务函数 }TASK_COMPONENTS;//任务定义 这个结构体的设计非常重要。
每个使用 4 个参数。
评论很详细,这里不再赘述。
2。
当任务运行标志显示时,该函数相当于中断服务函数。
该函数需要在定时器的中断服务函数中调用。
这里是独立的,可以移植、可以理解。
Code: voidTaskRemarks(void) { uint8i; for(i=0;i//任务时间一一处理 { if(TaskComps[ i] .Timer)//时间不为0 { TaskComps[i].Timer--;//减一拍 if(TaskComps[i].Timer==0)//时间减少 Done { TaskComps[i].Timer=TaskComps[i].ItvTime;//恢复定时器值并重新开始 TaskComps[i].Run=1;//任务可以运行了 } } } } 我们仔细对比一下下一个函数,看看是不是和上面的一样上面的定时复用函数又是什么呢? ? 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},//显示工作状态 //在此添加您的任务。
; 定义变量时,我们已经初始化了值。
这些值的初始化非常重要,与具体的执行时间优先级有关。
这个需要自己掌握。
① 大致意思是我们有三个。
版权声明:本文内容由互联网用户自发贡献,本站不拥有所有权,不承担相关法律责任。如果发现本站有涉嫌抄袭的内容,欢迎发送邮件 举报,并提供相关证据,一经查实,本站将立刻删除涉嫌侵权内容。
标签:
相关文章
06-18
06-17
06-18
最新文章
使用电子管有哪些注意事项?如何检查电子管之间是否短路?
博通支付1200万美元和解SEC财务欺诈指控
八名运营商高管确认加入虚拟运营商
内蒙古农牧区雷电灾害成因分析及防雷对策
北京联通将5G应用于世园会远程医疗急救
TD-SCDMA最后一轮冲刺测试启动,产业前景更加光明
专访阿里云总裁王健:云计算服务平台梦想成真
USB2.0控制器CY7C68013的接口设计与实现