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