搜索
bottom↓
楼主: smset

再出个调度器,极小资源单片机值得一用

  [复制链接]

出0入8汤圆

发表于 2014-4-14 14:55:14 | 显示全部楼层
smset 发表于 2014-4-8 13:37
是啊,在任务函数里面就是要通过WaitX才释放cpu资源。

这也是非抢占式任务调度的特点。

高端啊~~

出0入0汤圆

发表于 2014-4-15 08:41:22 | 显示全部楼层
你好,小小调度器能用在stm32上吗?用sysstick时钟。我的是小项目,不想用ucos。如果移植过去,我会发源码跟帖。请指导

出0入0汤圆

 楼主| 发表于 2014-4-15 12:33:57 | 显示全部楼层
lts 发表于 2014-4-15 08:41
你好,小小调度器能用在stm32上吗?用sysstick时钟。我的是小项目,不想用ucos。如果移植过去,我会发源码 ...


可以的,小小调度器的特点就是极高的可移植性,和极少的移植工作量。

出0入0汤圆

发表于 2014-4-15 12:46:38 | 显示全部楼层
mark。。。。。。。。。。。

出0入0汤圆

发表于 2014-4-15 15:20:38 | 显示全部楼层
   mark  

出0入0汤圆

发表于 2014-4-15 15:21:49 | 显示全部楼层
谢谢…………。

出0入0汤圆

发表于 2014-4-16 14:10:52 | 显示全部楼层
mark,热贴还是要好好学学。

出0入0汤圆

发表于 2014-4-18 09:52:13 | 显示全部楼层
mark,标记

出0入0汤圆

发表于 2014-4-18 11:21:20 | 显示全部楼层
顶一下   

出0入0汤圆

发表于 2014-4-18 12:19:03 来自手机 | 显示全部楼层
mark,好帖,值得学习!

出0入0汤圆

发表于 2014-4-19 03:32:35 | 显示全部楼层
大神。。。膜拜!!!

出0入0汤圆

发表于 2014-4-19 10:14:28 | 显示全部楼层
mark

出0入4汤圆

发表于 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后从开始运行

出0入0汤圆

发表于 2014-4-21 05:41:09 | 显示全部楼层
LZ你好!!相当感谢你的分享精神!!!学习了一晚上你的793楼的代码,有几个疑问想请问下LZ。

1. 如下面所列代码,是否可以理解为在demo中,task1和task2分别1s,2s执行一次;
2. 根据我的理解,调度器不会判定一个用户代码是否锁死,或者超时。在执行完一个用户任务之前,其他任务是不会被执行的 (除了中断内的高优先任务);
3. 根据我的理解,调度器在task中用所定义宏 CallSub调用子任务时(如在task1中调用task2),系统的机理是首先终止task1,在task1的下一个时间片到来时再运行task2.

学习中多有不懂。查了很多资料了。不知道自己理解的程序和您的是否一致。还望大神指教了。。。


  1. unsigned char  task1(){
  2. _SS
  3.   while(1){
  4.    WaitX(100);
  5.    LED1=!LED1;   
  6.   }
  7. _EE
  8. }

  9. unsigned char  task2(){
  10. _SS
  11.   while(1){
  12.    WaitX(100);
  13.    LED2=!LED2;   
  14.   }
  15. _EE
  16. }
复制代码

出0入0汤圆

发表于 2014-4-21 09:14:49 来自手机 | 显示全部楼层
收藏了,顶

出0入0汤圆

 楼主| 发表于 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.


出0入0汤圆

发表于 2014-4-21 11:24:49 | 显示全部楼层
真是一个好贴啊!!顶起。

出0入0汤圆

发表于 2014-4-22 16:58:49 | 显示全部楼层
谢谢楼主分享!

出0入0汤圆

发表于 2014-4-24 11:17:28 | 显示全部楼层
Mark一下。需要仔细学习一下。

出0入0汤圆

发表于 2014-4-24 12:02:06 | 显示全部楼层
smset 发表于 2014-4-21 10:06
从宏观上看,所有顶层task都在并行执行,只有微观上才有先后等待的概念。

楼主,可否写个中文教程,针对调度器的,我等新手真心看不懂,捉急啊!!!!!

出0入0汤圆

发表于 2014-4-24 12:34:04 | 显示全部楼层
果断顶啊

出100入0汤圆

发表于 2014-4-24 12:47:15 | 显示全部楼层
MARK 好贴学习!   

出0入0汤圆

 楼主| 发表于 2014-4-24 13:37:11 | 显示全部楼层
ypengfei 发表于 2014-4-24 12:02
楼主,可否写个中文教程,针对调度器的,我等新手真心看不懂,捉急啊!!!!! ...

  顶到1000楼,就写详细的中文教程。

出0入0汤圆

发表于 2014-4-24 14:08:41 | 显示全部楼层
smset 发表于 2014-4-24 13:37
顶到1000楼,就写详细的中文教程。

面对对知识的渴望,就不要再折磨我们了,快点吧!

出0入0汤圆

发表于 2014-4-24 14:25:46 | 显示全部楼层
把楼主 793楼 移植到stm8l152c6上 好用的 IAR的,呵呵
代码打包奉上。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x

出0入4汤圆

发表于 2014-4-24 14:51:56 | 显示全部楼层
顶顶更健康

出0入0汤圆

 楼主| 发表于 2014-4-24 17:03:55 | 显示全部楼层
本帖最后由 smset 于 2014-4-24 17:08 编辑
lianglee 发表于 2014-4-24 14:59
做个最简单的任务,

一个按键,LED输出.


示意代码(统一按20ms去抖的):


  1. unsgined char SubTask1
  2. {
  3. _SS

  4.   LED=0; //关闭LED
  5.   WaitX(10);
  6.   LED=1; //打开LED
  7.   WaitX(10);

  8.   LED=0; //关闭LED
  9.   WaitX(20);
  10.   LED=1; //打开LED
  11.   WaitX(20);

  12.   LED=0; //关闭LED
  13.   WaitX(30);
  14.   LED=1; //打开LED
  15.   WaitX(30);

  16.   LED=0; //关闭LED
  17.   WaitX(40);
  18.   LED=1; //打开LED
  19.   WaitX(40);

  20.   LED=0; //关闭LED
  21.   WaitX(50);
  22.   LED=1; //打开LED
  23.   WaitX(50);

  24.   LED=0; //关闭LED
  25.   WaitX(100);
  26.   LED=1; //打开LED
  27.   WaitX(100);

  28.   LED=0;

  29. _EE
  30. }

  31. unsgined char Task1
  32. {
  33. static unsigned char i;
  34. _SS
  35.   while(1){
  36.     LED=0; //关闭LED
  37.     while(KEY) WaitX(0);  

  38.     LED=1; //打开LED
  39.     WaitX(2);//20ms 按键去抖

  40.    while(!KEY) WaitX(0);  

  41.     CallSub(SubTask1);

  42.     for (i=0;i<5;i++){
  43.       while(KEY) WaitX(0);  
  44.       WaitX(2);//20ms按键去抖
  45.     while(!KEY) WaitX(0);  
  46.       WaitX(2);//20ms按键去抖
  47.    }
  48.   }
  49. _EE

  50. }

复制代码

出0入0汤圆

发表于 2014-4-24 19:28:38 | 显示全部楼层
记号,学习一下

出0入0汤圆

发表于 2014-4-26 15:42:53 | 显示全部楼层
支持 楼主

出0入0汤圆

发表于 2014-4-27 13:25:58 | 显示全部楼层
Mark。。。自虐啊~~。。。。。

出0入0汤圆

发表于 2014-4-27 14:56:33 | 显示全部楼层
学习了,貌似对伪线程,状态机不是很理解。

出0入0汤圆

发表于 2014-4-27 15:08:26 | 显示全部楼层
收藏                  

出0入0汤圆

发表于 2014-4-28 19:48:54 | 显示全部楼层
真是获益匪浅。。

出0入0汤圆

发表于 2014-4-28 20:53:53 | 显示全部楼层
楼主加油!过来学习!

出0入0汤圆

发表于 2014-4-28 21:06:03 | 显示全部楼层
学习了 谢谢

出0入4汤圆

发表于 2014-4-28 21:17:57 | 显示全部楼层
学习!加一楼

出0入0汤圆

发表于 2014-4-29 20:27:54 来自手机 | 显示全部楼层
到1000出教程,太好了

出0入0汤圆

发表于 2014-5-1 20:53:49 | 显示全部楼层
小单片机用挺好,不过不知稳定性如何,限制一些switch和return不知道有不有影响开发

出0入0汤圆

发表于 2014-5-6 21:09:09 | 显示全部楼层
我移植到STM32F030上面出了点小问题,就是简单在task0()里面闪灯,但是在这之前发现程序需要3到4秒以后才开始执行闪灯的程序,前面的时间不知道是什么情况。求楼主解答。

出0入0汤圆

 楼主| 发表于 2014-5-7 08:37:18 | 显示全部楼层
rhyme 发表于 2014-5-6 21:09
我移植到STM32F030上面出了点小问题,就是简单在task0()里面闪灯,但是在这之前发现程序需要3到4秒以后才开 ...

你把整个代码贴出来看看。

出0入0汤圆

发表于 2014-5-8 22:01:17 | 显示全部楼层
关注一下,有可能用到呢!

出0入0汤圆

发表于 2014-5-8 22:01:35 | 显示全部楼层
关注一下,有可能用到呢!

出0入0汤圆

发表于 2014-5-8 22:02:31 | 显示全部楼层
关注一下,有可能用到呢!

出0入0汤圆

发表于 2014-5-8 22:06:06 | 显示全部楼层
关注一下,有可能用到呢!

出0入0汤圆

发表于 2014-5-8 22:07:56 | 显示全部楼层
日,不好意思,电脑卡了,我使劲点击几下,让后,,,,抱歉

出0入0汤圆

发表于 2014-5-8 22:45:31 | 显示全部楼层
学习先,当资料用

出0入0汤圆

发表于 2014-5-10 11:05:44 | 显示全部楼层
顶到1000,楼主出教程吧

出0入4汤圆

发表于 2014-5-10 11:17:21 | 显示全部楼层
其实可以考虑移植qpn,成熟方便。

出0入0汤圆

发表于 2014-5-10 15:27:10 | 显示全部楼层
楼主,什么情况下程序会运行_EE里的_lc=0;return 255;这两句呢

出0入0汤圆

 楼主| 发表于 2014-5-10 15:37:45 | 显示全部楼层
lyny 发表于 2014-5-10 15:27
楼主,什么情况下程序会运行_EE里的_lc=0;return 255;这两句呢

当一个任务不是永远循环执行时,就会执行到_EE处。

一个任务可以永远循环执行,比如任务函数里有while(1){  ....  },  也可以只执行一次或数次。





出0入0汤圆

 楼主| 发表于 2014-5-10 15:43:56 | 显示全部楼层
本帖最后由 smset 于 2014-5-10 15:45 编辑
cnshibo 发表于 2014-5-10 11:17
其实可以考虑移植qpn,成熟方便。



一个系统由多个任务组成

一个任务由多个状态组成

小小调度器的策略是: 没有状态,只有任务

出0入0汤圆

发表于 2014-5-10 16:01:42 | 显示全部楼层
smset 发表于 2014-5-10 15:37
当一个任务不是永远循环执行时,就会执行到_EE处。

一个任务可以永远循环执行,比如任务函数里有while(1 ...

谢谢,理解了。回头试一试,不过感觉程序运行方式还是像时间片轮询一样,可能我还没领会到其中精妙之处。

出0入0汤圆

发表于 2014-5-10 20:01:52 | 显示全部楼层
入门中,不是很懂
留个爪印
感谢lz

出0入0汤圆

发表于 2014-5-10 20:52:00 来自手机 | 显示全部楼层
顶啊,早点顶到1000楼,让楼主出教程

出0入0汤圆

发表于 2014-5-10 21:01:09 | 显示全部楼层
又升级了!!看看先

出0入0汤圆

发表于 2014-5-10 21:26:29 | 显示全部楼层
mark..........

出0入0汤圆

发表于 2014-5-10 21:43:14 | 显示全部楼层
贡献一楼,添砖加瓦,已用的LZ的这个调度器一年多了,没发现啥问题,当然,也就用它做简单任务调度

出0入8汤圆

发表于 2014-5-11 00:01:34 | 显示全部楼层
谢谢已收藏!

出0入0汤圆

发表于 2014-5-12 00:04:39 | 显示全部楼层
继续顶一下

出0入0汤圆

发表于 2014-5-12 10:08:29 | 显示全部楼层
支持楼主,好东西呀

出0入0汤圆

发表于 2014-5-12 12:31:48 | 显示全部楼层
顶到1000楼

出0入0汤圆

发表于 2014-5-12 12:33:45 来自手机 | 显示全部楼层
再加一楼

出0入0汤圆

发表于 2014-5-12 12:34:02 来自手机 | 显示全部楼层
再加一楼

出0入0汤圆

发表于 2014-5-12 16:30:07 | 显示全部楼层
这个必须顶

出0入8汤圆

发表于 2014-5-14 09:47:53 | 显示全部楼层
还差一百多楼呢,兄弟们加油啊~

出0入0汤圆

发表于 2014-5-14 10:51:32 | 显示全部楼层
留下了,有项目的时候试试。

出0入0汤圆

发表于 2014-5-15 19:24:31 | 显示全部楼层
smset 发表于 2014-5-7 08:37
你把整个代码贴出来看看。

已经解决,谢谢!

出0入0汤圆

发表于 2014-5-15 22:51:38 | 显示全部楼层
这个必须要顶! 顶完了,慢慢看!

出0入0汤圆

发表于 2014-5-15 22:57:44 | 显示全部楼层
宏替换后的, c 文件能查看到吗? keil C51

出0入0汤圆

发表于 2014-5-19 19:24:12 | 显示全部楼层
c 功力不行啊,期待楼主出更详细的应用指导!

出0入0汤圆

发表于 2014-5-19 21:54:06 | 显示全部楼层
再顶顶,楼主出教程吧, 把任务函数编写的注意事项详细写写呗(大概看了下,还不会运用到案子中),在多举些例,

出0入0汤圆

发表于 2014-5-19 22:08:53 | 显示全部楼层
记号一下,有空研究一下

出0入0汤圆

发表于 2014-5-20 09:55:05 | 显示全部楼层
再顶顶! 宏这个东西啊,慢慢看出了点问道! 是个好东西.

出0入0汤圆

发表于 2014-5-20 12:16:03 | 显示全部楼层
头文件,顶一千楼

  1. #ifndef __SCHEDULE_H
  2. #define __SCHEDULE_H

  3. /* Includes *******************************************************************/
  4. #include <stdint.h>
  5. #include <stdbool.h>

  6. /* Macros *********************************************************************/
  7. #define SCH_TICK_TIME       100
  8. #define SCH_MAX_TICK        0xFFFF
  9. #define SCH_MAX_TASK        16


  10. /* Types **********************************************************************/
  11. typedef uint16_t SCH_TICK_t;
  12. typedef uint16_t SCH_SEMAPHORE_t;

  13. /* Variables ******************************************************************/
  14. extern volatile SCH_TICK_t SCH_TaskTicks[SCH_MAX_TASK];

  15. /* Schedule *******************************************************************/

  16. #define SCH_TASK_BEGIN() \
  17.            static uint8_t _lc = 0;\
  18.            switch (_lc)\
  19.            {\
  20.            default:

  21. #define SCH_TASK_END() \
  22.                ;\
  23.            };\
  24.            _lc = 0;\
  25.            return SCH_MAX_TICK

  26. #define SCH_DELAY(ticks) \
  27.            do\
  28.            {\
  29.                _lc = (__LINE__ + ((__LINE__ % 256) == 0)) % 256;\
  30.                return ticks;\
  31.            } while (false);\
  32.            case (__LINE__ + ((__LINE__ % 256 )== 0)) % 256:

  33. #define SCH_RUN_TASK(task, id) \
  34.            do\
  35.            {\
  36.                SCH_TICK_t tick;\
  37.                do\
  38.                {\
  39.                    tick = SCH_TaskTicks[id];\
  40.                } while (tick != SCH_TaskTicks[id]);\
  41.                if (tick == 0)\
  42.                {\
  43.                    SCH_TaskTicks[id] = task();\
  44.                }\
  45.            } while (false)

  46. #define SCH_RUN_TASK_CONT(task, id) \
  47.            {\
  48.                SCH_TICK_t tick;\
  49.                do\
  50.                {\
  51.                    tick = SCH_TaskTicks[id];\
  52.                } while (tick != SCH_TaskTicks[id]);\
  53.                if (tick == 0)\
  54.                {\
  55.                   SCH_TaskTicks[id] = task();\
  56.                   continue;\
  57.                }\
  58.            }

  59. #define SCH_CALL_SUB_TASK(subtask) \
  60.            do\
  61.            {\
  62.                SCH_TICK_t currdt;\
  63.                _lc = (__LINE__ + ((__LINE__ % 256) == 0)) % 256;\
  64.                return 0;\
  65.            case (__LINE__ + ((__LINE__ % 256 )== 0)) % 256:\
  66.                currdt = subtask();\
  67.                if (currdt != SCH_MAX_TICK)\
  68.                {\
  69.                    return currdt;\
  70.                }\
  71.            } while(false)

  72. #define SCH_INIT() \
  73.            {\
  74.                uint8_t i;\
  75.                for (i = SCH_MAX_TASK; i > 0; i--)\
  76.                {\
  77.                    SCH_TaskTicks[i-1] = 0;\
  78.                }\
  79.            }

  80. #define SCH_UPDATE_TICKS() \
  81.            {\
  82.                uint8_t i;\
  83.                for (i = SCH_MAX_TASK; i > 0; i--)\
  84.                {\
  85.                    if ((SCH_TaskTicks[i-1] != 0) && \
  86.                        (SCH_TaskTicks[i-1] != SCH_MAX_TICK))\
  87.                    {\
  88.                        SCH_TaskTicks[i-1]--;\
  89.                    }\
  90.                }\
  91.            }

  92. /* Semaphore ******************************************************************/

  93. #define SCH_SEMAPHORE_INIT(sem) sem = 0

  94. #define SCH_SEMAPHORE_WAIT(sem) \
  95.            do\
  96.            {\
  97.                sem = 1;\
  98.                SCH_DELAY(0);\
  99.                if (sem > 0)\
  100.                {\
  101.                    return 1;\
  102.                }\
  103.            } while (false)

  104. #define SCH_SEMAPHORE_WAIT_TICK(sem, tick) \
  105.            do\
  106.            {\
  107.                sem = tick + 1;\
  108.                SCH_DELAY(0);\
  109.                if (sem > 1)\
  110.                {\
  111.                    sem--;\
  112.                    return 1;\
  113.                }\
  114.            } while (false)

  115. #define SCH_SEMAPHORE_SEND(sem) \
  116.            do\
  117.            {\
  118.                sem = 0;\
  119.            } while (false)


  120. #endif
复制代码


出0入0汤圆

发表于 2014-5-20 13:29:50 | 显示全部楼层
这个宏 格式好看多了.  不在同一行了,但是好像smset强调要在同一行的哦.

出0入0汤圆

发表于 2014-5-20 16:45:38 | 显示全部楼层
smset 发表于 2012-12-18 18:29
优化无止境!呵呵,330楼看似不能再优化了,但我再尝试做一次优化:

敬请评测该版本,看是否还能优化:在k ...

LZ V5改天整来好生测试下,在不想用RTOS的地方很有用

出0入0汤圆

发表于 2014-5-21 15:49:14 | 显示全部楼层

  1. unsigned char  task1()
  2. {
  3.         //_SS
  4.         static unsigned char _lc=0;
  5.         switch(_lc)
  6.         {
  7.                 default:
  8.                                 while(1)
  9.                                 {
  10.                                         do
  11.                                         {
  12.                                                 _lc=(__LINE__+((__LINE__%256)==0))%256;
  13.                                                 return 100 ;
  14.                                         } while(0);
  15.                                         case (__LINE__+((__LINE__%256)==0))%256:
  16.                                            //WaitX(100);
  17.                                            LED1=!LED1;   
  18.                                   }
  19.                 ;///
  20.         };
  21.         _lc=0;
  22.         return 255;
  23.         //_EE
  24. }
复制代码

出0入0汤圆

发表于 2014-5-21 15:53:18 | 显示全部楼层
attach://192959.png
这个是对应的汇编文件。
C:0x010A    24B8     ADD      A,#IP(0xB8) 这句看不懂.请高手指点!

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x

出0入0汤圆

发表于 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

出0入0汤圆

发表于 2014-5-21 16:17:48 | 显示全部楼层
_lc=(__LINE__+((__LINE__%256)==0))%256;
这样写有什么特别意义呢?

出0入0汤圆

发表于 2014-5-21 16:58:49 | 显示全部楼层
添砖,顶到1000楼,期待教程

出0入0汤圆

发表于 2014-5-21 17:57:02 | 显示全部楼层
对,顶到楼主出来为止!!

出0入0汤圆

发表于 2014-5-21 19:00:49 | 显示全部楼层
switch(const9)
{
        default: ;;  //default  可以放在switch大括号里的任意位置??????
        while(1)
        {
                case: ;;//case 甚至可以放在,一个循环里面啊?????
        }

}
switch总是先去,比较case,不管他在那里啊????是不是这样啊!!

出0入0汤圆

发表于 2014-5-22 16:22:33 | 显示全部楼层
展开成这样,功能正常,三个LED,闪动!。

  1. unsigned char  task1()
  2. {
  3.         //_SS
  4.         //*/
  5.         static unsigned char _lc=0;
  6.         switch(_lc)
  7.         {
  8.                 default:
  9.         //*/
  10.         //_SS
  11.                 while(1)
  12.                         {
  13.                                 //WaitX(100);
  14.                                 //*/
  15.                                 do{        _lc=__LINE__; return 50 ;} while(0); case (__LINE__):
  16.                                 //*/
  17.                                 //WaitX(100);
  18.                                 LED1=!LED1;   
  19.                         }
  20.         //_EE
  21.         ;
  22.         }
  23.         _lc=0;
  24.         return 255;                                       
  25.         //_EE
  26. }

复制代码

出0入0汤圆

发表于 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

这是为什么呀!!!!





出0入0汤圆

发表于 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.

出0入0汤圆

发表于 2014-5-22 17:24:41 | 显示全部楼层
_lc=(__LINE__+((__LINE__%256)==0))%256;
这样写法没看明白啊???

出0入0汤圆

发表于 2014-5-22 18:09:22 | 显示全部楼层
1.这样写不行!!!(问题解决!!)
static unsigned char _lc; _lc=0;

这个问题,大概知道了;反汇编后,分开写,每次进入任务都会对_lc赋值,不能保留waitX()取得数值.
可能的原因是,C语言静态变量初始化,只能使用连写的方式吧!  有知道来由的,说说!!(本人C语言菜鸟,自学中...有能解答类似问题的书籍也希望朋友推荐下,先谢谢啦!)

出0入0汤圆

发表于 2014-5-22 18:32:21 | 显示全部楼层
看过了,汇编代码. 越看越觉得变态,太变态了! 不得不佩服啊,太变态了!!不过,也有点过瘾!  

出0入0汤圆

发表于 2014-5-23 00:23:17 | 显示全部楼层
本帖最后由 ppdd 于 2014-5-23 00:29 编辑

汇报汇报,基本看懂TASK1执行过程。 个人理解如下:

  1. unsigned char  task1()         //基本看懂TASK,执行过程
  2. {
  3.         //_SS
  4.         static unsigned char _lc=0;//静态变量初始化为零,默认也为零
  5.         switch(_lc) //此处汇编(_lc+256-(do的行号,也是_lc的值))
  6.         {                        //然后判断Acc为零,进行跳转
  7.         default:        //default: 可放在switch内任意位置
  8.         //_SS                //switch首先寻找case,并对比判断。
  9.                 while(1)//第一次进任务,_lc==0,执行default语句,正和吾意
  10.                 {
  11.                         //WaitX(100);//首次执行,设置好_lc值,返回延时心跳数
  12.                         //*/  //当然本例,每次都循环返回心跳数。
  13.                         do{        _lc=__LINE__; return 100 ;} while(0); case (__LINE__):  //case 可以在switch内部的任意位置,甚至一个while循环内部,天哪!!C也太灵活了吧!!
  14.                         //*/
  15.                         //WaitX(100);//二次进入,直接跳转do行+1的位置执行。
  16.                         LED1=!LED1;         //由于while(1)的影响,程序仍然由return 100出。
  17.                 }
  18.         //_EE                //由于while(1)的影响,程序_EE段未执行。
  19.         ;                    //Keil ,太牛逼了;竟然直接无视,不进行汇编
  20.         }
  21.         _lc=0;
  22.         return 255;
  23.         //_EE
  24. }

复制代码


努力顶到1000楼!

出0入0汤圆

发表于 2014-5-23 00:38:56 | 显示全部楼层

对应的汇编,关键点。程序已经验证,功能正常。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x

出0入0汤圆

发表于 2014-5-27 21:18:25 | 显示全部楼层
顶到 900楼! 我又看了一遍!

出0入0汤圆

发表于 2014-5-27 21:56:17 | 显示全部楼层
支持分享!楼主加油!

出0入0汤圆

发表于 2014-5-28 23:47:10 | 显示全部楼层
感谢分享,下载学习。

出0入0汤圆

发表于 2014-5-29 09:01:07 | 显示全部楼层
如果有一个线程要持续运行几秒的时间,怎么破?是不是只能用抢占了?
(比如说采样10S,运算持续3秒)

出0入0汤圆

发表于 2014-5-29 09:41:34 | 显示全部楼层
介于OS和裸机之间的一种选择呗

出0入0汤圆

发表于 2014-5-29 10:14:42 | 显示全部楼层
在加一楼

出0入0汤圆

发表于 2014-5-29 10:34:53 | 显示全部楼层
按照模板,做了个呼吸灯,已经可以正常运行,时基=1ms!

  1.                                   
  2. #include <STC12C5A60S2.h>
  3. #include "PTSchedul.h"

  4. sbit LED0 = P1^0;
  5. sbit LED1 = P2^5;
  6. sbit LED2 = P2^7;

  7. sbit LED3 = P1^7;

  8. unsigned char LED_PWM=0;



  9. unsigned char task0()
  10. {
  11.         _SS
  12.         while(1)
  13.         {
  14.                 WaitX(500);
  15.                    //LED0=!LED0;
  16.         }
  17.         _EE
  18. }

  19. unsigned char  task1()
  20. {
  21.         _SS
  22.         while(1)
  23.         {
  24.                 WaitX(100);
  25.                 LED1=!LED1;
  26.         }
  27.         _EE
  28. }

  29. unsigned char  task2()
  30. {
  31.         _SS
  32.         while(1)
  33.         {
  34.                 WaitX(10);
  35.                 LED2=!LED2;
  36.         }
  37.         _EE
  38. }


  39. unsigned char tsk4_led_drv()
  40. {
  41. _SS
  42.         while(1)
  43.         {
  44.                 LED0=0;
  45.                 WaitX(LED_PWM);
  46.                 LED0=1;
  47.                 WaitX(20-LED_PWM);
  48.         }
  49. _EE
  50. }


  51. unsigned char tsk3_breathe_led() //50ms执行一次        20HZ
  52. {
  53. static unsigned char  i,bLighting=1,bDarking;
  54. _SS
  55.         while(1)
  56.         {
  57.                
  58.                 if(bLighting)
  59.                 {
  60.                         for(i=1;i<21;i++)
  61.                         {        WaitX(50);
  62.                                 LED_PWM++;
  63.                                 if(LED_PWM==20){bLighting=0;bDarking=1;}
  64.                         }       
  65.                 }

  66.                 if(bDarking)
  67.                 {
  68.                         for(i=1;i<21;i++)
  69.                         {        WaitX(50);
  70.                                 if(LED_PWM==0){bLighting=1;bDarking=0;}
  71.                                 LED_PWM--;
  72.                                 if(LED_PWM==0){bLighting=1;bDarking=0;}
  73.                                
  74.                         }       
  75.                 }

  76.         }
  77. _EE
  78. }

  79. void InitT0()
  80. {
  81.         TMOD = 0x21; //GATE1 C/T1  M1_1  M1_0  GATE0 C/T0  M0_1  M0_0   0000,0000
  82.         IE |= 0x82;  // 12t
  83.         TL0=0X66;        //1MS 11.0592Mhz
  84.         TH0=0XFC;
  85.         TR0 = 1;
  86. }

  87. void Timer0Init(void)                //10毫秒@11.0592MHz
  88. {
  89.         AUXR &= 0x7F;                //定时器时钟12T模式
  90.         TMOD &= 0xF0;                //设置定时器模式
  91.         TMOD |= 0x01;                //设置定时器模式
  92.         TL0 = 0x00;                //设置定时初值
  93.         TH0 = 0xDC;                //设置定时初值
  94.         TF0 = 0;                //清除TF0标志
  95.         TR0 = 1;                //定时器0开始计时
  96. }



  97. void INTT0(void) interrupt 1 using 1
  98. {
  99.     TL0=0X66;   //1ms 重装
  100.     TH0=0XFC;       

  101.        

  102.     UpdateTimers();

  103.     RunTask(task0,0);//任务0具有精确按时获得执行的权限,要求:task0每次执行消耗时间<0.5个 ticket
  104. }




  105. void main()
  106. {
  107.         InitT0();
  108.     InitTasks(); //初始化任务,实际上是给timers清零
  109.     while(1)
  110.         {
  111.                 //RunTask(task0,0);

  112.         RunTask(task1,3);//任务1具有比任务2高的运行权限

  113.         RunTask(task2,4);//任务2具有低的运行权限

  114.                
  115.                 RunTask(tsk4_led_drv,1);
  116.                 RunTask(tsk3_breathe_led,2);
  117.     }
  118. }


复制代码

出0入0汤圆

发表于 2014-5-29 18:05:52 | 显示全部楼层
P1口输出8种 不同的占空比的驱动,怎么写? 一定要给PIN脚对应一个驱动任务吗?
象这样:
  1. unsigned char _led1_drv() //阻塞时间可变
  2. {
  3. _SS
  4.         while(1)
  5.         {
  6.                 LED1=0;
  7.                 WaitX(LED1_PWM);
  8.                 LED1=1;
  9.                 WaitX(20-LED1_PWM);
  10.         }
  11. _EE
  12. }
复制代码

出0入0汤圆

发表于 2014-5-29 18:12:21 | 显示全部楼层
本帖最后由 ppdd 于 2014-5-29 18:14 编辑

楼主出来看看啊!! 打算做个流星灯,水滴效果的。
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-4-26 05:27

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

快速回复 返回顶部 返回列表