1
完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
因为我常用的是stm32F4系列单片机,所以采用其滴答定时器作为时基定时器(如果你使用的单片机是别款,只要单片机上有个定时器都可以,另外也得有中断处理函数)(另外如果用的是stm32等单片机,片上具有滴答定时器,可以省掉1、2步骤,在HAL库下直接用HAL_GetTick()代替GetCount()即可,其他类似) 1.首先初始化定时器,本人一般设置定时时间为1ms,这个可以是具体情况而定。 2.定义一个全局变量,假设命名为Count,并初始化为0;然后再定时器相关的中断处理函数中进行Count++。 static long long Count = 0; //定时器初始化,并设定定时时间和中断使能 void TimInit(){ ... } //其相关的中断处理函数 void InterHandle(void){ .... Count ++; } //防止外界修改Count long long GetCount(void){ return Count; } 3.在相关的头文件里定义俩个宏,第一行代码中的(num)表示任务上一次的运行时刻,然后通过全局的时钟数减去上一次的运行时刻,再与设定好的时间(ms)进行比较,如果大于等于则表示时间已到可以进行此任务,否则不能进行。当可以进行该任务时,会有num=GetCount()的动作,表示得到当前时间,方便下次判断下次进此任务。举个例子:现在12点整,定个明天12点整的闹钟,每天循环,然后它会显示还有24个小时,然后等它到每天12点就响,也就是进闹钟任务。类比就是num表示当前时间12点整,getCount()就是系统时钟,自定义ms就是那个最大间隔24个小时,然后以此循环。 #define _BEGIN(ms) static long long num = 0; if(GetCount() - num >= ms)do{ num = GetCount() #define _END() }while(0) 4.使用方式,先定义一个任务函数,千万要避免任务函数使用延时函数,不然可能会没效果的。一般一个任务的运行时间最好把控在所设置的最小时钟片内,比如我这定时为1ms,则处理每个任务所花的时间应该比1ms小。如果是在stm32上基本不用过多担心这个问题,只要不是跑什么耗时通信协议就好。那如果是在51上的话,那个最小时钟片还是定大一点比较稳,毕竟51的性能相对32而言是比较低的。 void Task1(void){ _BEGIN(100); //doSomeing LED1 = ~LED1;//比如让小灯1每隔100ms闪一下 _END(); } void Task2(void){ _BEGIN(150); //doSomeing LED2 = ~LED2;//比如让小灯2每隔150ms闪一下 _END(); } 5.在主函数的while(1){}里调用任务函数便可简单的实现多任务了 6.总结,由于整体比较简单,自然就会有很多缺点了,比如在一个任务函数里面不能够再次延时和如果在某个任务太占时间会影响其它任务等,还得改进,不过这个已经适用很多情景了。如果处理的任务太过复杂,就可以考虑上os了。 |
|
|
|
只有小组成员才能发言,加入小组>>
3310 浏览 9 评论
2991 浏览 16 评论
3492 浏览 1 评论
9057 浏览 16 评论
4086 浏览 18 评论
1176浏览 3评论
604浏览 2评论
const uint16_t Tab[10]={0}; const uint16_t *p; p = Tab;//报错是怎么回事?
597浏览 2评论
用NUC131单片机UART3作为打印口,但printf没有输出东西是什么原因?
2334浏览 2评论
NUC980DK61YC启动随机性出现Err-DDR是为什么?
1895浏览 2评论
小黑屋| 手机版| Archiver| 德赢Vwin官网 ( 湘ICP备2023018690号 )
GMT+8, 2024-12-22 18:11 , Processed in 1.278289 second(s), Total 80, Slave 61 queries .
Powered by 德赢Vwin官网 网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
德赢Vwin官网 观察
版权所有 © 湖南华秋数字科技有限公司
德赢Vwin官网 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号