新聞中心

        EEPW首頁 > 嵌入式系統(tǒng) > 設計應用 > 裸奔程序之看門狗定時器

        裸奔程序之看門狗定時器

        作者: 時間:2016-11-19 來源:網絡 收藏
        WATCHDOG定時器簡介:

        WATCHDOG定時器也可以像一般的16位定時器一樣用于產生周期性中斷,也可以用于發(fā)出復位信號以重啟時常的系統(tǒng)。它的結構與PWM很相似,如下圖所示:

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

        從上圖我們可以發(fā)現,WATCHDOG 定時器先經過8位預分頻將PCLK分頻后,被再次分頻得到4種頻率,16分頻、32分頻、64分頻、128分頻,WATCHDOG 定時器可以通過設置 WTCON[4:3]來決定工作在哪種頻率之下,WTCHT 寄存器按照其工作頻率減1計數,當達到0時,可以產生中斷信號,可以輸出復位信號。在第一次使用WATCHDOG 定時器時,需要往WTCNT 寄存器中寫入初始計數值,以后在計數值到達0時,自動從WATDAT 寄存器中裝入,重新開始下一個計數值。

        使用WATCHDOG定時器的“WATCHDOG 功能”時,在正常的程序中,必須不斷重新設置WTCNT 寄存器,使之不為0,這樣可以保證系統(tǒng)不被重啟,這就是所謂的“喂狗”啦。當程序崩潰時不能正常“喂狗”,計數值達到0后系統(tǒng)將被重啟,這樣程序將重新運行。

        有關WATCHDOG 定時器的寄存器只有3個。我們來簡單介紹一下:

        1、WTCON 寄存器(WATCHDOG TIMER CONTROL)

        用于設置分頻系數,選擇工作頻率,決定是否使能中斷,是否啟用WATDOG 功能(即是否輸出復位信號),WATCHDOG 定時器的工作頻率可以通過下面這個公式計算:
        WATCHDOG 定時器工作頻率 = PCLK / {prescaler +1 } / {divider value }

        {prescaler value } = 0~255, {divider value} = 16,32,64,128。

        2、WTDAT 寄存器(WATCHDOG TIMER DATA)

        WTDAT 寄存器被用來決定WATCHDOG 定時器的超時周期,在定時器啟動后,當計數達到0時,WTDAT 寄存器的值會自動傳入 WTCNT 寄存器。不過,第一次啟動WATCHDOG 定時器時,WTDAT 寄存器的值不會自動傳入WTNT寄存器,這就需要首先在WTNT裝入初值啦。

        3、WTCNT 寄存器(WATCHDOG TIMR COUNT)

        在啟動WATCHDOG 定時器前,必須往WTCNT這個寄存器寫入初始計數值。啟動定時器后,它減1計數,當計數值達到0時,如果中斷被使能的話,就會發(fā)出中斷請求;如WATCHDOG功能被使能的話,將會發(fā)出復位信號,裝載 WTDAT寄存器的值并重新計數。

        注意:

        當使能中斷的時候,WATCHDOG定時器中斷是有次級中斷源的,初始化中斷的時候需要格外注意。

        ————————————————————————————————————————————

        下面開始講解main.c程序:

        #include "2440addr.h"
        #include "Option.h"


        #define LED1_ON (rGPBDAT &=~(1<<5))
        #define LED1_OFF (rGPBDAT |=(1<<5) )
        #define LED2_ON (rGPBDAT &=~(1<<6))
        #define LED2_OFF (rGPBDAT |=(1<<6))
        #define LED3_ON (rGPBDAT &=~(1<<7))
        #define LED3_OFF (rGPBDAT |=(1<<7))
        #define LED4_ON (rGPBDAT &=~(1<<8))
        #define LED4_OFF (rGPBDAT |=(1<<8))

        void __irq Wdt_Int(void);

        void Delay(void)
        {
        int i;
        for(i=0;i<1000000;i++);
        }

        void Main(void)
        {
        rGPBCON &=~((3<<10)|(3<<12)|(3<<14)|(3<<16)); //對GPBCON[10:17]清零
        rGPBCON |=((1<<10)|(1<<12)|(1<<14)|(1<<16)); //設置GPB5~8為輸出
        rGPBUP &=~((1<<5)|(1<<6)|(1<<7)|(1<<8)); //設置GPB5~8的上拉功能
        rGPBDAT |=(1<<5)|(1<<6)|(1<<7)|(1<<8); //關閉LED

        rGPBCON |=1; //輸出
        rGPBUP |=0;
        rGPBDAT|=0; //關閉蜂鳴器

        rWTDAT=50000; //設置看門狗定時器超時時間為4秒(50÷12.5)
        rWTCNT=50000;
        rWTCON=(249<<8)|(1<<5)|(0<<3)|(1<<2);//預分頻值為249,使能看門狗,分頻系數為16,中斷使能

        rSRCPND |=BIT_WDT_AC97;
        rINTPND |=BIT_WDT_AC97;
        rSUBSRCPND |= BIT_SUB_WDT; //清除中斷標志

        rINTMSK &= ~(BIT_WDT_AC97);
        rINTSUBMSK &= ~(BIT_SUB_WDT);//開中斷

        pISR_WDT_AC97=(unsigned)Wdt_Int;//設置中斷程序入口
        while(1)
        {
        LED1_ON;Delay();LED1_OFF;
        LED2_ON;Delay();LED2_OFF;
        LED3_ON;Delay();LED3_OFF;
        LED4_ON;Delay();LED4_OFF;
        rWTCNT=50000; //喂狗 沒喂狗蜂鳴器很響
        }
        }

        void __irq Wdt_Int(void)
        {
        rSRCPND |=BIT_WDT_AC97;
        rINTPND |=BIT_WDT_AC97;
        rSUBSRCPND |= BIT_SUB_WDT; //清除中斷標志
        rGPBDAT =1;
        Delay();// from 2440lib.c
        rGPBDAT =0; //蜂鳴器響一段時間
        }

        —————————————————————————————————————————————

        我們首先來看main函數,進入main函數之后,首先是設置LED1~4對應管腳為輸出、使能上拉、關閉全部LED。(前面四句)

        接著三句是設置蜂鳴器控制管腳GPB0為輸出、使能上拉、關閉蜂鳴器。

        我們先來看這句 rWTCON=(249<<8)|(1<<5)|(0<<3)|(1<<2);//預分頻值為249,使能看門狗,分頻系數為16,中斷使能

        通過WATCHDOG 定時器工作頻率 = PCLK / {prescaler +1 } / {divider value }

        {prescaler value } = 0~255, {divider value} = 16,32,64,128。

        計算求得WATCHDOG工作頻率為12500Hz,即每秒鐘計數12500次。

        再回頭來看看上面那二句就很清楚的知道是定時器4秒的意思啦。

        rWTDAT=50000; //設置看門狗定時器超時時間為4秒(50÷12.5)
        rWTCNT=50000;

        接下來是清除中斷標志,注意WATCHDOG是有次級中斷源的,所以需要清除二個中斷掛起寄存器。

        rSRCPND |=BIT_WDT_AC97;
        rINTPND |=BIT_WDT_AC97;
        rSUBSRCPND |= BIT_SUB_WDT; //清除中斷標志

        接下來是打開中斷,也是打開二個中斷允許寄存器。

        rINTMSK &= ~(BIT_WDT_AC97);
        rINTSUBMSK &= ~(BIT_SUB_WDT);//開中斷

        接下來是設置中斷的起始地址,將中斷服務程序的起始地址映射到內存。

        pISR_WDT_AC97=(unsigned)Wdt_Int;//設置中斷程序入口

        我們進入中斷服務程序看看:

        ——————————————————————————————————————————————

        void __irq Wdt_Int(void)
        {
        rSRCPND |=BIT_WDT_AC97;
        rINTPND |=BIT_WDT_AC97;
        rSUBSRCPND |= BIT_SUB_WDT; //清除中斷標志
        rGPBDAT =1; //蜂鳴器響
        Delay();
        rGPBDAT =0; //蜂鳴器響一段時間
        }

        ——————————————————————————————————————————————

        進入中斷服務程序后,首先清楚中斷標志,接著讓蜂鳴器響一下,接著關閉。

        最后進入死循環(huán),前面四句是循環(huán)點亮LED燈,接著重新賦值給WTCNT,實現喂狗功能。

        rWTCNT=50000; //喂狗 沒喂狗蜂鳴器很響

        ——————————————————————————————————————————————

        到這里,我們WATCHDOG 定時器的講解結束啦。



        評論


        技術專區(qū)

        關閉
        主站蜘蛛池模板: 桂阳县| 外汇| 淮阳县| 图片| 桃江县| 庆安县| 土默特左旗| 仙居县| 巴南区| 方山县| 郯城县| 封开县| 图木舒克市| 杭锦后旗| 阿城市| 常熟市| 东台市| 宜阳县| 广州市| 周至县| 惠水县| 株洲市| 永康市| 中西区| 尼勒克县| 剑河县| 上虞市| 泾源县| 盐亭县| 商丘市| 金华市| 皋兰县| 象山县| 中方县| 稷山县| 辉南县| 商河县| 罗定市| 县级市| 伊金霍洛旗| 株洲市|