自在自线亚洲а∨天堂在线-中文字幕一区视频播放-扒开双腿猛进入喷水高潮叫声-欧美日本亚洲一区二区-老熟妇高潮偷拍一区二区-国产精品高清一区二区不卡-午夜色福利视频一区二区三区-亚洲国产成人精品福利在线观看-亚洲欧美成人一区二区在线电影

機(jī)電之家資源網(wǎng)
單片機(jī)首頁|單片機(jī)基礎(chǔ)|單片機(jī)應(yīng)用|單片機(jī)開發(fā)|單片機(jī)文案|軟件資料下載|音響制作|電路圖下載 |嵌入式開發(fā)
培訓(xùn)信息
贊助商
程序的多任務(wù)和資源復(fù)用舉例
程序的多任務(wù)和資源復(fù)用舉例
 更新時(shí)間:2008-7-26 20:30:55  點(diǎn)擊數(shù):3
【字體: 字體顏色

程序的多任務(wù)和資源復(fù)用舉例

有一臺(tái)機(jī)電設(shè)備 , 有兩個(gè)按鍵,控制設(shè)備的兩個(gè)不同部分。
現(xiàn)要求:
  每個(gè)按鍵按下,相應(yīng)控制程序運(yùn)行。但兩個(gè)按鍵可以同時(shí)按下,就是說兩個(gè)控制程序可能
需要同時(shí)運(yùn)行。使用一個(gè)89C52,如何編寫程序?

注:此程序不使用RTOS等操作系統(tǒng)。


/*程序說明:
  一)產(chǎn)生波形可以使用中斷中計(jì)數(shù)來產(chǎn)生精確的波形。
      本答案中為更能體現(xiàn)程序的多任務(wù)和資源復(fù)用問題,采用主程序循環(huán)產(chǎn)生。
  二)請(qǐng)?zhí)貏e注意,題意是兩個(gè)程序在并發(fā)運(yùn)行,實(shí)際按本答案可以擴(kuò)展到N個(gè)不同任務(wù)同時(shí)運(yùn)行,在此就不討論。
      (對(duì)大程序結(jié)構(gòu)增加了很多其它的概念)
  三)因?yàn)樵谡搲现苯淤N出,所以程序放在一個(gè)文件中。
      應(yīng)該按Timer.c, Key.c, Const.h(存放常量定義),Task1, Task2, Answer.c存放
*/
#include <REG52.h>

/*Timer*/
bit fTimer0_2ms;   /*T0中斷產(chǎn)生的標(biāo)志,準(zhǔn)備傳遞給主循環(huán)*/
bit fSYS_2ms;      /*系統(tǒng)T0中斷產(chǎn)生的標(biāo)志,12M,主循環(huán)使用*/
bit fSYS_20ms;     /*每20MS產(chǎn)生一次的消息*/

#define INT2MSCOUNT     10                      /*產(chǎn)生2MS所需要的時(shí)間次數(shù)*/
unsigned char data mTimer_2msReg=INT2MSCOUNT;   /*產(chǎn)生2MS所需要的寄存器*/
#define INT20MSCOUNT    10                      /*產(chǎn)生20MS所需要的時(shí)間次數(shù),在20MS基礎(chǔ)上*/
unsigned char data mTimer_20msReg=INT20MSCOUNT; /*產(chǎn)生20MS所需要的寄存器,在20MS基礎(chǔ)上*/

/*KEY*/
unsigned char data mKey1SwapTask;    /***按鍵任務(wù)寄存器***/
unsigned char data mKey2SwapTask;    /***按鍵任務(wù)寄存器***/
sbit iKey1=P1^0;                     /*按鍵的輸入口*/
sbit iKey2=P1^1;

bit fKey1;                          /*為簡單化,沒使用隊(duì)列保存鍵值,使用標(biāo)志*/
bit fKey2;                          /*為簡單化,沒使用隊(duì)列保存鍵值,使用標(biāo)志*/


/*Task1*/
unsigned char data mTask1Id;        /*任務(wù)一的任務(wù)號(hào)*/
unsigned char data mTask1_1HzReg;   /*1hz時(shí)間寄存器*/
unsigned int data mTask1_2SReg;     /*2S時(shí)間寄存器*/
sbit oTask1=P1^2;                   /*輸出方波口*/

/*Task2*/
unsigned char data mTask2Id;        /*任務(wù)二的任務(wù)號(hào)*/
unsigned char data mTask2_1p2HzReg; /*1.2hz時(shí)間寄存器*/
sbit oTask2=P1^3;                   /*輸出方波口*/

/*---------------------------------------------------------------------------*/
/*產(chǎn)生以1MS為基礎(chǔ)的系統(tǒng)定時(shí)信號(hào),T0作為基準(zhǔn)定時(shí)器*/

/*************************************************
定時(shí)器T0初始化0.2MS,12M
*************************************************/
void Timer0_Init()
{
  TMOD|=0x2;            /*8位定時(shí)器*/

  TL0=TH0=~(200)+1;     /*12M*/

  TR0=1;
  ET0=1;
}

/*************************************************
定時(shí)器0的中斷服務(wù),產(chǎn)生fTimer0_2ms
*************************************************/
void timer0(void) interrupt 1 /*T0中斷*/
{
  mTimer_2msReg--;
  if(mTimer_2msReg==0){
    mTimer_2msReg=INT2MSCOUNT;  /*產(chǎn)生1MS所需要的寄存器*/
    fTimer0_2ms=1;
  }
}

/*************************************************
控制消息fSYS_2ms
*************************************************/
void Timer0_MainLoop()
{
  fSYS_2ms=0;
  fSYS_20ms=0;

  if(fTimer0_2ms){
    fTimer0_2ms=0;              /*接收中斷過來的時(shí)間標(biāo)志,轉(zhuǎn)換為消息*/
    fSYS_2ms=1;                 /*此消息在一周內(nèi)有效,被外部程序復(fù)用*/
    /*產(chǎn)生20MS的消息*/
    mTimer_20msReg--;
    if(mTimer_20msReg==0){
        mTimer_20msReg=INT20MSCOUNT;    /*產(chǎn)生20MS所需要的寄存器,在20MS基礎(chǔ)上*/
        fSYS_20ms=1;
    }
  }
}

/*---------------------------------------------------------------------------*/
/*按鍵掃描,包含兩個(gè)掃描任務(wù)*/
/**********************************************
每次系統(tǒng)時(shí)間進(jìn)入一次,20ms.這里把20MS判斷放進(jìn)來,好看點(diǎn)
按鍵掃描循環(huán)
為簡單化,沒使用隊(duì)列保存鍵值,使用標(biāo)志
那些重復(fù)發(fā)出N鍵,在這個(gè)結(jié)構(gòu)中非常容易加上
**********************************************/
void Key_MainLoop()
{
   if(fSYS_20ms==0)return;

   switch(mKey1SwapTask){
     case 0:/***有按鍵按下嗎?***/
            if(iKey1==0){
              mKey1SwapTask=1;
            }
            break;
    case 1: /***鍵按下去抖延時(shí)***/
            mKey1SwapTask=2;                    /***延時(shí)一個(gè)系統(tǒng)時(shí)間***/
            break;
    case 2: /***鍵值判斷***/
            if(iKey1==0){
              fKey1=1;                          /*按鍵有效*/
              mKey1SwapTask=3;                  /*去按鍵去抖*/
            }
            else mKey1SwapTask=0;               /*抖動(dòng)*/
            break;
    case 3: /***有松開嗎?***/
            if(iKey1==1){
              mKey1SwapTask=4;
            }
            break;
    case 4: /***鍵松開去抖延時(shí)***/
            mKey1SwapTask=5;                    /***延時(shí)一個(gè)系統(tǒng)時(shí)間***/
            break;
    case 5: /***鍵值判斷***/
            if(iKey1==1){
              mKey1SwapTask=0;                  /*去按鍵檢測開始*/
            }
            else mKey1SwapTask=3;               /*抖動(dòng)*/
            break;
   }


   switch(mKey2SwapTask){
     case 0:/***有按鍵按下嗎?***/
            if(iKey2==0){
              mKey2SwapTask=1;
            }
            break;
    case 1: /***鍵按下去抖延時(shí)***/
            mKey2SwapTask=2;                    /***延時(shí)一個(gè)系統(tǒng)時(shí)間***/
            break;
    case 2: /***鍵值判斷***/
            if(iKey2==0){
              fKey2=1;                          /*按鍵有效*/
              mKey2SwapTask=3;                  /*去按鍵去抖*/
            }
            else mKey2SwapTask=0;               /*抖動(dòng)*/
            break;
    case 3: /***有松開嗎?***/
            if(iKey2==1){
              mKey2SwapTask=4;
            }
            break;
    case 4: /***鍵松開去抖延時(shí)***/
            mKey2SwapTask=5;                    /***延時(shí)一個(gè)系統(tǒng)時(shí)間***/
            break;
    case 5: /***鍵值判斷***/
            if(iKey2==1){
              mKey2SwapTask=0;                  /*去按鍵檢測開始*/
            }
            else mKey2SwapTask=3;               /*抖動(dòng)*/
            break;
   }
}

/*---------------------------------------------------------------------------*/
/*任務(wù)一*/
/**********************************************
一個(gè)部分輸出1HZ的方波,2S后停止。
**********************************************/
void Task1_MainLoop()
{
    switch(mTask1Id){
      case 0:   if(fKey1){
                     fKey1=0;                   /*接收該鍵值*/
                     mTask1_1HzReg=500/2;       /*1hz時(shí)間寄存器,500ms,以2MS為單位*/
                     mTask1_2SReg=2000/2;       /*2S時(shí)間寄存器,500ms,以2MS為單位*/
                     oTask1=0;
                     mTask1Id=1;
                }
                break;
      case 1:   if(fSYS_2ms){
                   mTask1_1HzReg--;
                   if(mTask1_1HzReg==0){
                       oTask1=~oTask1;
                       mTask1_1HzReg=500/2;     /*1hz時(shí)間寄存器,500ms,以2MS為單位*/
                   }

                   mTask1_2SReg--;
                   if(mTask1_2SReg==0){
                       oTask1=1;                /*2S時(shí)間到*/
                       mTask1Id=0;
                   }
                }
                break;
    }
}


/*---------------------------------------------------------------------------*/
/*任務(wù)二*/
/**********************************************
一個(gè)一直輸出1.2hz的方波,直到按鍵再次按
**********************************************/
void Task2_MainLoop()
{
    switch(mTask2Id){
      case 0:   if(fKey2){
                     fKey2=0;                   /*接收該鍵值*/
                     mTask2_1p2HzReg=416/2;     /*1hz時(shí)間寄存器,832/2ms,以2MS為單位*/
                     oTask2=0;
                     mTask2Id=1;
                }
                break;
      case 1:   if(fKey2){
                  fKey2=0;
                  oTask2=1;
                  mTask2Id=0;
                }
                else {
                   if(fSYS_2ms){
                       mTask2_1p2HzReg--;
                       if(mTask2_1p2HzReg==0){
                           oTask2=~oTask1;
                           mTask2_1p2HzReg=416/2;   /*1hz時(shí)間寄存器,832/2ms,以2MS為單位*/
                       }
                   }
                }
                break;
    }
}

/*---------------------------------------------------------------------------*/
/*主程序*/
void main(){
   Timer0_Init();
   EA=1;

   while(1){
       Timer0_MainLoop();
       Key_MainLoop();
       Task1_MainLoop();
       Task2_MainLoop();
   }
}

 

  • 上一篇: 串口通信的單片機(jī)程序
  • 下一篇: 采用軟件定時(shí)的計(jì)算方法
  • 發(fā)表評(píng)論   告訴好友   打印此文  收藏此頁  關(guān)閉窗口  返回頂部
    熱點(diǎn)文章
     
    推薦文章
     
    相關(guān)文章
    網(wǎng)友評(píng)論:(只顯示最新5條。)
    關(guān)于我們 | 聯(lián)系我們 | 廣告合作 | 付款方式 | 使用幫助 | 機(jī)電之家 | 會(huì)員助手 | 免費(fèi)鏈接

    點(diǎn)擊這里給我發(fā)消息66821730(技術(shù)支持)點(diǎn)擊這里給我發(fā)消息66821730(廣告投放) 點(diǎn)擊這里給我發(fā)消息41031197(編輯) 點(diǎn)擊這里給我發(fā)消息58733127(審核)
    本站提供的機(jī)電設(shè)備,機(jī)電供求等信息由機(jī)電企業(yè)自行提供,該企業(yè)負(fù)責(zé)信息內(nèi)容的真實(shí)性、準(zhǔn)確性和合法性。
    機(jī)電之家對(duì)此不承擔(dān)任何保證責(zé)任,有侵犯您利益的地方請(qǐng)聯(lián)系機(jī)電之家,機(jī)電之家將及時(shí)作出處理。
    Copyright 2007 機(jī)電之家 Inc All Rights Reserved.機(jī)電之家-由機(jī)電一體化網(wǎng)更名-聲明
    電話:0571-87774297 傳真:0571-87774298
    杭州濱興科技有限公司提供技術(shù)支持

    主辦:杭州市高新區(qū)(濱江)機(jī)電一體化學(xué)會(huì)
    中國行業(yè)電子商務(wù)100強(qiáng)網(wǎng)站

    網(wǎng)站經(jīng)營許可證:浙B2-20080178-1