天天看點

6-STM32F1 -獨立看門狗

STM32F1 -獨立看門狗
(這裡有部分内容是拷貝原子哥的)
STM32F1的看門狗需要手動打開,而且打開後不能關閉,想要關閉看門狗唯一的辦法是複位,然後啟動時不打開看門狗。是以使用看門狗前需要考慮清楚。
STM32 的獨立看門狗由内部專門的 40Khz 低速時鐘驅動,即使主時鐘發生故障,它也仍然有效。這裡需要注意獨立看門狗的時鐘是一個内部 RC 時鐘,是以并不是準确的 40Khz,而是在 30~60Khz 之間的一個可變化的時鐘,隻是我們在估算的時候,以 40Khz 的頻率來計算,看門狗對時間的要求不是很精确,是以,時鐘有些偏差,都是可以接受的。 

設定看門狗的分頻系數的函數是:
void IWDG_SetPrescaler(uint8_t IWDG_Prescaler); //設定 IWDG 預分頻值

設定看門狗的重裝載值的函數是:
void IWDG_SetReload(uint16_t Reload); //設定 IWDG 重裝載值

設定好看門狗的分頻系數 prer 和重裝載值就可以知道看門狗的喂狗時間(也就是看門狗溢出時間),該時間的計算方式為:
Tout=((4×2^prer) ×rlr) /40
其中 Tout 為看門狗溢出時間(機關為 ms); prer 為看門狗時鐘預分頻值(IWDG_PR 值),範圍為 0~7; rlr 為看門狗的重裝載值(IWDG_RLR 的值);比如我們設定 prer 值為 4, rlr 值為 625,那麼就可以得到 Tout=64×625/40=1000ms,這樣,看門狗的溢出時間就是 1s, 隻要你在一秒鐘之内,有一次寫入 0XAAAA 到 IWDG_KR,就不會導緻看門狗複位(當然寫入多次也是可以的)。這裡需要提醒大家的是,看門狗的時鐘不是準确的 40Khz,是以在喂狗的時候,最好不要太晚了,否則,有可能發生看門狗複位。 

設定看門狗步驟
1,打開看門狗設定的鎖,隻有開鎖後才能設定看門狗
2,設定分頻值
3,設定重裝值
4,先喂狗一次
5,使能看門狗
6,看門狗配置完畢,剩下的就是有空就喂狗了,

代碼如下;
#include "sys.h"
#include "delay.h"
/************************************************************
功能,初始化LED滅,按下按鍵後LED點亮,按一次按鍵喂狗一次,如果看門狗不溢出LED會一直亮,如果不喂狗晶片複位後LED會熄滅。

看門狗時間計算(大概):Tout=((4*2^prer)*rlr)/40 (ms).
其中prer為分頻值,rlr為預裝載值

其中LED接在PB5上,低電平有效
按鍵接在PE4上,低電平有效

****************************************************************/

void init_led()
{
	GPIO_InitTypeDef GPIO_InitStruct;//GPIO結構體
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);//打開GPIOB時鐘

	GPIO_InitStruct.GPIO_Mode=GPIO_Mode_Out_PP;//推挽輸出
	GPIO_InitStruct.GPIO_Pin=GPIO_Pin_5;//PB5
	GPIO_InitStruct.GPIO_Speed=GPIO_Speed_10MHz;//翻轉速度=10MHZ
	GPIO_Init(GPIOB, &GPIO_InitStruct);
	GPIO_WriteBit(GPIOB,GPIO_Pin_5,1);//初始化輸出1吧
}
void init_key()
{
	GPIO_InitTypeDef GPIO_InitStruct;//GPIO結構體
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOE,ENABLE);//打開GPIOE時鐘

	GPIO_InitStruct.GPIO_Mode=GPIO_Mode_IPU;//低電平有效,是以設定為上拉輸入
	GPIO_InitStruct.GPIO_Pin=GPIO_Pin_4;//PE4
	//GPIO_InitStruct.GPIO_Speed=GPIO_Speed_10MHz;//輸入是不需要設定翻轉速度的
	GPIO_Init(GPIOE, &GPIO_InitStruct);
}

void init_my_watchdog()
{
	IWDG_WriteAccessCmd(IWDG_WriteAccess_Enable);//開鎖
	IWDG_SetPrescaler(4);//分頻0-255
	IWDG_SetReload(625);//重裝值
	//4分頻,重裝值624,看門狗溢出時間大概為1000ms
	
	IWDG_ReloadCounter();//喂狗
	IWDG_Enable();//使能看門狗
}
 int main(void)
 {	
	delay_init();	//延時函數初始化
	init_led();	 //LED初始化
	init_key();//按鍵初始化
	init_my_watchdog();//看門狗初始化
	while(1)
	{
		if(GPIO_ReadInputDataBit(GPIOE,GPIO_Pin_4)==0)//位讀取按鍵IO,按一次按鍵喂狗一次
		{
			GPIO_WriteBit(GPIOB,GPIO_Pin_5,0);//點亮LED
			IWDG_ReloadCounter();//喂狗
		}
	}
 }