在线看毛片网站电影-亚洲国产欧美日韩精品一区二区三区,国产欧美乱夫不卡无乱码,国产精品欧美久久久天天影视,精品一区二区三区视频在线观看,亚洲国产精品人成乱码天天看,日韩久久久一区,91精品国产91免费

<menu id="6qfwx"><li id="6qfwx"></li></menu>
    1. <menu id="6qfwx"><dl id="6qfwx"></dl></menu>

      <label id="6qfwx"><ol id="6qfwx"></ol></label><menu id="6qfwx"></menu><object id="6qfwx"><strike id="6qfwx"><noscript id="6qfwx"></noscript></strike></object>
        1. <center id="6qfwx"><dl id="6qfwx"></dl></center>

            新聞中心

            EEPW首頁 > 嵌入式系統(tǒng) > 設(shè)計(jì)應(yīng)用 > 程序的多任務(wù)和資源復(fù)用舉例C51源程序

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

            作者: 時(shí)間:2016-11-18 來源:網(wǎng)絡(luò) 收藏
            程序的多任務(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

            /*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; /*為簡(jiǎn)單化,沒使用隊(duì)列保存鍵值,使用標(biāo)志*/
            bit fKey2; /*為簡(jiǎn)單化,沒使用隊(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)
            為簡(jiǎ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; /*去按鍵檢測(cè)開始*/
            }
            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; /*去按鍵檢測(cè)開始*/
            }
            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();
            }
            }


            評(píng)論


            技術(shù)專區(qū)

            關(guān)閉