文章目錄
-
-
- 獨立看門狗IWDG
- IWDG函數操作
- 視窗看門狗WWDG
- WWDG函數操作
-
獨立看門狗IWDG
溢出時間=重裝載值* 分頻系數 * 時鐘周期
//初始化獨立看門狗
//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);
};
}
時鐘頻率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
它和獨立看門狗的差別在于它可以設定喂狗的上限時間
若在不可喂狗時間(上限時間之前)喂狗,則會産生複位信号
兩種會産生複位的情況:
1、計數器的值大于上視窗的值(上圖中T6>W6産生1和啟動位1與結果為1)
2、計數溢出還沒有喂狗,CNT為3FH,T6位為0,經過或門為1,和動位1與結果為1(如上圖筆記)
另外有一個早期喚醒中斷,在計數到0x40的時候産生這個中斷,提醒:“你再不喂狗就要複位了!!”的資訊,然後便可以在中斷處理函數裡面喂狗以防止産生複位。
WWDG函數操作
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隻在
剛啟動的時候閃一下。