新聞中心

        EEPW首頁 > 嵌入式系統 > 設計應用 > 1個定時器多處復用的問題

        1個定時器多處復用的問題

        作者: 時間:2016-11-10 來源:網絡 收藏

        問題: 在一個工程中往往需要用到多個定時,然而我們采用的CPU一般也只有2,3個定時器。顯然是不夠用的,那么應該怎么辦呢?

        我想如果使用過系統的人都會知道,在系統中有個時鐘節拍,而多個任務都是共同使用這個時鐘節拍進行延時或任務切換。那么我們是否可以借鑒一下呢?

        本文引用地址:http://www.104case.com/article/201611/317373.htm

        下面我們LPC2131舉例說明:

        ①.宏定義:

        #define T0_CLOCK_TICK (100)// 1S中計數次數

        #define T0_TASK_NUM (3) // 3個定時

        ②. 進行定義一個定時數組:

        uint32 T0_Counter[T0_TASK_NUM] ={0};// NUM 為需要使用的定時個數

        ③. 在相應的定義一個數組來存儲標志位:

        uint8 T0_Mark[T0_TASK_NUM]= {0};// 標志位為1表示定時時間到

        ④. 編寫定時器初始化函數:

        /**************************************************************************************
        * FunctionName : Timer0Init()
        * Description : 初始化定時器0
        * EntryParameter : NO
        * ReturnValue : NO
        **************************************************************************************/
        void Timer0Init(void)
        {
        /*Fcclk = Fosc x 4 = 11.0592MHz x 4 = 44.2368MHz
        Fpclk = Fcclk / 4 = 44.2368MHz / 4 = 11.0592MHz*/

        T0TC = 0; // 定時器設置為0
        T0PR = 0; // 設置定時器0分頻為1分頻
        T0MCR = 0x03;// 匹配通道0匹配中斷并復位T0TC
        T0MR0 = Fpclk/T0_CLOCK_TICK;// 比較值(1/T0_CLOCK_TICK s定時值)
        T0TCR = 0x00;// 關閉定時器0
        T0Open();// 開定時器

        /* 設置定時器0中斷IRQ*/
        VICIntSelect = 0x00; // 所有中斷通道設置為IRQ中斷
        VICVectCntl4 = 0x20|0x04;// 定時器0中斷通道分配最高優先級
        VICVectAddr4 = (uint32)IRQ_Time0;// 設置中斷服務程序地址向量
        VICIntEnable = 1 << 0x04;// 使能定時器0中斷
        }

        ⑤. 編寫中斷服務函數:

        /**************************************************************************************
        * FunctionName : IRQ_Time0()
        * Description : 定時器0中斷服務
        * EntryParameter : NO
        * ReturnValue : NO
        **************************************************************************************/

        void __irq IRQ_Time0(void) // 中斷服務函數

        {

        uint8 i;

        for (i=0; i {
        if (T0_Counter[i] != 0)
        {
        T0_Counter[i]--;// 計數值減1
        if (T0_Counter[i] == 0)
        {
        T0_SetMark(i);// 相應標志位置1
        }
        }
        }

        T0IR = 0x01;// 清除中斷標志
        VICVectAddr = 0x00;// 通知VIC中斷處理結束

        }

        ⑥. 編寫標志位置位函數:

        /**************************************************************************************
        * FunctionName : T0_SetMark()
        * Description : 設置相應標準位
        * EntryParameter : NO
        * ReturnValue : NO
        **************************************************************************************/
        void T0_SetMark(uint8 num)
        {
        switch (num)
        {
        case 0: T0_Mark[0] = 1; break;// 標志位置位
        case 1: T0_Mark[1] = 1; break;//
        case 2: T0_Mark[2] = 1; break;//

        default: break;
        }
        }

        ⑦. 編寫相應的函數,在需要使用的函數中設定計數時間:

        voidFunction1(void)

        {

        T0_Mark[0] = 0; // 清除標志位

        T0_Counter[0] = 100;// 1s計數器100次

        while (1)

        {

        if (T0_Mark[0] == 1)// 判斷時間是否到

        {

        T0_Mark[0] = 0;// 清除標志

        ...

        }

        }

        }

        ⑧. 編寫其他函數,按照以上方法。

        注意事項:

        ①. 可以根據具體需要更改計數個數。

        ②. 定時器計數1S的此時可以根據具體需要設定,如果設定計數此時太多,CPU的效率會降低,但是精確度會高一下;反正精確度低,但是CUP效率會高一些。



        關鍵詞: 定時器多處復

        評論


        技術專區

        關閉
        主站蜘蛛池模板: 万安县| 杨浦区| 大埔区| 合肥市| 新宁县| 东宁县| 昌吉市| 南昌县| 临湘市| 聂拉木县| 连云港市| 北海市| 嘉义市| 晋江市| 南靖县| 鲁山县| 庆元县| 云霄县| 灵石县| 尼勒克县| 崇礼县| 保亭| 兴文县| 邹平县| 房山区| 比如县| 龙游县| 民丰县| 周宁县| 兴隆县| 滨州市| 英吉沙县| 三明市| 平昌县| 阿克苏市| 连云港市| 潍坊市| 商丘市| 渝中区| 峨山| 沙田区|