#include "REG52.H"
#include "INTRINS.H"
/**************小小调度器开始 *********************************/
#define MAXTASKS 3 //顶层任务数量,可按需增加,最大为255个。
unsigned char timers[MAXTASKS];
char currid; //当前运行的任务号
#define _SS static char lc=0; switch(lc){ case 0: //跳转开始
#define _EE }; lc=0; //跳转结束
#define DelayX(b) settimer(&lc,__LINE__,b); return ; case __LINE__: //任务内延时等待“函数”
#define RunTask(a,b) currid=b; if (timers[currid]==0){timers[currid]=-1; a();} //运行顶层任务
#define CallSub(x) DelayX(0);x(); if (timers[currid]!=-1) return; //调用子任务
void settimer(char *lc,char line,unsigned char d){//设置定时器
*lc=line; timers[currid]=d;
}
/****************小小调度器结束*** (我很短,但用起来很爽)******************************/
sbit KEY = P3^2;
unsigned char code numtab[16]={0x0,0x1,0x2,0x3,0x4,0x5,0x6,0x7,0x8,0x9,0x10,0x11,0x12,0x13,0x14,0x15};
// sfr IAP_CONTR = 0xC7;
// sfr WDT_CONTR = 0xC1;
//清除看门狗
// void clr_wdt()
// {
// WDT_CONTR =0x3C;
// }
//初始化定时器,产生10ms中断
void InitT0()
{
TMOD = 0x21;
IE |= 0x82; // 12t
TL0=0Xff;
TH0=0Xb7;
TR0 = 1;
}
//定时器中断处理函数
void INTT0(void) interrupt 1 using 1
{
unsigned char i;
TL0=0Xff; //10ms 重装
TH0=0Xb7;
//逻辑定时器处理
for (i=0;i<MAXTASKS;i++){
if (timers[i]>0) {
timers[i]--;
}
}
}
sbit LED1= P2^4;
//任务一,状态机写法
void ontimer0(){
LED1=!LED1; // LED1引脚接在发光管负极,LED1=0 为亮,LED1=1为灭
if (LED1) timers[currid]=100; //1000mS 灭
else timers[currid]=200; //2000ms 亮
}
//任务二,状态机写法
char keycount=0;
void task1(){
if(KEY==0) {
keycount++;
if (keycount>20) P0 = 0x60;
}
else{
keycount=0;
}
timers[currid]=5; //重装定时器
}
//这是一个子任务函数
void subtask()
{
static char i;
_SS
for(i=0;i<=5;i++){
DelayX(100);
//P1=numtab;
P1=(P1&0xf0)|i;
}
_EE
}
//任务三,“线程”写法,复杂任务请用这种方式来写,比传统状态机写法更简单,更自然,而且更省ROM!
void task2()
{
static char i; //变量请申明为静态的。
_SS
while(1){
for(i=0;i<=15;i++){ //先从0--9快速显示,间隔2000mS
DelayX(100);
// P1=numtab;
P1=(P1&0xf0)|i;
}
//for(;;);
for(i=0;i<=8;i++){//然后从0--9慢速显示,间隔1000mS
DelayX(200);
// P1=numtab;
P1=(P1&0x0f)|(i<<4);
CallSub(subtask); //顶层任务的任何地方都可以调用子任务
}
//CallSub(subtask); //顶层任务的任何地方都可以调用子任务
}
_EE
}
void main()
{
// P3M0 = 0x00;
// P3M1 =0x00;
P0=0XFF;
P1 = 0xff; //关LED数码管显示
P3=0XFF;
InitT0(); //初始化定时器,以便产生10ms中断
KEY =1; //按键IO口
while(1){
// clr_wdt(); //清除看门狗
//这里,只需运行顶层任务即可
RunTask(ontimer0,0); //ontimer0任务放在第0个任务槽
RunTask(task1,1); //task1任务放在第1个任务槽
RunTask(task2,2); //task2任务放在第2个任务槽
//...还可以增加更多任务
}
}
没有合适的资源?快使用搜索试试~ 我知道了~
thread2.rar_C语言状态机_Protothread_伪线程C_小小调度器整理说明_调度器
共23个文件
bak:3个
lst:2个
obj:2个
1.该资源内容由用户上传,如若侵权请联系客服进行举报
2.虚拟产品一经售出概不退款(资源遇到问题,请及时私信上传者)
2.虚拟产品一经售出概不退款(资源遇到问题,请及时私信上传者)
版权申诉
0 下载量 60 浏览量
2022-07-14
19:08:06
上传
评论
收藏 102KB RAR 举报
温馨提示
1) 超级可以移植性,与 CPU 无关,几乎任何支持 C 语言编程的 CPU 都可以用!(本文仅仅以 51 单片机为例而已,但实际上可以任意移植) 2) 小之又小, 原理很简单,一看就懂。 3) 省之又省, 可以说对 RAM 和 ROM 省到极致。 4) 取 protothread 之精华,将定时器与状态机和伪线程语法融合到一个框架,任务函数可以有两种写法。 5) 基于定时器触发,调度效率高,最大化减少无效的代码运行时间。
资源详情
资源评论
资源推荐
收起资源包目录
thread2.rar (23个子文件)
thread2
main.OBJ 7KB
thread 6KB
thread.uvgui_Administrator.bak 130KB
main.c 3KB
thread.lnp 58B
thread.plg 177B
STARTUP.LST 14KB
thread_uvopt.bak 72KB
main.LST 6KB
thread.hex 2KB
main.__i 34B
fangzhen
ARES.dmp 38KB
Last Loaded fangzhen.DBK 164KB
fangzhen.DSN 164KB
fangzhen.PWI 959B
thread.uvgui.Administrator 130KB
STARTUP.A51 6KB
thread.uvproj 14KB
thread_uvproj.bak 13KB
thread.uvgui.levi 69KB
thread.uvopt 6KB
thread.M51 10KB
STARTUP.OBJ 749B
共 23 条
- 1
四散
- 粉丝: 49
- 资源: 1万+
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功
评论0