下面代碼是來自51hei的一個(gè)代碼,其中一個(gè)是將任務(wù)放在一個(gè)隊(duì)列里面輪轉(zhuǎn)執(zhí)行,更重要的是一個(gè)—LINE—神一般的應(yīng)用。
#include <stc89c51.h>
#include <stc89c51.h>
#include <stdio.h>
/*****************小小調(diào)度器部分開始********************************************/
這里開始是重點(diǎn)
這里開始是重點(diǎn)
#define _SS static char lc=0; switch(lc){ case 0: lc=0;
#define _EE }; lc=0;
#define WaitX(a,b) settimer(&lc,__LINE__,a,b); return ; case __LINE__:
這里是重點(diǎn)的結(jié)束
這里是重點(diǎn)的結(jié)束
struct TASK {
char td;
void (*fp)();
};
#define MAXTASKS 5
struct TASK tasks[MAXTASKS];
//設(shè)置定時(shí)器
void settimer(char *lc,char line,char tmrid,int d){
*lc=line;
tasks[tmrid].td=d;
}
//邏輯定時(shí)器處理,在定時(shí)器中斷里調(diào)用
void dectimers() {
unsigned char i;
for (i=0;i<MAXTASKS;i++){
if (tasks[i].td>0) tasks[i].td--;
}
}
//任務(wù)調(diào)度函數(shù),在main里面運(yùn)行
void runtasks() {
unsigned char i;
for(i=0;i<MAXTASKS;i++)
{
if (tasks[i].fp!=0){
if (tasks[i].td==0){
tasks[i].td=-1;
tasks[i].fp();
}
}
}
}
/****************小小調(diào)度器部分結(jié)束*******************************************************/
sbit KEY = P3^2;
unsigned char code numtab[16]={0x24,0x6F,0xE0,0x62,0x2B,0x32,0x30,0x67,0x20,0x22,0x21,0x38,0xB4,0x68,0xB0,0xB1};
sfr IAP_CONTR = 0xC7;
sfr WDT_CONTR = 0xC1;
//清除看門狗
void clr_wdt()
{
WDT_CONTR =0x3C;
}
//初始化定時(shí)器
void InitT0()
{
TMOD = 0x21;
IE |= 0x82; // 12t
TL0=0Xff;
TH0=0Xb7;
TR0 = 1;
}
//定時(shí)器中斷
void INTT0(void) interrupt 1 using 1
{
TL0=0Xff; //10ms 重裝
TH0=0Xb7;
dectimers();
}
sbit LED1= P2^4;
//任務(wù)一,狀態(tài)機(jī)寫法
void ontimer0(){
LED1=!LED1; // LED1引腳接在發(fā)光管負(fù)極,LED1=0 為亮,LED1=1為滅。
//重裝定時(shí)器
if (LED1) tasks[0].td=45; //450mS 滅
else tasks[0].td=5; //50ms 亮
}
//任務(wù)二,狀態(tài)機(jī)寫法
char keycount=0;
void task1(){
if(KEY==0) {
keycount++;
if (keycount>20) IAP_CONTR = 0x60;
}
else{
keycount=0;
}
//重裝定時(shí)器
tasks[1].td=5;
}
//任務(wù)三,偽線程寫法
神一樣的代碼就在這里了。
神一樣的代碼就在這里了。
void task2()
{
static char i;
_SS
while(1){
for(i=0;i<=9;i++){ //從0--9快速顯示,間隔200mS
WaitX(2,20); 這里是一個(gè)delay,但是,程序退出了,然后下一次時(shí)間到了之后直接就回到這里執(zhí)行了。太強(qiáng)大了。一直沒有想到可以用LINE+switch case這么使用。
P1=numtab[i];
}
for(i=0;i<=9;i++){ //從0--9慢速顯示,間隔500mS
WaitX(2,50);
P1=numtab[i];
}
}
_EE
}
void main()
{
unsigned char KeyNum;
P3M0 = 0x00;
P3M1 =0x00;
//WDT_CONTR= 0x00; //關(guān)閉看門狗
P1 = 0xff; //關(guān)顯示
clr_wdt();
InitT0();
KEY =1; //按鍵IO口
KeyNum=0; //按下次數(shù)
//裝載任務(wù):
tasks[0].fp=ontimer0;
tasks[1].fp=task1;
tasks[2].fp=task2;
//循環(huán)調(diào)度
while(1){
runtasks();
clr_wdt();
}
}