4933|10

2002

帖子

24

TA的资源

五彩晶圆(高级)

楼主
 

【LPC54100】第四周-状态机多任务实现 [复制链接]

 
本帖最后由 shower.xu 于 2015-5-1 09:57 编辑

最近工作上的事很多,一直没抽出时间赶进度,为了过好五一,今天下午抽时间移植了一个状态机系统上去,实现多任务的运行,为下一步菜单系统打下基础。

下面简单介绍一下这个状态机系统:

这个状态机是从隔壁论坛里网友的分享里copy过来的,试了几次,很好用,所以打算在小资源的单片机系统里面用下去。

它需要一个时钟,支持多个任务分时并发,支持信号量传递,简单的优先级等等。

  1. #ifndef TINYOS
  2.         #define TINYOS
  3.         #define MAXTASKS 5                //顶层任务数量最大为255个,顶层任务的任何地方都可以调用子任务.
  4.         extern  volatile unsigned char timers[MAXTASKS];
  5.         #define _SS static unsigned char _lc=0; switch(_lc){default:
  6.         #define _EE ;}; _lc=0; return 255;
  7.         #define WaitX(tickets)  do {_lc=(__LINE__+((__LINE__%256)==0))%256; return tickets ;} while(0); case (__LINE__+((__LINE__%256)==0))%256:

  8.         #define RunTask(TaskName,TaskID) do { if (timers[TaskID]==0) timers[TaskID]=TaskName(); }  while(0);
  9.         #define RunTaskA(TaskName,TaskID) { if (timers[TaskID]==0) {timers[TaskID]=TaskName(); continue;} }   //前面的任务优先保证执行

  10.         #define CallSub(SubTaskName) do {unsigned char currdt; _lc=(__LINE__+((__LINE__%256)==0))%256; return 0; case (__LINE__+((__LINE__%256)==0))%256:  currdt=SubTaskName(); if(currdt!=255) return currdt;} while(0);
  11.         #define InitTasks() {unsigned char i; for(i=MAXTASKS;i>0 ;i--) timers[i-1]=0; }
  12.         #define UpdateTimers() {unsigned char i; for(i=MAXTASKS;i>0 ;i--){if((timers[i-1]!=0)&&(timers[i-1]!=255)) timers[i-1]--;}}

  13.         #define SEM unsigned int
  14.         //初始化信号量
  15.         #define InitSem(sem) sem=0;
  16.         //等待信号量
  17.         #define WaitSem(sem) do{ sem=1; WaitX(0); if (sem>0) return 1;} while(0);
  18.         //等待信号量或定时器溢出, 定时器tickets 最大为0xFFFE
  19.         #define WaitSemX(sem,tickets)  do { sem=tickets+1; WaitX(0); if(sem>1){ sem--;  return 1;} } while(0);
  20.         //发送信号量
  21.         #define SendSem(sem)  do {sem=0;} while(0);
  22. #endif//终止
复制代码
首先包含头文件和声明函数和变量

  1. //TinyOS
  2. #include "tinyOS.h"
  3. /*      信号量传递       */
  4. SEM keyPressed;
  5. /*      系统定时器       */
  6. void toggle_OS_timer(void);
  7. //unsigned char  task0();
  8. unsigned char  task1(void);
  9. unsigned char  task2(void);               
  10. unsigned char  task3(void);        
  11. unsigned char  task4(void);        
复制代码
编写任务代码,系统需要一个时钟

  1. /*  TinyOS task function */
  2. void toggle_OS_timer(void)
  3. {
  4.     UpdateTimers();
  5.         //RunTask(task0,0); //任务0具有精确按时获得执行的权限
  6. }

  7. /*     按键扫描任务,15ms一次        */
  8. unsigned char  task1(){
  9. _SS
  10.         while(1)
  11.         {
  12.                 key_scan();
  13.                 if(key_status) SendSem(keyPressed);
  14.                 WaitX(15);
  15.                 key_flag_clr();
  16.         }
  17. _EE
  18. }
  19. /*     菜单响应程序        */
  20. unsigned char  task2(){
  21. _SS
  22.         while(1)
  23.         {
  24.                 WaitSem(keyPressed);        
  25.                 MenuIndex_switch();        
  26.         }
  27. _EE
  28. }
  29. /*     闪烁标题栏程序        */
  30. unsigned char  task3(){
  31. _SS
  32.         while(1)
  33.         {        
  34.     GUI_RectangleFill(0+1, 0+1,0+12,0+12, Magenta);        
  35.     GUI_RectangleFill(0+12, 0+1,0+24-1,0+12, Red);
  36.           GUI_RectangleFill(0+12, 0+12,0+24-1,0+24-1, Yellow);
  37.           GUI_RectangleFill(0+1, 0+12,0+12,0+24-1, Green);
  38.                 WaitX(250);
  39.     GUI_RectangleFill(0+1, 0+1,0+12,0+12, Green);        
  40.     GUI_RectangleFill(0+12, 0+1,0+24-1,0+12,Magenta );
  41.           GUI_RectangleFill(0+12, 0+12,0+24-1,0+24-1,Red );
  42.           GUI_RectangleFill(0+1, 0+12,0+12,0+24-1,Yellow );
  43.                 WaitX(250);
  44.     GUI_RectangleFill(0+1, 0+1,0+12,0+12,Yellow );        
  45.     GUI_RectangleFill(0+12, 0+1,0+24-1,0+12, Green);
  46.           GUI_RectangleFill(0+12, 0+12,0+24-1,0+24-1,Magenta );
  47.           GUI_RectangleFill(0+1, 0+12,0+12,0+24-1, Red);
  48.                 WaitX(250);
  49.     GUI_RectangleFill(0+1, 0+1,0+12,0+12, Red);        
  50.     GUI_RectangleFill(0+12, 0+1,0+24-1,0+12, Yellow);
  51.           GUI_RectangleFill(0+12, 0+12,0+24-1,0+24-1, Green);
  52.           GUI_RectangleFill(0+1, 0+12,0+12,0+24-1,Magenta );
  53.                 WaitX(250);
  54.         }
  55. _EE
  56. }

  57. /*     动画切换程序        */
  58. unsigned char  task4(){
  59.         static uint8 ts=0;
  60. _SS
  61.         while(1)
  62.         {        
  63.                 ts++;
  64.                 Board_LED_SetPortState(1<<(ts&0x03));         
  65.                 WaitX(250); //25fps
  66.         }
  67. _EE
  68. }
复制代码
好,一切就绪,初始化并运行任务即可

  1. /*tinyOS start here */
  2.         InitTasks(); //初始化任务,实际上是给timers清零
  3.         InitSem(keyPressed);//初始化信号量
  4.         MenuIndex_switch();
  5.         while(1)
  6.         {
  7.                 RunTaskA(task1,1);//按键扫描
  8.                 RunTaskA(task2,2);//菜单相应
  9.                 RunTaskA(task4,4);//界面切换动画        
  10.                 RunTaskA(task3,3);//闪烁标题栏                        
  11.         }        
复制代码
是不是很简单呢,那我们看实现了哪些功能。

task1进行按键的周期扫描,并把结果传递给task2。

task2平时不运行,直到task1告知有按键按下。这个时候执行界面切换程序来响应按键。

task3闪烁窗口左上角标题栏,告知系统运行。

task4控制桌面流水灯。



代码

TinyOS.rar (1.5 MB, 下载次数: 49, 售价: 1 分芯积分)

运行界面





视频

此帖出自NXP MCU论坛

最新回复

感谢分享  详情 回复 发表于 2017-10-24 10:13

赞赏

2

查看全部赞赏

点赞 关注(2)
 

回复
举报

234

帖子

0

TA的资源

一粒金砂(高级)

沙发
 
呵呵 ,用了ssmet 的小小调度器, 这个非常不错, 真心好用, 小资源MCU更值得一用
此帖出自NXP MCU论坛

点评

是的,确实很好用  详情 回复 发表于 2015-5-1 09:56
 
 
 

回复

2002

帖子

24

TA的资源

五彩晶圆(高级)

板凳
 
foxpro2005 发表于 2015-5-1 09:46
呵呵 ,用了ssmet 的小小调度器, 这个非常不错, 真心好用, 小资源MCU更值得一用

是的,确实很好用
此帖出自NXP MCU论坛
 
 
 

回复

266

帖子

0

TA的资源

一粒金砂(高级)

4
 
牛人!学习学习
此帖出自NXP MCU论坛
 
个人签名

gitee/casy

 
 

回复

22

帖子

0

TA的资源

一粒金砂(中级)

5
 
请问,有那个tinyos的详细资料吗??给个链接就好 。
此帖出自NXP MCU论坛
 
 
 

回复

22

帖子

0

TA的资源

一粒金砂(中级)

6
 
请问,楼主用的什么编译器呢??我用的5.14编译出一堆错误……
此帖出自NXP MCU论坛
 
 
 

回复

27

帖子

0

TA的资源

一粒金砂(中级)

7
 
这个不错,赞了
此帖出自NXP MCU论坛
 
 
 

回复

2002

帖子

24

TA的资源

五彩晶圆(高级)

8
 
请百度~小小调度器
此帖出自NXP MCU论坛
 
 
 

回复

3238

帖子

5

TA的资源

五彩晶圆(中级)

9
 
pt的思路确实不错,就是代码编码风格看起来有点不习惯
此帖出自NXP MCU论坛
 
个人签名淘宝:https://viiot.taobao.com/Q群243090717
多年专业物联网行业经验,个人承接各类物联网外包项目
 
 

回复

19

帖子

0

TA的资源

一粒金砂(中级)

10
 
用了ssmet 的小小调度器, 这个非常不错, 真心好用, 小资源MCU更值得一用
此帖出自NXP MCU论坛
 
 
 

回复

200

帖子

1

TA的资源

一粒金砂(中级)

11
 
感谢分享
此帖出自NXP MCU论坛
 
 
 

回复
您需要登录后才可以回帖 登录 | 注册

随便看看
查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
关闭
站长推荐上一条 1/10 下一条

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

站点相关: 国产芯 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网

北京市海淀区中关村大街18号B座15层1530室 电话:(010)82350740 邮编:100190

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved
快速回复 返回顶部 返回列表