專注電子技術(shù)學(xué)習(xí)與研究
當(dāng)前位置:單片機(jī)教程網(wǎng) >> MCU設(shè)計(jì)實(shí)例 >> 瀏覽文章

裸機(jī)中的戰(zhàn)斗機(jī),一個(gè)裸機(jī)調(diào)度器

作者:huqin   來源:本站原創(chuàng)   點(diǎn)擊數(shù):  更新時(shí)間:2014年02月01日   【字體:
下面代碼是來自51hei的一個(gè)代碼,其中一個(gè)是將任務(wù)放在一個(gè)隊(duì)列里面輪轉(zhuǎn)執(zhí)行,更重要的是一個(gè)—LINE—神一般的應(yīng)用。


#include <stc89c51.h>
 #include <stdio.h>
 
 /*****************小小調(diào)度器部分開始********************************************/ 

這里開始是重點(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é)束

 
 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();
  }
 }
關(guān)閉窗口

相關(guān)文章