stm32 独立看门狗和窗口看门狗区别
原文地址https://www.cnblogs.com/pertor/p/9483445.html
一、使用調(diào)條件
二、特點(diǎn)對比?
三、手冊介紹
?
【注】圖中的WDGTB為3表示2^3=8,表示8分頻,最小時(shí)間910us也等于每次計(jì)數(shù)器減一所需要經(jīng)過的時(shí)間:T(LSB),每隔910us減1。最大值也等于,設(shè)置重載(喂狗)值127時(shí)(最大),一個(gè)復(fù)位周期的時(shí)間就是最大值58.25ms,也就是所能維持進(jìn)入復(fù)位的最大時(shí)間。
?
由于窗口看門狗使用的APB1的PCLK1,時(shí)鐘最高36MHZ,和RCC_APB2Periph_GPIOx不同,APB1最大就是36MHZ,APB2最大就是72MHZ。
所以串口看門狗需要配置APB1時(shí)鐘使能,如下語句。
可以從圖1-3 窗口看門狗編程說明紅看到T(WWDG)=T(PCLK1) x 4096 x 2^WDGTB x (T[5:0]+1)? ; (ms)
?
WDGTB[1:0]: 時(shí)基 (Timer base),也就是設(shè)置WDGTB 的值是1/2/4還是8,這在配置寄存器(WWDG_CFR)寄存器的位8:7 中設(shè)置,
其預(yù)分頻器的時(shí)基可以設(shè)置如下:
00: CK計(jì)時(shí)器時(shí)鐘(PCLK1除以4096)除以1
01: CK計(jì)時(shí)器時(shí)鐘(PCLK1除以4096)除以2
10: CK計(jì)時(shí)器時(shí)鐘(PCLK1除以4096)除以4
11: CK計(jì)時(shí)器時(shí)鐘(PCLK1除以4096)除以8
也可以直接用這個(gè)函數(shù)
1 WWDG_SetPrescaler(WWDG_Prescaler_8); //8預(yù)分頻,則WWDG時(shí)鐘頻率=(PCK1(36M)/4096)/8=1099Hz(910us)?也可以直接用這個(gè)函數(shù)
其次是設(shè)置窗口值,用來與遞減計(jì)數(shù)器進(jìn)行比較用的窗口值。通過如下函數(shù)即可
1 WWDG_SetWindowValue(80);//設(shè)置窗口值為80則WWDG的計(jì)數(shù)值必須在64~80之間才能喂狗(64是0x40,當(dāng)再次減1就會T6清零,從而導(dǎo)致復(fù)位了,即刷新窗口設(shè)置成了80-64,127-80也是不能更新值得否則也會復(fù)位)?應(yīng)當(dāng)注意:在窗口看門狗中,當(dāng)遞減計(jì)數(shù)器在窗口外被重新裝載,(若看門狗被啟動)則產(chǎn)生復(fù)位,也即是說在90-64外面使用這個(gè)重載函數(shù),會有問題發(fā)生
最后我們設(shè)置?(T[5:0]+1)的值,這里我們設(shè)置最大127,代碼如下,以后每次喂狗也可以用這個(gè)函數(shù)進(jìn)行重載計(jì)數(shù)值(喂狗)。
1 WWDG_Enable(127)?因?yàn)檫@是會導(dǎo)致產(chǎn)生復(fù)位,所以重載的窗口一定要設(shè)置好。
總結(jié)就是我們使用串口看門狗應(yīng)該先配置寄存器(WWDG_CFR),即配置窗口值是多少到最小的0x40*T(LSB)(假定T(LSB)為每減一計(jì)數(shù)所需要的時(shí)間),這個(gè)配置會告訴單片機(jī)什么時(shí)候來與遞減計(jì)數(shù)器進(jìn)行值比較,如果計(jì)數(shù)值值小于0x40就產(chǎn)生復(fù)位。
當(dāng)然,本例中如果你在減減計(jì)數(shù)值還在0x7E~0x50(127~80)之間就重載計(jì)數(shù)值(喂狗)同樣會導(dǎo)致芯片復(fù)位。所以窗口的概念一定要理解好,在窗內(nèi)才可以重載計(jì)數(shù)值(喂狗),這樣才不會莫名被復(fù)位。
?最終的初始化窗口看門狗的配置函數(shù)(WWDG)如下:
/************************************************************* Function : WWDGReste_Init Description: 窗口看門狗定時(shí)器 Input : none return : none *************************************************************/ void WWDGReste_Init(void) {RCC_APB1PeriphClockCmd(RCC_APB1Periph_WWDG, ENABLE);//WWDG連接在PCLK1(36M)的時(shí)鐘線上WWDG_SetPrescaler(WWDG_Prescaler_8); //8預(yù)分頻,則WWDG時(shí)鐘頻率=(PCK1(36M)/4096)/8=1099Hz(910us)WWDG_SetWindowValue(80);//設(shè)置窗口值為80則WWDG的計(jì)數(shù)值必須在64~80之間才能喂狗(64是0x40,當(dāng)再次減1就會T6清零,從而導(dǎo)致復(fù)位了)//設(shè)置WWDG計(jì)數(shù)值為127,超時(shí)時(shí)間=910us*64=58.25ms,所以WWDG_Enable(127);//(0x7F為設(shè)置的最小值,0x40為最大的復(fù)位值,取值應(yīng)該在0x40~0x7F之間)刷新窗口為:910us*(127-80)=42.77ms < 刷新窗口 < 910us*64=58.25ms } void mian(void) { //初始化while(1){delay_ms(400)WWDG_Enable(127);//無需判斷直接等待窗口看門狗中斷觸發(fā)} }或者這樣的留參帶使能中斷形式:
#include "wdg.h" #include "stm32f10x_wwdg.h"static u8 WWDG_CNT=0x7f; /*保存WWDG計(jì)數(shù)器的設(shè)置值,默認(rèn)為最大127. *///======================================================================================== /*** 初始化窗口看門狗* tr :T[6:0],計(jì)數(shù)器值* wr :W[6:0],窗口值* fprer:分頻系數(shù)(WDGTB),僅最低2位有效* Fwwdg=PCLK1/(4096*2^fprer).// 計(jì)數(shù)器值為7f,窗口寄存器為5f,分頻數(shù)為8WWDG_Init(0X7F,0X5F,WWDG_Prescaler_8);*/ void WWDG_Init(u8 tr,u8 wr,u32 fprer) {RCC_APB1PeriphClockCmd(RCC_APB1Periph_WWDG, ENABLE); /*WWDG時(shí)鐘使能*/WWDG_SetPrescaler(fprer); /*設(shè)置IWDG預(yù)分頻值*/WWDG_SetWindowValue(wr); /*設(shè)置窗口值*/WWDG_CNT=tr&WWDG_CNT; /* 初始化WWDG_CNT. */WWDG_Enable(WWDG_CNT); /*使能看門狗 , 設(shè)置 counter . */WWDG_ClearFlag(); /*清除提前喚醒中斷標(biāo)志位*/WWDG_NVIC_Init();/* 初始化窗口看門狗 NVIC */WWDG_EnableIT(); /* 開啟窗口看門狗中斷 */ }/*** 窗口看門狗中斷服務(wù)程序*/ void WWDG_NVIC_Init(void) {NVIC_InitTypeDef NVIC_InitStructure;NVIC_InitStructure.NVIC_IRQChannel = WWDG_IRQn; /*WWDG中斷*//* 搶占2,子優(yōu)先級3 */NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2;NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3; NVIC_InitStructure.NVIC_IRQChannelCmd?=?ENABLE;??????//中斷使能,NVIC_Init(&NVIC_InitStructure);/* NVIC初始化*/ }/*** 重設(shè)置WWDG計(jì)數(shù)器的值,喂狗*/ void WWDG_Set_Counter(u8 cnt) {WWDG_Enable(cnt); /*使能看門狗 , 設(shè)置 counter . */ }/*** 看門狗中斷服務(wù)程序*/ void WWDG_IRQHandler(void) {WWDG_Set_Counter(WWDG_CNT);WWDG_ClearFlag(); /*清除提前喚醒中斷標(biāo)志位*/LED1 = ~LED1; /*LED狀態(tài)翻轉(zhuǎn) */ }void mian(void) { //初始化while(1){} }三、中斷說明:
?關(guān)于void WWDG_IRQHandler(void)里的中斷進(jìn)入是在減計(jì)數(shù)到0x40時(shí),處罰中斷進(jìn)入這個(gè)中斷函數(shù),如果在中斷函數(shù)中進(jìn)行減計(jì)數(shù)的操作,可以避免復(fù)位的厄運(yùn),但是如果你不做喂狗操作,那減計(jì)數(shù)值將接著減,數(shù)值將為0x3F,此時(shí)bit7被置零,此時(shí)將會直接導(dǎo)致復(fù)位。總之,進(jìn)入中斷函數(shù)并非就復(fù)位了,只是此時(shí)的減計(jì)數(shù)值到了0x40,而下一次減計(jì)數(shù)器減一后值為0x3F將導(dǎo)致芯片復(fù)位了。
獨(dú)立看門狗(IWDG)的代碼:
/*** 初始化獨(dú)立看門狗* prer:分頻數(shù):0~7(只有低 3 位有效!)* 分頻因子=4*2^prer.但最大值只能是 256!* rlr:重裝載寄存器值:低 11 位有效.* 時(shí)間計(jì)算(大概):Tout=((4*2^prer)*rlr)/40 (ms).*IWDG_Init(4,625);//初始化獨(dú)立看門狗,分頻數(shù)為64,重裝載值為625,溢出時(shí)間計(jì)算為:64*625/40=1000ms=1s*/ void IWDG_Init(u8 prer,u16 rlr) {IWDG_WriteAccessCmd(IWDG_WriteAccess_Enable); /* 使能對寄存器IWDG_PR和IWDG_RLR的寫操作*/IWDG_SetPrescaler(prer); /*設(shè)置IWDG預(yù)分頻值:設(shè)置IWDG預(yù)分頻值*/IWDG_SetReload(rlr); /*設(shè)置IWDG重裝載值*/IWDG_ReloadCounter(); /*按照IWDG重裝載寄存器的值重裝載IWDG計(jì)數(shù)器*/IWDG_Enable(); /*使能IWDG*/ }/*** 喂獨(dú)立看門狗*/ void IWDG_Feed(void) {IWDG_ReloadCounter(); /*reload*/ }/***main函數(shù)*/ void main(void) {NVIC_Configuration();//優(yōu)先級配置IWDG_Init(4,625);//初始化獨(dú)立看門狗,分頻數(shù)為64,重裝載值為625,溢出時(shí)間計(jì)算為:64*625/40=1000ms=1swhile(1){delay_ms(500);//0.5秒喂一次狗IWDG_Feed();//喂狗} }?
?
總結(jié)
以上是生活随笔為你收集整理的stm32 独立看门狗和窗口看门狗区别的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: stm32使用rtc到底用LSI还是LS
- 下一篇: 百度网盘共享