男女午夜激情_www.天堂av.com_亚洲综合小说区_亚洲欧美自拍视频_成年精品_久久www免费人成—看片_激情综合五月天_久久高潮视频_最新国产成人ab网站_国产精品卡一

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

程序的多任務和資源復用舉例

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

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


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

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

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

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

bit fKey1;                          /*為簡單化,沒使用隊列保存鍵值,使用標志*/
bit fKey2;                          /*為簡單化,沒使用隊列保存鍵值,使用標志*/


/*Task1*/
unsigned char data mTask1Id;        /*任務一的任務號*/
unsigned char data mTask1_1HzReg;   /*1hz時間寄存器*/
unsigned int data mTask1_2SReg;     /*2S時間寄存器*/
sbit oTask1=P1^2;                   /*輸出方波口*/

/*Task2*/
unsigned char data mTask2Id;        /*任務二的任務號*/
unsigned char data mTask2_1p2HzReg; /*1.2hz時間寄存器*/
sbit oTask2=P1^3;                   /*輸出方波口*/

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

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

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

  TR0=1;
  ET0=1;
}

/*************************************************
定時器0的中斷服務,產(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;              /*接收中斷過來的時間標志,轉(zhuǎn)換為消息*/
    fSYS_2ms=1;                 /*此消息在一周內(nèi)有效,被外部程序復用*/
    /*產(chǎn)生20MS的消息*/
    mTimer_20msReg--;
    if(mTimer_20msReg==0){
        mTimer_20msReg=INT20MSCOUNT;    /*產(chǎn)生20MS所需要的寄存器,在20MS基礎上*/
        fSYS_20ms=1;
    }
  }
}

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

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


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

/*---------------------------------------------------------------------------*/
/*任務一*/
/**********************************************
一個部分輸出1HZ的方波,2S后停止。
**********************************************/
void Task1_MainLoop()
{
    switch(mTask1Id){
      case 0:   if(fKey1){
                     fKey1=0;                   /*接收該鍵值*/
                     mTask1_1HzReg=500/2;       /*1hz時間寄存器,500ms,以2MS為單位*/
                     mTask1_2SReg=2000/2;       /*2S時間寄存器,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時間寄存器,500ms,以2MS為單位*/
                   }

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


/*---------------------------------------------------------------------------*/
/*任務二*/
/**********************************************
一個一直輸出1.2hz的方波,直到按鍵再次按
**********************************************/
void Task2_MainLoop()
{
    switch(mTask2Id){
      case 0:   if(fKey2){
                     fKey2=0;                   /*接收該鍵值*/
                     mTask2_1p2HzReg=416/2;     /*1hz時間寄存器,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時間寄存器,832/2ms,以2MS為單位*/
                       }
                   }
                }
                break;
    }
}

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

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

 

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

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

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

    網(wǎng)站經(jīng)營許可證:浙B2-20080178-1
    主站蜘蛛池模板: 南溪县| 手游| 公安县| 赤城县| 桃园县| 耿马| 鲁山县| 绩溪县| 交口县| 密山市| 冀州市| 平武县| 亚东县| 祁阳县| 江北区| 通江县| 泗洪县| 新竹县| 万载县| 托里县| 栖霞市| 正定县| 民权县| 左贡县| 西吉县| 沈阳市| 鹿邑县| 娄烦县| 南投市| 周至县| 泾源县| 灵川县| 于都县| 儋州市| 江山市| 石河子市| 钦州市| 荥经县| 马龙县| 钟祥市| 鲁山县|