視窗看門狗—WWDG
1.基本介紹
獨立看門狗是12位遞減計數器,視窗看門狗是7位遞減計數器。
獨立看門狗沒上限值,視窗看門狗有上限值(由使用者設定)和固定下限值(0X40)。
視窗看門狗在上限值以上進行喂狗會産生複位,在下限值還未進行喂狗也會産生複位。故視窗看門狗一定要在上限值和下限值之間進行喂狗。
1.1視窗看門狗時鐘
視窗看門狗時鐘來自PCLK1,挂接在APB1總線上,由RCC開啟。最大頻率為42M。
1.2WDG預分頻器
PCLK1時鐘經過預分頻器分頻後輸入給計數器時鐘。
分頻因子通過WWDG_CFR的8:7設定分頻因子,可設為0 、 1 、 2、 3。
分頻後的計數器時鐘為:CK_CNT=PCLK1/4096/(2^WDGTB)
PCLK1等于APB1時鐘;
WDGTB為分頻因子(0-3)
4096為固定值。
1.3計數器
計數器為7位遞減計數器,故計數器最大值為0x7F。值放在WWDG_CR中的6:0位。故計數器的範圍為0x7F-0x40。
為防止忘記進行喂狗,可開啟提前喚醒中斷。開啟後當計數器計數到0x40時,進入中斷。開啟中斷方式為WWDG_CFR位9EWI置1。
如果不用中斷進行喂狗,也可以進行計算,在計算時間内進行喂狗。
Twwdg=(4096×2^WDGTB×(T[5:0]+1))/PCLK1;
Twwdg為視窗看門狗的逾時時間,機關為ms。
PCLK1為APB1的時鐘頻率,最大42MHz。
WDGTB為視窗看門狗的預分頻系數。
T[5:0]為視窗看門狗的計數器低6位。
若PCLK1為42MHz,則最大逾時和最小逾時時間如下圖
1.4看門狗配置寄存器(WWDG_CFR)
一般設定為視窗看門狗時間比實際程式運作時間稍大一些,就可在程式剛運作完後進行看門狗喂狗。
1.5系統複位信号
當超過視窗上限值喂狗或低于視窗下限值還未進行喂狗,并且WDGA位置為1(開啟視窗看門狗)。将産生一個複位信号,系統複位。
2.相關寄存器
2.1中斷結構體
typedef struct
{
uint8_t NVIC_IRQChannel;//中斷通道
uint8_t NVIC_IRQChannelPreemptionPriority;//搶占優先級
uint8_t NVIC_IRQChannelSubPriority;//子優先級
FunctionalState NVIC_IRQChannelCmd;//中斷使能
} NVIC_InitTypeDef;
2.2視窗看門狗結構體
typedef struct
{
__IO uint32_t CR; //看門狗控制寄存器,設定計數值及使能看門狗
__IO uint32_t CFR; //看門狗配置寄存器,設定視窗值上限,使能中斷
__IO uint32_t SR; //狀态寄存器,清除中斷标志位
} WWDG_TypeDef;
3.配置步驟
3.1分步設定
(1)定義相關結構體
(2)開啟開門狗時鐘
(3)設定視窗值和分頻數
WWDG_SetWindowValue(0x5f);//設定視窗值
WWDG_SetPrescaler(WWDG_Prescaler_8);//設定分頻值
//設定視窗值
void WWDG_SetWindowValue(uint8_t WindowValue)
{
__IO uint32_t tmpreg = 0;
/* Check the parameters */
assert_param(IS_WWDG_WINDOW_VALUE(WindowValue));
/* Clear W[6:0] bits */
tmpreg = WWDG->CFR & CFR_W_MASK;
/* Set W[6:0] bits according to WindowValue value */
tmpreg |= WindowValue & (uint32_t) BIT_MASK;
/* Store the new value */
WWDG->CFR = tmpreg;
}
#define WWDG_Prescaler_1 ((uint32_t)0x00000000)
#define WWDG_Prescaler_2 ((uint32_t)0x00000080)
#define WWDG_Prescaler_4 ((uint32_t)0x00000100)
#define WWDG_Prescaler_8 ((uint32_t)0x00000180)
//設定分頻數
/**
* @brief Sets the WWDG Prescaler.
* @param WWDG_Prescaler: specifies the WWDG Prescaler.
* This parameter can be one of the following values:
* @arg WWDG_Prescaler_1: WWDG counter clock = (PCLK1/4096)/1
* @arg WWDG_Prescaler_2: WWDG counter clock = (PCLK1/4096)/2
* @arg WWDG_Prescaler_4: WWDG counter clock = (PCLK1/4096)/4
* @arg WWDG_Prescaler_8: WWDG counter clock = (PCLK1/4096)/8
* @retval None
*/
void WWDG_SetPrescaler(uint32_t WWDG_Prescaler)
{
uint32_t tmpreg = 0;
/* Check the parameters */
assert_param(IS_WWDG_PRESCALER(WWDG_Prescaler));
/* Clear WDGTB[1:0] bits */
tmpreg = WWDG->CFR & CFR_WDGTB_MASK;
/* Set WDGTB[1:0] bits according to WWDG_Prescaler value */
tmpreg |= WWDG_Prescaler;
/* Store the new value */
WWDG->CFR = tmpreg;
}
(4)初始化中斷結構體
NVIC_InitStructure.NVIC_IRQChannel = WWDG_IRQn;//視窗中斷通道
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=2;//搶占優先級
NVIC_InitStructure.NVIC_IRQChannelSubPriority =3; //子優先級
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ通道使能
NVIC_Init(&NVIC_InitStructure); //根據指定的參數初始化NVIC寄存器
(5)設定計數器初始值并使能WWDG
WWDG_Enable(0x7f); //使能視窗看門狗并初始化計數器值,看門狗控制器寄存器WDGA置1
WWDG_ClearFlag(); //清除視窗看門狗狀态标志(這一句必須加上,否則進入不了中斷)
//使能WWDG函數
void WWDG_Enable(uint8_t Counter)
{
/* Check the parameters */
assert_param(IS_WWDG_COUNTER(Counter));
WWDG->CR = WWDG_CR_WDGA | Counter;
}
//清除看門狗狀态标志函數
void WWDG_ClearFlag(void)
{
WWDG->SR = (uint32_t)RESET;
}
(6)開啟看門狗中斷
//看門狗中斷使能函數
void WWDG_EnableIT(void)
{
*(__IO uint32_t *) CFR_EWI_BB = (uint32_t)ENABLE;
}
(7)編寫看門狗中斷函數
/*******************************************************************************
* 函 數 名 : WWDG_IRQHandler
* 函數功能 : WWDG中斷函數
* 輸 入 : 無
* 輸 出 : 無
*******************************************************************************/
void WWDG_IRQHandler(void)
{
WWDG_SetCounter(0x7f); //重新指派
WWDG_ClearFlag(); //清除視窗看門狗狀态标志
}
3.2完整視窗看門狗初始化函數
/*******************************************************************************
* 函 數 名 : WWDG_Init
* 函數功能 : WWDG初始化
視窗值是:0x5f
定時器計數值是:0x7f
預分頻值是:8
視窗看門狗進入中斷的頻率計算公式是:PCLK1/(4096*2^pre)
* 輸 入 : 無
* 輸 出 : 無
*******************************************************************************/
void WWDG_Init(void)
{
NVIC_InitTypeDef NVIC_InitStructure;
RCC_APB1PeriphClockCmd(RCC_APB1Periph_WWDG,ENABLE); //開啟視窗看門狗的時鐘
WWDG_SetWindowValue(0x5f);//設定視窗值
WWDG_SetPrescaler(WWDG_Prescaler_8);//設定分頻值
NVIC_InitStructure.NVIC_IRQChannel = WWDG_IRQn;//視窗中斷通道
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=2;//搶占優先級
NVIC_InitStructure.NVIC_IRQChannelSubPriority =3; //子優先級
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ通道使能
NVIC_Init(&NVIC_InitStructure); //根據指定的參數初始化NVIC寄存器
WWDG_Enable(0x7f); //使能視窗看門狗并初始化計數器值
WWDG_ClearFlag(); //清除視窗看門狗狀态标志(這一句必須加上,否則進入不了中斷)
WWDG_EnableIT(); //開啟中斷
}
/*******************************************************************************
* 函 數 名 : WWDG_IRQHandler
* 函數功能 : WWDG中斷函數
* 輸 入 : 無
* 輸 出 : 無
*******************************************************************************/
void WWDG_IRQHandler(void)
{
WWDG_SetCounter(0x7f); //重新指派
WWDG_ClearFlag(); //清除視窗看門狗狀态标志
}
講解不到位的希望大家指出,有需要我講解的部分,希望大家提出,我會出文檔講解。