天天看點

stm32F4看門狗——随手筆記

文章目錄

      • 獨立看門狗IWDG
      • IWDG函數操作
      • 視窗看門狗WWDG
      • WWDG函數操作

獨立看門狗IWDG

stm32F4看門狗——随手筆記

溢出時間=重裝載值* 分頻系數 * 時鐘周期

//初始化獨立看門狗

//prer:分頻數:0~7(隻有低3位有效!)

//rlr:自動重裝載值,0~0XFFF.

//分頻因子=4* 2^prer.但最大值隻能是256!

//rlr:重裝載寄存器值:低11位有效.

//時間計算(大概):Tout=((4*2^prer)*rlr)/32 (ms).

IWDG函數操作

  • void IWDG_Init(u8 prer,u16 rlr);//IWDG初始化,預分頻系數,重裝載值
//初始化獨立看門狗
//prer:分頻數:0~7(隻有低3位有效!)
//rlr:自動重裝載值,0~0XFFF.
//分頻因子=4*2^prer.但最大值隻能是256!
//rlr:重裝載寄存器值:低11位有效.
//時間計算(大概):Tout=((4*2^prer)*rlr)/32 (ms).
void IWDG_Init(u8 prer,u16 rlr)
{
	IWDG_WriteAccessCmd(IWDG_WriteAccess_Enable); //使能對IWDG->PR IWDG->RLR的寫,取消寄存器寫保護
	
	IWDG_SetPrescaler(prer); //設定IWDG(獨立看門狗)分頻系數,确定時鐘

	IWDG_SetReload(rlr);   //設定IWDG(獨立看門狗)裝載值,确定溢出時間

	IWDG_ReloadCounter(); //reload應用程式喂狗
	
	IWDG_Enable();       //使能看門狗
}

//喂獨立看門狗
void IWDG_Feed(void)
{
	IWDG_ReloadCounter();//reload
}
           

主函數:

#include "sys.h"
#include "delay.h"
#include "usart.h"
#include "led.h"
#include "beep.h"
#include "key.h"
#include "iwdg.h"


//ALIENTEK 探索者STM32F407開發闆 實驗6
//獨立看門狗實驗 -庫函數版本
//技術支援:www.openedv.com
//淘寶店鋪:http://eboard.taobao.com
//廣州市星翼電子科技有限公司   
//作者:正點原子 @ALIENTEK


int main(void)
{ 
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//設定系統中斷優先級分組2
	delay_init(168);  //初始化延時函數
	LED_Init();				//初始化LED端口
	KEY_Init();		  	//初始化按鍵
	delay_ms(100);    //延時100ms (為了讓眼睛感受到它滅的時間)
	IWDG_Init(4,500); //預分頻數為64,重載值為500,溢出時間為1s	
	LED0=0;					  //先點亮紅燈
	while(1)
	{
		//不斷檢測按鍵是否按下
		if(KEY_Scan(0)==WKUP_PRES)//如果WK_UP按下,則喂狗
		{
			IWDG_Feed();//喂狗
		}
		delay_ms(10);
	};

}

           
stm32F4看門狗——随手筆記

時鐘頻率LSI是32k,

IWDG_Init(4,500); //預分頻數為64,重載值為500,溢出時間為1s

根據上表格,PR為4時,預分頻數為64,則時鐘是32K/64==0.5KHz的計數頻率,即一個時鐘周期是1/(0.5* 1000)=0.002s=2ms,這時若我們要讓最大溢出時間為1s,則設定重裝載值為500,則2ms*500=1s

同理,比如要溢出時間為2s,可以是 IWDG_Init(3,2000);也可以是IWDG_Init(4,1000);

在主函數中不斷檢測按鍵達到這樣的目的:若我們不斷按按鍵,則不斷喂狗,最大溢出時間為1s,若沒有按鍵沒有喂狗,即超過1s都沒有按按鍵,則會産生複位,則led0會熄滅一下。

視窗看門狗WWDG

它和獨立看門狗的差別在于它可以設定喂狗的上限時間

stm32F4看門狗——随手筆記

若在不可喂狗時間(上限時間之前)喂狗,則會産生複位信号

stm32F4看門狗——随手筆記

兩種會産生複位的情況:

1、計數器的值大于上視窗的值(上圖中T6>W6産生1和啟動位1與結果為1)

2、計數溢出還沒有喂狗,CNT為3FH,T6位為0,經過或門為1,和動位1與結果為1(如上圖筆記)

stm32F4看門狗——随手筆記

另外有一個早期喚醒中斷,在計數到0x40的時候産生這個中斷,提醒:“你再不喂狗就要複位了!!”的資訊,然後便可以在中斷處理函數裡面喂狗以防止産生複位。

stm32F4看門狗——随手筆記
stm32F4看門狗——随手筆記

WWDG函數操作

stm32F4看門狗——随手筆記
stm32F4看門狗——随手筆記

wwdg.c:

#include "wwdg.h"
#include "led.h"
//	 
//本程式隻供學習使用,未經作者許可,不得用于其它任何用途
//ALIENTEK STM32F407開發闆
//看門狗 驅動代碼	   
//正點原子@ALIENTEK
//技術論壇:www.openedv.com
//建立日期:2014/6/12
//版本:V1.0
//版權所有,盜版必究。
//Copyright(C) 廣州市星翼電子科技有限公司 2014-2024
//All rights reserved				
//********************************************************************************
//V1.1 20140504
//增加了視窗看門狗相關函數。
// 

//儲存WWDG計數器的設定值,預設為最大. 
u8 WWDG_CNT=0X7F;
//初始化視窗看門狗 	
//tr   :T[6:0],計數器值,初值 
//wr   :W[6:0],視窗值,上視窗值 
//fprer:分頻系數(WDGTB),僅最低2位有效 
//Fwwdg=PCLK1/(4096*2^fprer). 一般PCLK1=42Mhz
void WWDG_Init(u8 tr,u8 wr,u32 fprer)
{
 
	NVIC_InitTypeDef NVIC_InitStructure;
 
	
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_WWDG,ENABLE); //使能視窗看門狗時鐘
	
	WWDG_CNT=tr&WWDG_CNT;   //初始化WWDG_CNT. 相與是因為寄存器中計數器隻用到了tr中的低7位
	WWDG_SetPrescaler(fprer); //設定分頻值/預分頻系數
	WWDG_SetWindowValue(wr); //設定視窗值
//	WWDG_SetCounter(WWDG_CNT);//設定計數值
	WWDG_Enable(WWDG_CNT);  //開啟看門狗
	
	NVIC_InitStructure.NVIC_IRQChannel=WWDG_IRQn;  //視窗看門狗中斷
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=0x02;  //搶占優先級為2
	NVIC_InitStructure.NVIC_IRQChannelSubPriority=0x03;					//子優先級為3
	NVIC_InitStructure.NVIC_IRQChannelCmd=ENABLE;  //使能視窗看門狗
	NVIC_Init(&NVIC_InitStructure);
	
	WWDG_ClearFlag();//清除提前喚醒中斷标志位
  WWDG_EnableIT();//開啟提前喚醒中斷
}



//視窗看門狗中斷服務程式 0x40的時候産生該中斷
void WWDG_IRQHandler(void)
{
	WWDG_SetCounter(WWDG_CNT); //重設視窗看門狗值
	WWDG_ClearFlag();//清除提前喚醒中斷标志位
	LED1=!LED1;//不停喂狗則DS1不停的閃爍
}

           

main

#include "sys.h"
#include "delay.h"
#include "usart.h"
#include "led.h"
#include "beep.h"
#include "key.h"
#include "wwdg.h"


//ALIENTEK 探索者STM32F407開發闆 實驗7
//視窗看門狗實驗 -庫函數版本
//技術支援:www.openedv.com
//淘寶店鋪:http://eboard.taobao.com
//廣州市星翼電子科技有限公司    
//作者:正點原子 @ALIENTEK 

int main(void)
{ 
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//設定系統中斷優先級分組2
	delay_init(168);  //初始化延時函數
	LED_Init();				//初始化LED端口
	KEY_Init();		  	//初始化按鍵
	LED0=0;				   //點亮LED0
	delay_ms(300);//複位後亮300ms
	
	WWDG_Init(0x7F,0X5F,WWDG_Prescaler_8); 	//計數器值為7f,視窗寄存器為5f,分頻數為8	   
	
	while(1)
	{
		LED0=1;  //熄滅LED燈
	}
}

           

實驗現象:

本實驗, 程式一運作則開啟WWDG,并使得DS0亮300ms後關閉,進入死循環。等待WWDG中斷的

到來,在中斷裡面,喂狗,并執行DS1的翻轉操作。是以可以看到DS1不停的閃爍,而DS0隻在

剛啟動的時候閃一下。

繼續閱讀