蓝蓝的恋
发表于 2014-4-14 14:55:14
smset 发表于 2014-4-8 13:37
是啊,在任务函数里面就是要通过WaitX才释放cpu资源。
这也是非抢占式任务调度的特点。
{:smile:} 高端啊~~{:tongue:}
lts
发表于 2014-4-15 08:41:22
你好,小小调度器能用在stm32上吗?用sysstick时钟。我的是小项目,不想用ucos。如果移植过去,我会发源码跟帖。请指导
smset
发表于 2014-4-15 12:33:57
lts 发表于 2014-4-15 08:41
你好,小小调度器能用在stm32上吗?用sysstick时钟。我的是小项目,不想用ucos。如果移植过去,我会发源码 ...
可以的,小小调度器的特点就是极高的可移植性,和极少的移植工作量。
277955973
发表于 2014-4-15 12:46:38
mark。。。。。。。。。。。
young_fly
发表于 2014-4-15 15:20:38
mark
lxm
发表于 2014-4-15 15:21:49
谢谢…………。
haso2007
发表于 2014-4-16 14:10:52
mark,热贴还是要好好学学。
zjk
发表于 2014-4-18 09:52:13
mark,标记
kevinliu_wei
发表于 2014-4-18 11:21:20
顶一下
小黑鱼1148
发表于 2014-4-18 12:19:03
mark,好帖,值得学习!
lswhome
发表于 2014-4-19 03:32:35
大神。。。膜拜!!!
湛泸骏驰
发表于 2014-4-19 10:14:28
mark {:lol:}{:lol:}
liuqian
发表于 2014-4-19 18:48:23
walle531 发表于 2014-4-1 14:20
我想知道当任务挂起后,下次重新恢复任务的时候怎么搞才能从新开始运行任务,而不是从上次退出的地方继续运 ...
加一个宏
#define _TASK_RESET(ticks) {_lc=0;return ticks;}
_TASK_RESET(100/TICK_RATE_MS) ;
任务完成退出,100ms后从开始运行
tianyiran02
发表于 2014-4-21 05:41:09
LZ你好!!相当感谢你的分享精神!!!学习了一晚上你的793楼的代码,有几个疑问想请问下LZ。
1. 如下面所列代码,是否可以理解为在demo中,task1和task2分别1s,2s执行一次;
2. 根据我的理解,调度器不会判定一个用户代码是否锁死,或者超时。在执行完一个用户任务之前,其他任务是不会被执行的 (除了中断内的高优先任务);
3. 根据我的理解,调度器在task中用所定义宏 CallSub调用子任务时(如在task1中调用task2),系统的机理是首先终止task1,在task1的下一个时间片到来时再运行task2.
学习中多有不懂。查了很多资料了。不知道自己理解的程序和您的是否一致。还望大神指教了。。。
unsigned chartask1(){
_SS
while(1){
WaitX(100);
LED1=!LED1;
}
_EE
}
unsigned chartask2(){
_SS
while(1){
WaitX(100);
LED2=!LED2;
}
_EE
}
943941946
发表于 2014-4-21 09:14:49
收藏了,顶
smset
发表于 2014-4-21 10:06:24
tianyiran02 发表于 2014-4-21 05:41
LZ你好!!相当感谢你的分享精神!!!学习了一晚上你的793楼的代码,有几个疑问想请问下LZ。
1. 如下面所 ...
从宏观上看,所有顶层task都在并行执行,只有微观上才有先后等待的概念。
因此以下三个方面的问题,都是出在这个概念上的问题:
1. 如下面所列代码,是否可以理解为在demo中,task1和task2分别1s,2s执行一次;
task1和task2是并行执行的。 并非是task1在前1秒执行,然后task2在后一秒执行。
2. 根据我的理解,调度器不会判定一个用户代码是否锁死,或者超时。在执行完一个用户任务之前,其他任务是不会被执行的 (除了中断内的高优先任务);
所有顶级任务都是并行执行的。 执行task1时,task2,task3.......同时都在执行。
3. 根据我的理解,调度器在task中用所定义宏 CallSub调用子任务时(如在task1中调用task2),系统的机理是首先终止task1,在task1的下一个时间片到来时再运行task2.
在task1中调用task2,系统的机理是先挂起task1(而不是终止),在task1的下一个时间片到来时再运行task2,然后等task2执行完毕后,再继续执行task1.
关于以后
发表于 2014-4-21 11:24:49
真是一个好贴啊!!顶起。
pnsyzx20088hlq
发表于 2014-4-22 16:58:49
谢谢楼主分享!
3htech
发表于 2014-4-24 11:17:28
Mark一下。需要仔细学习一下。
ypengfei
发表于 2014-4-24 12:02:06
smset 发表于 2014-4-21 10:06
从宏观上看,所有顶层task都在并行执行,只有微观上才有先后等待的概念。
楼主,可否写个中文教程,针对调度器的,我等新手真心看不懂,捉急啊!!!!!
yanglei920509
发表于 2014-4-24 12:34:04
果断顶啊
dong889
发表于 2014-4-24 12:47:15
MARK 好贴学习!
smset
发表于 2014-4-24 13:37:11
ypengfei 发表于 2014-4-24 12:02
楼主,可否写个中文教程,针对调度器的,我等新手真心看不懂,捉急啊!!!!! ...
{:lol:}顶到1000楼,就写详细的中文教程。{:lol:}
ypengfei
发表于 2014-4-24 14:08:41
smset 发表于 2014-4-24 13:37
顶到1000楼,就写详细的中文教程。
面对对知识的渴望,就不要再折磨我们了,快点吧!
lovepig200
发表于 2014-4-24 14:25:46
把楼主 793楼 移植到stm8l152c6上 好用的 IAR的,呵呵
代码打包奉上。
szpspike
发表于 2014-4-24 14:51:56
顶顶更健康
smset
发表于 2014-4-24 17:03:55
本帖最后由 smset 于 2014-4-24 17:08 编辑
lianglee 发表于 2014-4-24 14:59
做个最简单的任务,
一个按键,LED输出.
示意代码(统一按20ms去抖的):
unsgined char SubTask1
{
_SS
LED=0; //关闭LED
WaitX(10);
LED=1; //打开LED
WaitX(10);
LED=0; //关闭LED
WaitX(20);
LED=1; //打开LED
WaitX(20);
LED=0; //关闭LED
WaitX(30);
LED=1; //打开LED
WaitX(30);
LED=0; //关闭LED
WaitX(40);
LED=1; //打开LED
WaitX(40);
LED=0; //关闭LED
WaitX(50);
LED=1; //打开LED
WaitX(50);
LED=0; //关闭LED
WaitX(100);
LED=1; //打开LED
WaitX(100);
LED=0;
_EE
}
unsgined char Task1
{
static unsigned char i;
_SS
while(1){
LED=0; //关闭LED
while(KEY) WaitX(0);
LED=1; //打开LED
WaitX(2);//20ms 按键去抖
while(!KEY) WaitX(0);
CallSub(SubTask1);
for (i=0;i<5;i++){
while(KEY) WaitX(0);
WaitX(2);//20ms按键去抖
while(!KEY) WaitX(0);
WaitX(2);//20ms按键去抖
}
}
_EE
}
yylwt
发表于 2014-4-24 19:28:38
记号,学习一下
jasongwq
发表于 2014-4-26 15:42:53
支持 楼主
zyp000
发表于 2014-4-27 13:25:58
Mark。。。自虐啊~~。。。。。
zengyunming
发表于 2014-4-27 14:56:33
学习了,貌似对伪线程,状态机不是很理解。
wildcat7261
发表于 2014-4-27 15:08:26
收藏
关于以后
发表于 2014-4-28 19:48:54
真是获益匪浅。。
g527727372
发表于 2014-4-28 20:53:53
楼主加油!过来学习!
269287142
发表于 2014-4-28 21:06:03
学习了 谢谢
fulitun
发表于 2014-4-28 21:17:57
学习!加一楼
lts
发表于 2014-4-29 20:27:54
到1000出教程,太好了
hejiang177
发表于 2014-5-1 20:53:49
小单片机用挺好,不过不知稳定性如何,限制一些switch和return不知道有不有影响开发
rhyme
发表于 2014-5-6 21:09:09
我移植到STM32F030上面出了点小问题,就是简单在task0()里面闪灯,但是在这之前发现程序需要3到4秒以后才开始执行闪灯的程序,前面的时间不知道是什么情况。求楼主解答。
smset
发表于 2014-5-7 08:37:18
rhyme 发表于 2014-5-6 21:09
我移植到STM32F030上面出了点小问题,就是简单在task0()里面闪灯,但是在这之前发现程序需要3到4秒以后才开 ...
你把整个代码贴出来看看。
mdcao
发表于 2014-5-8 22:01:17
关注一下,有可能用到呢!
mdcao
发表于 2014-5-8 22:01:35
关注一下,有可能用到呢!
mdcao
发表于 2014-5-8 22:02:31
关注一下,有可能用到呢!
mdcao
发表于 2014-5-8 22:06:06
关注一下,有可能用到呢!
mdcao
发表于 2014-5-8 22:07:56
日,不好意思,电脑卡了,我使劲点击几下,让后,,,,抱歉{:dizzy:}
blavy
发表于 2014-5-8 22:45:31
学习先,当资料用
lyny
发表于 2014-5-10 11:05:44
顶到1000,楼主出教程吧
cnshibo
发表于 2014-5-10 11:17:21
其实可以考虑移植qpn,成熟方便。
lyny
发表于 2014-5-10 15:27:10
楼主,什么情况下程序会运行_EE里的_lc=0;return 255;这两句呢
smset
发表于 2014-5-10 15:37:45
lyny 发表于 2014-5-10 15:27
楼主,什么情况下程序会运行_EE里的_lc=0;return 255;这两句呢
当一个任务不是永远循环执行时,就会执行到_EE处。
一个任务可以永远循环执行,比如任务函数里有while(1){....},也可以只执行一次或数次。
smset
发表于 2014-5-10 15:43:56
本帖最后由 smset 于 2014-5-10 15:45 编辑
cnshibo 发表于 2014-5-10 11:17
其实可以考虑移植qpn,成熟方便。
一个系统由多个任务组成
一个任务由多个状态组成
小小调度器的策略是: 没有状态,只有任务 {:smile:}
lyny
发表于 2014-5-10 16:01:42
smset 发表于 2014-5-10 15:37
当一个任务不是永远循环执行时,就会执行到_EE处。
一个任务可以永远循环执行,比如任务函数里有while(1 ...
谢谢,理解了。回头试一试,不过感觉程序运行方式还是像时间片轮询一样,可能我还没领会到其中精妙之处。
liuchengliaaa
发表于 2014-5-10 20:01:52
入门中,不是很懂
留个爪印
感谢lz
funnybow
发表于 2014-5-10 20:52:00
顶啊,早点顶到1000楼,让楼主出教程
minier
发表于 2014-5-10 21:01:09
又升级了!!看看先
gz_dailin
发表于 2014-5-10 21:26:29
mark..........
wangyj173
发表于 2014-5-10 21:43:14
贡献一楼,添砖加瓦,已用的LZ的这个调度器一年多了,没发现啥问题,当然,也就用它做简单任务调度
micintcnh
发表于 2014-5-11 00:01:34
谢谢已收藏!
funnybow
发表于 2014-5-12 00:04:39
继续顶一下
fgdzypf
发表于 2014-5-12 10:08:29
支持楼主,好东西呀
vvi
发表于 2014-5-12 12:31:48
顶到1000楼
funnybow
发表于 2014-5-12 12:33:45
再加一楼
funnybow
发表于 2014-5-12 12:34:02
再加一楼
melodyoooo
发表于 2014-5-12 16:30:07
这个必须顶
蓝蓝的恋
发表于 2014-5-14 09:47:53
还差一百多楼呢,兄弟们加油啊~
wjjcyy
发表于 2014-5-14 10:51:32
留下了,有项目的时候试试。
rhyme
发表于 2014-5-15 19:24:31
smset 发表于 2014-5-7 08:37
你把整个代码贴出来看看。
已经解决,谢谢!
ppdd
发表于 2014-5-15 22:51:38
这个必须要顶! 顶完了,慢慢看!
ppdd
发表于 2014-5-15 22:57:44
宏替换后的, c 文件能查看到吗? keil C51
ppdd
发表于 2014-5-19 19:24:12
c 功力不行啊,期待楼主出更详细的应用指导!
mdcao
发表于 2014-5-19 21:54:06
再顶顶,楼主出教程吧, 把任务函数编写的注意事项详细写写呗(大概看了下,还不会运用到案子中),在多举些例,{:biggrin:}
SNOOKER
发表于 2014-5-19 22:08:53
记号一下,有空研究一下
ppdd
发表于 2014-5-20 09:55:05
再顶顶! 宏这个东西啊,慢慢看出了点问道! 是个好东西.
gtzhangzr
发表于 2014-5-20 12:16:03
{:lol:}头文件{:lol:}{:lol:},顶一千楼
#ifndef __SCHEDULE_H
#define __SCHEDULE_H
/* Includes *******************************************************************/
#include <stdint.h>
#include <stdbool.h>
/* Macros *********************************************************************/
#define SCH_TICK_TIME 100
#define SCH_MAX_TICK 0xFFFF
#define SCH_MAX_TASK 16
/* Types **********************************************************************/
typedef uint16_t SCH_TICK_t;
typedef uint16_t SCH_SEMAPHORE_t;
/* Variables ******************************************************************/
extern volatile SCH_TICK_t SCH_TaskTicks;
/* Schedule *******************************************************************/
#define SCH_TASK_BEGIN() \
static uint8_t _lc = 0;\
switch (_lc)\
{\
default:
#define SCH_TASK_END() \
;\
};\
_lc = 0;\
return SCH_MAX_TICK
#define SCH_DELAY(ticks) \
do\
{\
_lc = (__LINE__ + ((__LINE__ % 256) == 0)) % 256;\
return ticks;\
} while (false);\
case (__LINE__ + ((__LINE__ % 256 )== 0)) % 256:
#define SCH_RUN_TASK(task, id) \
do\
{\
SCH_TICK_t tick;\
do\
{\
tick = SCH_TaskTicks;\
} while (tick != SCH_TaskTicks);\
if (tick == 0)\
{\
SCH_TaskTicks = task();\
}\
} while (false)
#define SCH_RUN_TASK_CONT(task, id) \
{\
SCH_TICK_t tick;\
do\
{\
tick = SCH_TaskTicks;\
} while (tick != SCH_TaskTicks);\
if (tick == 0)\
{\
SCH_TaskTicks = task();\
continue;\
}\
}
#define SCH_CALL_SUB_TASK(subtask) \
do\
{\
SCH_TICK_t currdt;\
_lc = (__LINE__ + ((__LINE__ % 256) == 0)) % 256;\
return 0;\
case (__LINE__ + ((__LINE__ % 256 )== 0)) % 256:\
currdt = subtask();\
if (currdt != SCH_MAX_TICK)\
{\
return currdt;\
}\
} while(false)
#define SCH_INIT() \
{\
uint8_t i;\
for (i = SCH_MAX_TASK; i > 0; i--)\
{\
SCH_TaskTicks = 0;\
}\
}
#define SCH_UPDATE_TICKS() \
{\
uint8_t i;\
for (i = SCH_MAX_TASK; i > 0; i--)\
{\
if ((SCH_TaskTicks != 0) && \
(SCH_TaskTicks != SCH_MAX_TICK))\
{\
SCH_TaskTicks--;\
}\
}\
}
/* Semaphore ******************************************************************/
#define SCH_SEMAPHORE_INIT(sem) sem = 0
#define SCH_SEMAPHORE_WAIT(sem) \
do\
{\
sem = 1;\
SCH_DELAY(0);\
if (sem > 0)\
{\
return 1;\
}\
} while (false)
#define SCH_SEMAPHORE_WAIT_TICK(sem, tick) \
do\
{\
sem = tick + 1;\
SCH_DELAY(0);\
if (sem > 1)\
{\
sem--;\
return 1;\
}\
} while (false)
#define SCH_SEMAPHORE_SEND(sem) \
do\
{\
sem = 0;\
} while (false)
#endif
ppdd
发表于 2014-5-20 13:29:50
这个宏 格式好看多了.不在同一行了,但是好像smset强调要在同一行的哦.
hejiang177
发表于 2014-5-20 16:45:38
smset 发表于 2012-12-18 18:29
优化无止境!呵呵,330楼看似不能再优化了,但我再尝试做一次优化:
敬请评测该版本,看是否还能优化:在k ...
LZ V5改天整来好生测试下,在不想用RTOS的地方很有用
ppdd
发表于 2014-5-21 15:49:14
unsigned chartask1()
{
//_SS
static unsigned char _lc=0;
switch(_lc)
{
default:
while(1)
{
do
{
_lc=(__LINE__+((__LINE__%256)==0))%256;
return 100 ;
} while(0);
case (__LINE__+((__LINE__%256)==0))%256:
//WaitX(100);
LED1=!LED1;
}
;///
};
_lc=0;
return 255;
//_EE
}
ppdd
发表于 2014-5-21 15:53:18
attach://192959.png
这个是对应的汇编文件。
C:0x010A 24B8 ADD A,#IP(0xB8) 这句看不懂.请高手指点!
ppdd
发表于 2014-5-21 16:04:45
task1:
C:0x0108 E511 MOV A,0x11 //给_lc变量分配地址0x11,_lc内容传给A
C:0x010A 24B8 ADD A,#IP(0xB8)//这里没有看懂?????
C:0x010C 6008 JZ C:0116 //A的内容为零,跳0x0116
C:0x010E 8000 SJMP C:0110 //A的值不为零跳0x0110
C:0x0110 751145 MOV 0x11,#0x45//????这句也没看懂
C:0x0113 7F64 MOV R7,#0x64//return 100(0x64)
C:0x0115 22 RET //是由于return
C:0x0116 B2A1 CPL LED1(0xA0.1)//位取反
C:0x0118 80F6 SJMP C:0110 //又跳到0x0110,并return
ppdd
发表于 2014-5-21 16:17:48
_lc=(__LINE__+((__LINE__%256)==0))%256;
这样写有什么特别意义呢?
dlmaowf
发表于 2014-5-21 16:58:49
添砖,顶到1000楼,期待教程
ppdd
发表于 2014-5-21 17:57:02
对,顶到楼主出来为止!!
ppdd
发表于 2014-5-21 19:00:49
switch(const9)
{
default: ;;//default可以放在switch大括号里的任意位置??????
while(1)
{
case: ;;//case 甚至可以放在,一个循环里面啊?????
}
}
switch总是先去,比较case,不管他在那里啊????是不是这样啊!!
ppdd
发表于 2014-5-22 16:22:33
展开成这样,功能正常,三个LED,闪动!。
unsigned chartask1()
{
//_SS
//*/
static unsigned char _lc=0;
switch(_lc)
{
default:
//*/
//_SS
while(1)
{
//WaitX(100);
//*/
do{ _lc=__LINE__; return 50 ;} while(0); case (__LINE__):
//*/
//WaitX(100);
LED1=!LED1;
}
//_EE
;
}
_lc=0;
return 255;
//_EE
}
ppdd
发表于 2014-5-22 16:27:50
1.这样写不行!!!
static unsigned char _lc; _lc=0;
2.分两行也不行!!!???
do{ _lc=__LINE__; return 50 ;} while(0);
case (__LINE__):
不得其门而入啊! 各位看懂的给点意见啊!!
3. 结束部分,分成多行,一句一行,程序运行正常。
//_EE
22. ;
23. }
24. _lc=0;
25. return 255;
26. //_EE
这是为什么呀!!!!
ppdd
发表于 2014-5-22 16:45:02
do{
_lc=__LINE__; return 50 ;} while(0); case (__LINE__):
这样写也可以啊!!!
终于明白了!啊,是这样的: switch(_lc)其中_lc取得行号(C编译环境下),就是case (__LINE__),这两个必须是一样的. 也就是说: _lc=__LINE__和Case(__LINE__)必须在同一行.这样才能switch到这个case.
ppdd
发表于 2014-5-22 17:24:41
_lc=(__LINE__+((__LINE__%256)==0))%256;
这样写法没看明白啊???
ppdd
发表于 2014-5-22 18:09:22
1.这样写不行!!!(问题解决!!)
static unsigned char _lc; _lc=0;
这个问题,大概知道了;反汇编后,分开写,每次进入任务都会对_lc赋值,不能保留waitX()取得数值.
可能的原因是,C语言静态变量初始化,只能使用连写的方式吧!有知道来由的,说说!!(本人C语言菜鸟,自学中...有能解答类似问题的书籍也希望朋友推荐下,先谢谢啦!)
ppdd
发表于 2014-5-22 18:32:21
看过了,汇编代码. 越看越觉得变态,太变态了! 不得不佩服啊,太变态了!!不过,也有点过瘾!
ppdd
发表于 2014-5-23 00:23:17
本帖最后由 ppdd 于 2014-5-23 00:29 编辑
汇报汇报,基本看懂TASK1执行过程。 个人理解如下:
unsigned chartask1() //基本看懂TASK,执行过程
{
//_SS
static unsigned char _lc=0;//静态变量初始化为零,默认也为零
switch(_lc) //此处汇编(_lc+256-(do的行号,也是_lc的值))
{ //然后判断Acc为零,进行跳转
default: //default: 可放在switch内任意位置
//_SS //switch首先寻找case,并对比判断。
while(1)//第一次进任务,_lc==0,执行default语句,正和吾意
{
//WaitX(100);//首次执行,设置好_lc值,返回延时心跳数
//*///当然本例,每次都循环返回心跳数。
do{ _lc=__LINE__; return 100 ;} while(0); case (__LINE__)://case 可以在switch内部的任意位置,甚至一个while循环内部,天哪!!C也太灵活了吧!!
//*/
//WaitX(100);//二次进入,直接跳转do行+1的位置执行。
LED1=!LED1; //由于while(1)的影响,程序仍然由return 100出。
}
//_EE //由于while(1)的影响,程序_EE段未执行。
; //Keil ,太牛逼了;竟然直接无视,不进行汇编
}
_lc=0;
return 255;
//_EE
}
努力顶到1000楼!
ppdd
发表于 2014-5-23 00:38:56
对应的汇编,关键点。程序已经验证,功能正常。
wugang_1213
发表于 2014-5-27 21:18:25
顶到 900楼! 我又看了一遍!{:lol:}
cinple
发表于 2014-5-27 21:56:17
支持分享!楼主加油!
bigwei
发表于 2014-5-28 23:47:10
感谢分享,下载学习。
rootxie
发表于 2014-5-29 09:01:07
如果有一个线程要持续运行几秒的时间,怎么破?是不是只能用抢占了?
(比如说采样10S,运算持续3秒)
firstzys
发表于 2014-5-29 09:41:34
介于OS和裸机之间的一种选择呗
fgdzypf
发表于 2014-5-29 10:14:42
在加一楼{:smile:}
ppdd
发表于 2014-5-29 10:34:53
按照模板,做了个呼吸灯,已经可以正常运行,时基=1ms!
#include <STC12C5A60S2.h>
#include "PTSchedul.h"
sbit LED0 = P1^0;
sbit LED1 = P2^5;
sbit LED2 = P2^7;
sbit LED3 = P1^7;
unsigned char LED_PWM=0;
unsigned char task0()
{
_SS
while(1)
{
WaitX(500);
//LED0=!LED0;
}
_EE
}
unsigned chartask1()
{
_SS
while(1)
{
WaitX(100);
LED1=!LED1;
}
_EE
}
unsigned chartask2()
{
_SS
while(1)
{
WaitX(10);
LED2=!LED2;
}
_EE
}
unsigned char tsk4_led_drv()
{
_SS
while(1)
{
LED0=0;
WaitX(LED_PWM);
LED0=1;
WaitX(20-LED_PWM);
}
_EE
}
unsigned char tsk3_breathe_led() //50ms执行一次 20HZ
{
static unsigned chari,bLighting=1,bDarking;
_SS
while(1)
{
if(bLighting)
{
for(i=1;i<21;i++)
{ WaitX(50);
LED_PWM++;
if(LED_PWM==20){bLighting=0;bDarking=1;}
}
}
if(bDarking)
{
for(i=1;i<21;i++)
{ WaitX(50);
if(LED_PWM==0){bLighting=1;bDarking=0;}
LED_PWM--;
if(LED_PWM==0){bLighting=1;bDarking=0;}
}
}
}
_EE
}
void InitT0()
{
TMOD = 0x21; //GATE1 C/T1M1_1M1_0GATE0 C/T0M0_1M0_0 0000,0000
IE |= 0x82;// 12t
TL0=0X66; //1MS 11.0592Mhz
TH0=0XFC;
TR0 = 1;
}
void Timer0Init(void) //10毫秒@11.0592MHz
{
AUXR &= 0x7F; //定时器时钟12T模式
TMOD &= 0xF0; //设置定时器模式
TMOD |= 0x01; //设置定时器模式
TL0 = 0x00; //设置定时初值
TH0 = 0xDC; //设置定时初值
TF0 = 0; //清除TF0标志
TR0 = 1; //定时器0开始计时
}
void INTT0(void) interrupt 1 using 1
{
TL0=0X66; //1ms 重装
TH0=0XFC;
UpdateTimers();
RunTask(task0,0);//任务0具有精确按时获得执行的权限,要求:task0每次执行消耗时间<0.5个 ticket
}
void main()
{
InitT0();
InitTasks(); //初始化任务,实际上是给timers清零
while(1)
{
//RunTask(task0,0);
RunTask(task1,3);//任务1具有比任务2高的运行权限
RunTask(task2,4);//任务2具有低的运行权限
RunTask(tsk4_led_drv,1);
RunTask(tsk3_breathe_led,2);
}
}
ppdd
发表于 2014-5-29 18:05:52
P1口输出8种 不同的占空比的驱动,怎么写? 一定要给PIN脚对应一个驱动任务吗?
象这样:
unsigned char _led1_drv() //阻塞时间可变
{
_SS
while(1)
{
LED1=0;
WaitX(LED1_PWM);
LED1=1;
WaitX(20-LED1_PWM);
}
_EE
}
ppdd
发表于 2014-5-29 18:12:21
本帖最后由 ppdd 于 2014-5-29 18:14 编辑
楼主出来看看啊!! 打算做个流星灯,水滴效果的。
页:
1
2
3
4
5
6
7
8
[9]
10
11
12
13