STM32獨立看門狗(IWDG)


引言

在單片機運行的過程中,我們可能會遇到程序陷入死循環的情況。很顯然我們需要對這種情況進行提前的預防。看門狗就是用來進行該工作的。看門狗分為獨立看門狗和窗口看門狗,這一節介紹的是獨立看門狗。




看門狗介紹

STM32的獨立看門狗由內部專門的40KHz低速時鍾驅動,與系統主時鍾分開工作,也就是說,主時鍾損壞時,看門狗仍然可以正常使用。這個低速時鍾是一個RC時鍾,並不是很精確,頻率在30~60KHz之間。

看門狗的作用就是在一定時間內(通過定時計數器實現) 沒有接收喂狗信號(表示 MCU 已經掛了),便實現處理器的自動復位重啟(發送復位信號)。

設置看門狗的步驟如下:

  • 取消寄存器寫保護
  • 設置獨立看門狗的預分頻系數和重裝載值
  • 喂狗(重載計數值)
  • 啟動看門狗

設預分頻系數為prer,重裝載值為rlr,則喂狗的時間計算公式為(T的單位為ms):

\[T=\frac{4 \times 2^{p r e r} \times r l r}{40} \]

$\frac{1}{40} $ 即 $\frac{1}{f} $ 是一個周期的長度,也就是計數器加一所需要的時間。\(4\times 2^{prer}\)是預分頻系數的值。預分頻系數乘以周期得到的是分頻后計數器加一所用的時間。而這個時間再乘以重裝載值rlr得到的是一次喂狗的時間。

可能有人會問,\(2^{prer}\)不是預分頻系數了嗎?為什么還要乘以4?這里可以看一下庫函數中對分頻系數的一系列預定義。

#define IWDG_Prescaler_4            ((uint8_t)0x00)
#define IWDG_Prescaler_8            ((uint8_t)0x01)
#define IWDG_Prescaler_16           ((uint8_t)0x02)
#define IWDG_Prescaler_32           ((uint8_t)0x03)
#define IWDG_Prescaler_64           ((uint8_t)0x04)
#define IWDG_Prescaler_128          ((uint8_t)0x05)
#define IWDG_Prescaler_256          ((uint8_t)0x06)

可以看到,當設置prer參數為0時,預分頻系數為4,也就是說,我們設置參數為0時,預分頻系數都不是0,而是4。因此,這里需要把這個4乘進去。




編碼

main.c

int main(void){
	delay_init();
    //下列幾個初始化函數在之前的博客中可以找到
	LED_Init();
	KEY_Init();
	IWDG_Init(4, 625);	//預分頻系數為4,重裝載數為625,喂狗時間約為1s。
	delay_ms(500);		//進行延遲,使led的滅掉可以看到。
	LED0 = 0;
	while(1){
		if(KEY_Scan() == 1){	//如果WK_UP按鍵按下,就進行喂狗。
			IWDG_Feed();
		}
		delay_ms(10);
	}
}

wdg.h

#ifndef __WDG_H
#define __WDG_H
#include "sys.h"

void IWDG_Init(u8 prer, u16 rlr);   //獨立看門狗初始化函數
void IWDG_Feed(void);               //喂狗函數

#endif

wdg.c

#include "wdg.h"

void IWDG_Init(u8 prer, u16 rlr){
	IWDG_WriteAccessCmd(IWDG_WriteAccess_Enable);	//取消寫保護
	IWDG_SetPrescaler(prer);	//設置預分頻系數
	IWDG_SetReload(rlr);		//設置重裝載值
	IWDG_ReloadCounter();		//重載計數器喂狗
	IWDG_Enable();				//使能看門狗
}

void IWDG_Feed(void){
	IWDG_ReloadCounter();		//重載計數器喂狗函數
}




至此,我們就完成了獨立看門狗的學習。為了手中單片機的性命,還是盡量讓看門狗發揮一點作用吧。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM