14.1 STM32看門狗簡介
在單片機(jī)構(gòu)成的微型計(jì)算機(jī)系統(tǒng)中,單片機(jī)的工作可能會受到外界的電磁干擾或者程序運(yùn)行的BUG導(dǎo)致程序指針錯(cuò)誤,或者其他錯(cuò)誤導(dǎo)致的死循環(huán),引發(fā)整個(gè)系統(tǒng)陷入停滯狀態(tài),所以需要一個(gè)與系統(tǒng)獨(dú)立的定時(shí)器來監(jiān)控單片機(jī)的運(yùn)行狀態(tài),這個(gè)定時(shí)器在系統(tǒng)正常運(yùn)轉(zhuǎn)的時(shí)候,不停的刷新定時(shí)器的計(jì)數(shù)器,例如隔一段時(shí)間給這個(gè)定時(shí)器的計(jì)數(shù)器寫100,然后在定時(shí)器減運(yùn)算到0之前再一次寫入100,這樣,就保證了定時(shí)器不計(jì)數(shù)到0,也就意味著通過判斷這個(gè)定時(shí)器是否計(jì)數(shù)到0來判斷系統(tǒng)是否陷入死機(jī)狀態(tài),實(shí)現(xiàn)這種功能的定時(shí)器就稱為看門狗,不停的刷新計(jì)數(shù)器值的行為就稱為“喂狗”,一般計(jì)數(shù)器計(jì)數(shù)到0后會直接對單片機(jī)進(jìn)行復(fù)位,用于避免系統(tǒng)陷入死循環(huán)。
STM32內(nèi)部有兩種看門狗模塊,一種是窗口看門狗WWDG,另一種是獨(dú)立看門狗IWDG,STM32的獨(dú)立看門狗由內(nèi)部專門的40Khz低速時(shí)鐘驅(qū)動,即使主時(shí)鐘發(fā)生故障,它也仍然有效。
獨(dú)立看門狗的時(shí)鐘是一個(gè)內(nèi)部RC時(shí)鐘,所以并不是準(zhǔn)確的40Khz,而是在30~60Khz之間的一個(gè)可變化的時(shí)鐘,只是我們在估算的時(shí)候,以40Khz的頻率來計(jì)算。
窗口看門狗通常被用來監(jiān)測由外部干擾或不可預(yù)見的邏輯條件造成的應(yīng)用程序背離正常的運(yùn)行序列而產(chǎn)生的軟件故障。除非遞減計(jì)數(shù)器的值在T6位變成0前被刷新,看門狗電路在達(dá)到預(yù)置的時(shí)間周期時(shí),會產(chǎn)生一個(gè)MCU復(fù)位。
在遞減計(jì)數(shù)器達(dá)到窗口配置寄存器數(shù)值之前,如果7位的遞減計(jì)數(shù)器數(shù)值在控制寄存器中被刷新,那么也將產(chǎn)生一個(gè)MCU復(fù)位。這表明遞減計(jì)數(shù)器需要在一個(gè)有限的時(shí)間窗口中被刷新。
14.2 獨(dú)立看門狗相關(guān)寄存器
14.2.1 鍵值寄存器IWDG_KR
15 | 14 | 13 | 12 | 11 | 10 | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
KEY[15:0] |
該寄存器屬于只寫寄存器,讀取的值為0x0000,軟件必須以一定間隔寫入0xAAAA,否則,當(dāng)計(jì)數(shù)器為0時(shí),看門狗會產(chǎn)生復(fù)位;
寫入0x5555表示允許訪問IWDG_PR和IWDG_RLR寄存器;
寫入0xCCCC表示啟動看門狗工作,如果選擇了硬件看門狗則不受此命令字限制。
14.2.2 預(yù)分頻寄存器IWDG_PR
15 | 14 | 13 | 12 | 11 | 10 | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
- | PR[2:0] |
Bit 2~Bit 0:預(yù)分頻因子
000:預(yù)分頻因子=4
001:預(yù)分頻因子=8
010:預(yù)分頻因子=16
011:預(yù)分頻因子=32
100:預(yù)分頻因子=64
101:預(yù)分頻因子=128
110:預(yù)分頻因子=256
111:預(yù)分頻因子=256
14.2.3 重裝載寄存器IWDG_RLR
15 | 14 | 13 | 12 | 11 | 10 | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
- | RLR[11:0] |
Bit 11~Bit 0:看門狗計(jì)數(shù)器重裝載值:每當(dāng)向IWDG_KR寄存器寫入0xAAAA時(shí),重裝載值會被傳送到計(jì)數(shù)器中,隨后計(jì)數(shù)器從這個(gè)值開始遞減計(jì)數(shù)。
14.3 窗口看門狗相關(guān)寄存器
14.3.1 控制寄存器WWDG_CR
15 | 14 | 13 | 12 | 11 | 10 | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
- | WDGA | T6 | T5 | T4 | T3 | T2 | T1 | T0 |
Bit 7:激活位:,此位由軟件置1,但僅能由硬件在復(fù)位后清0。當(dāng)WDGA=1時(shí),看門狗可以產(chǎn)生復(fù)位
0:禁止看門狗
1:啟用看門狗
Bit 6~Bit 0:7位計(jì)數(shù)器,存儲看門狗的計(jì)數(shù)器值。每(4096x2 ^WDGTB^ )個(gè)PCLK1周期減1。當(dāng)T6變成0產(chǎn)生看門狗復(fù)位
14.3.2 配置寄存器WWDG_CFR
15 | 14 | 13 | 12 | 11 | 10 | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
- | EWI | TB1 | TB0 | W6 | W5 | W4 | W3 | W2 | W1 | W0 |
Bit 9:提前喚醒中斷,此位若置1,則當(dāng)計(jì)數(shù)器值達(dá)到40h,即產(chǎn)生中斷,此中斷只能由硬件在復(fù)位后清除
Bit 8:預(yù)分頻器時(shí)基
00:CK計(jì)時(shí)器時(shí)鐘不分頻
01:CK計(jì)時(shí)器時(shí)鐘2分頻
10:CK計(jì)時(shí)器時(shí)鐘4分頻
11:CK計(jì)時(shí)器時(shí)鐘8分頻
Bit6~Bit 5:7位窗口值,用來與遞減計(jì)數(shù)器進(jìn)行比較用的窗口值
14.3.3 狀態(tài)寄存器WWDG_SR
15 | 14 | 13 | 12 | 11 | 10 | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
- | EWIF |
Bit 0:提前喚醒中斷標(biāo)志,當(dāng)計(jì)數(shù)器值達(dá)到40h時(shí),此位由硬件置1。它必須通過軟件寫0來清除。若中斷未被使能,此位也會被置1
14.4 實(shí)驗(yàn)例程
14.4.1 獨(dú)立看門狗實(shí)驗(yàn)
功能:如果看門狗沒有復(fù)位,接在PB5上的LED常亮,如果PA0的按鍵按下,就喂狗,只要按鍵不停的按,看門狗就一直不會產(chǎn)生復(fù)位,保持DS0的常亮,一旦超過看門狗定溢出時(shí)間,那么將導(dǎo)致程序重啟,這將導(dǎo)致DS0熄滅一次。
(1)創(chuàng)建wdg.h文件輸入以下代碼。
#ifndef _WDG_H_
#define _WDG_H_
#include "sys.h"
/*********************************************************************************************************
函 數(shù) 列 表
*********************************************************************************************************/
void IWDG_Init( u8 prer, u16 rlr ) ; //獨(dú)立看門狗初始化
#endif
(2)創(chuàng)建wdg.c文件輸入以下代碼。
#include "wdg.h"
/***************************************************
Name :IWDG_Init
Function :獨(dú)立看門狗初始化
Paramater :
prer:分頻數(shù):0~7
rlr:重裝載寄存器值
Return :None
***************************************************/
void IWDG_Init( u8 prer, u16 rlr )
{
IWDG->KR = 0x5555 ; //使能對IWDG->PR和IWDG->RLR的寫
IWDG->PR = prer ; //設(shè)置分頻系數(shù)
IWDG->RLR = rlr ; //從加載寄存器 IWDG->RLR
IWDG->KR = 0xAAAA ; //更新計(jì)數(shù)器
IWDG->KR = 0xCCCC ; //使能看門狗
}
(3)在1.c文件中輸入以下代碼。
#include "sys.h"
#include "delay.h"
#include "usart1.h"
#include "wdg.h"
/***************************************************
Name :LED_Init
Function :LED初始化
Parameter :None
Return :None
***************************************************/
#define LED PBout( 5 ) //定義LED端口
void LED_Init()
{
RCC->APB2ENR |= 1<<3 ;
GPIOB->CRL &= 0xFF0FFFFF ;
GPIOB->CRL |= 0x00300000 ;
LED = 1 ;
}
/***************************************************
Name :KEY_Init
Function :KEY初始化
Parameter :None
Return :None
***************************************************/
#define KEY PAin( 0 ) //定義按鍵端口
void KEY_Init()
{
RCC->APB2ENR |= 1<<2 ;
GPIOA->CRL &= 0xFFFFFFF0 ;
GPIOA->CRL |= 0x00000008;
}
/***************************************************
Name :main
Function :主函數(shù)
Parameter :None
Return :None
***************************************************/
int main()
{
STM32_Clock_Init( 9 ) ; //STM32時(shí)鐘初始化
SysTick_Init( 72 ) ; //SysTick初始化
USART1_Init( 72, 115200 ) ; //初始化串口1波特率115200
LED_Init() ; //LED初始化
KEY_Init() ; //按鍵初始化
delay_ms( 500 ) ; //延時(shí)500ms,讓人可以看到DS0滅的狀態(tài)
IWDG_Init( 4, 625 ) ; //與分頻數(shù)為64,重載值為625,溢出時(shí)間為1s
LED = 0 ; //點(diǎn)亮DS0
while( 1 )
{
if( KEY==1 )
{
delay_ms( 10 ) ;
if( KEY==1 )
{
IWDG->KR = 0xAAAA ; //喂狗
}
}
delay_ms( 20 ) ;
}
}
-
單片機(jī)
+關(guān)注
關(guān)注
6040文章
44605瀏覽量
637140 -
看門狗
+關(guān)注
關(guān)注
10文章
566瀏覽量
70889 -
STM32
+關(guān)注
關(guān)注
2270文章
10918瀏覽量
356868 -
計(jì)數(shù)器
+關(guān)注
關(guān)注
32文章
2259瀏覽量
94831 -
定時(shí)器
+關(guān)注
關(guān)注
23文章
3254瀏覽量
115113
發(fā)布評論請先 登錄
相關(guān)推薦
評論