新聞中心

        EEPW首頁 > 嵌入式系統(tǒng) > 設(shè)計應(yīng)用 > stm32 獨立看門狗[操作寄存器+庫函數(shù)]

        stm32 獨立看門狗[操作寄存器+庫函數(shù)]

        作者: 時間:2016-11-30 來源:網(wǎng)絡(luò) 收藏
        以單片機為核心的微型計算機系統(tǒng)中,單片機經(jīng)常會受到來自外界電磁場的干擾。

        造成程序跑飛,只是程序的正常運行狀態(tài)被打斷而進入死循環(huán),從而使單片機控制的系統(tǒng)無法正常工作??撮T狗就是一種專門用于檢測單片機程序運行狀態(tài)的硬件結(jié)構(gòu)。

        stm32也是如此。

        stm32的獨立看門狗由內(nèi)部專門的40Khz低速時鐘驅(qū)動,即使主時鐘發(fā)生故障時,它也仍然有效。這里需要注意的是獨立看門狗的時鐘是一個內(nèi)部時鐘,所以不是準確的40Khz,而是在30~60Khz之間的一個可變化的時鐘,看門狗的時鐘對時間的要求不是很精確,所以時鐘有偏差可以接受。

        本例直接操作寄存器實現(xiàn)驗證獨立看門狗的復位功能,設(shè)定一個800ms的喂狗時間,在主函數(shù)中實現(xiàn)LED閃爍,如果設(shè)定一個1s的延時,則觸發(fā)獨立看門狗復位,LED常亮。
        庫函數(shù)實現(xiàn)當外部中斷發(fā)生(按下PA0按鍵),長時間不喂狗,引發(fā)獨立看門狗復位時,向外用串口輸出復位提示。


        直接操作寄存器

        使用獨立看門狗,需要了解一下寄存器:

        鍵值寄存器:(IWDG_KR)
        低16位有效的寄存器,只寫寄存器,讀出值恒為0x0000.
        軟件必須以一定的間隔寫入0xAAAA,否則,當計數(shù)器為0時,看門狗會產(chǎn)生復位。
        寫入0x5555表示允許訪問IWDG_PR和IWDG_RLR寄存器。
        寫入0xCCCC,啟動看門狗工作。

        預分頻寄存器:(IWDG_PR)
        第三位有效寄存器,用于設(shè)置看門狗的分頻系數(shù),最低為4,最高位256.
        通過設(shè)置PR[2:0]:位來選擇計數(shù)器時鐘的預分頻因子。要改變預分頻因子,IWDG_SR寄存器的PVU位必須為0。

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

        000: 預分頻因子=4 100: 預分頻因子=64
        001: 預分頻因子=8 101: 預分頻因子=128
        010: 預分頻因子=16 110: 預分頻因子=256
        011: 預分頻因子=32 111: 預分頻因子=256

        重裝載寄存器:(IWDG_RLR)
        低12位有效,RL[11:0]。用于定義看門狗計數(shù)器的重裝載值。
        每當向IWDG_KR寄存器寫入0xAAAA時,重裝載值會被傳送到計數(shù)器中。隨后計數(shù)器從這個值開始遞減計數(shù)。看門狗超時周期可通過此重裝載值和時鐘預分頻值來計算。 只有當IWDG_SR寄存器中的RVU位為0時,才能對此寄存器進行修改。

        狀態(tài)寄存器:(IWDG_SR)
        只有低兩位有效。都由硬件置’1’和 清’0’。
        RVU[1]: 看門狗計數(shù)器重裝載值更新
        PVU[0]:看門狗預分頻值更新

        代碼如下: (system.h 和 stm32f10x_it.h 等相關(guān)代碼參照 stm32 直接操作寄存器開發(fā)環(huán)境配置)
        User/main.c
        01 #include
        02 #include "system.h"
        03 #include "wdg.h"
        04
        05 #define LED1 PAout(4)
        06 #define LED2 PAout(5)
        07
        08 void Gpio_Init(void);
        09
        10 int main(void)
        11 {
        12
        13 Rcc_Init(9); //系統(tǒng)時鐘設(shè)置
        14
        15 Gpio_Init();
        16
        17 Iwdg_Init(3,1000); //設(shè)定為800ms內(nèi)喂狗
        18
        19 while(1){
        20
        21 LED1 = !LED1;
        22
        23 delay(100000); //延時100ms后喂狗,LED閃爍
        24
        25 //delay(1000000); //延時1000ms,引發(fā)獨立看門狗復位,LED不閃爍
        26
        27 Iwdg_Feed(); //喂狗
        28
        29 }
        30
        31 }
        32
        33
        34 void Gpio_Init(void)
        35 {
        36 RCC->APB2ENR|=1<<2; //使能PORTA時鐘
        37
        38 GPIOA->CRL&=0x0000FFFF; // PA0~3設(shè)置為浮空輸入,PA4~7設(shè)置為推挽輸出
        39 GPIOA->CRL|=0x33334444;
        40
        41 }
        Library/wdg.c (此文件包含了獨立看門狗和窗口看門狗的驅(qū)動函數(shù))
        01 #include
        02 #include "wdg.h"
        03
        04 /********************************************
        05 *
        06 *本文件包含窗口看門狗和獨立看門口的相關(guān)函數(shù)
        07 *
        08 *********************************************/
        09
        10 u8 Wwdg_Cnt = 0x7F; //計數(shù)器值,默認為最大值127
        11
        12 //獨立看門狗初始化
        13 //參數(shù)說明:
        14 // pre:分頻數(shù)(0~7),相應(yīng)分頻因子為4*(2^pre)
        15 // rlr:低12位有[11:0]
        16 // 喂狗時間計算: T = (4*(2^pre)*rlr)/40;(ms)
        17 void Iwdg_Init(u8 pre,u16 rlr)
        18 {
        19 IWDG ->KR = 0x5555; //使能對PR RLR寄存器的寫操作
        20 IWDG ->PR =pre; //設(shè)置分頻數(shù)
        21 IWDG ->RLR = rlr; //設(shè)定重裝值
        22 IWDG ->KR = 0xAAAA; //裝載RLR值到看門狗計數(shù)器,即喂狗
        23 IWDG ->KR = 0xCCCC; //啟動看門狗
        24 }
        25
        26 //獨立看門狗喂狗
        27 void Iwdg_Feed()
        28 {
        29 IWDG -> KR = 0xAAAA; //喂狗
        30 }
        31
        32 //窗口看門狗初始化
        33 //參數(shù)說明:
        34 // cnt計數(shù)器的值,最大 127,0x7F
        35 // w_cnt 窗口值,最大 127,0x7F
        36 //pre 預分頻器的時基值,低兩位有效;實際時鐘為: PLCK1/4096/2^pre
        37 //需要再主函數(shù)中開啟中斷 WWDG_IRQChannel
        38 //設(shè)定喂狗時間范圍必須在:(WWDG時鐘為PCLK1,36Mhz)
        39 // Tmax =(4096*2^pre*(cnt-63)/36) (us)
        40 // Tmin =(4096*2^pre*(cnt-w_cnt)/36) (us)
        41 //超出次時間喂狗復位
        42
        43 void Wwdg_Init(u8 cnt,u8 w_cnt,u8 pre)
        44 {
        45 u8 Cnt_Max = 0x7f; //計數(shù)器最大值
        46
        47 Wwdg_Cnt = Cnt_Max&cnt; //設(shè)定計數(shù)器的值,防止溢出
        48
        49 RCC->APB1ENR |= 1<<11;
        50
        51 WWDG -> CFR |=pre<<7; //設(shè)定預分頻器的時基,實際分頻值我
        52 WWDG -> CFR |= 1<<9; //使能中斷
        53
        54 WWDG -> CFR &= 0xFF80; //初始化低七位,即窗口值清0
        55 WWDG -> CFR |= w_cnt; // 設(shè)定窗口值
        56
        57 WWDG -> CR |= Wwdg_Cnt|(1<<7); //設(shè)定計數(shù)器值,并激活開門狗
        58
        59 }
        60
        61 //窗口看門狗喂狗
        62
        63 void Wwdg_Feed()
        64 {
        65 WWDG->CR |= (Wwdg_Cnt&0x7F);
        66
        67 }
        Library/wdg.h
        1 #include
        2
        3 void Iwdg_Init(u8pre,u16 rlr);
        4 void Iwdg_Feed(void);
        5
        6 void Wwdg_Init(u8 cnt,u8 w_cnt,u8);
        7 void Wwdg_Feed(void);

        需要注意的是 獨立看門狗沒有響應(yīng)的中斷。


        上一頁 1 2 下一頁

        評論


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

        關(guān)閉
        主站蜘蛛池模板: 竹北市| 武鸣县| 霍城县| 余庆县| 宜昌市| 乌兰浩特市| 绍兴市| 大同县| 施秉县| 西乡县| 岢岚县| 漠河县| 湖口县| 南充市| 沐川县| 双柏县| 静宁县| 高陵县| 青海省| 江门市| 宿迁市| 平定县| 云阳县| 永定县| 柯坪县| 临高县| 朝阳市| 定边县| 菏泽市| 高雄市| 利辛县| 宁蒗| 永春县| 合阳县| 临城县| 开原市| 河源市| 江口县| 喜德县| 定安县| 临武县|