蓝蓝的恋 发表于 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
查看完整版本: 再出个调度器,极小资源单片机值得一用