天天看點

STM32-視窗看門狗---WWDG

視窗看門狗—WWDG

1.基本介紹

獨立看門狗是12位遞減計數器,視窗看門狗是7位遞減計數器。

獨立看門狗沒上限值,視窗看門狗有上限值(由使用者設定)和固定下限值(0X40)。

視窗看門狗在上限值以上進行喂狗會産生複位,在下限值還未進行喂狗也會産生複位。故視窗看門狗一定要在上限值和下限值之間進行喂狗。

STM32-視窗看門狗---WWDG
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,則最大逾時和最小逾時時間如下圖

STM32-視窗看門狗---WWDG
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(); //清除視窗看門狗狀态标志
}
           

講解不到位的希望大家指出,有需要我講解的部分,希望大家提出,我會出文檔講解。