STM32看門狗--窗口看門狗

stm32有兩個看門狗,獨立看門狗和窗口看門狗,其實兩者的功能是類似的,只是餵狗的限制時間不同。

 

獨立看門狗是限制餵狗時間在0-x內,x由你的相關寄存器決定。餵狗的時間不能過晚。

窗口看門狗所以稱之爲窗口就是因爲其餵狗時間是一個有上下限的範圍內,你可以通過設定相關寄存器,設定其上限時間和下限時間。餵狗的時間不能過早也不能過晚。

圖1

 

窗口看門狗的

上窗口就是配置寄存器WWDG->CFR裏設定的W[6:0];

下窗口是固定的0x40

當窗口看門狗的計數器在上窗口值之外,或是低於下窗口值都會產生復位。

圖2

 

 

&& 上窗口的值可以只有設定,7位二進制數最大隻可以設定爲127(0x7F),最小又必須大於下窗口的0x40,所以其取值範圍爲64~127(即:0x40~0x7F;

 

&& 配置寄存器WWDG->CFR中爲計數器設定時鐘分頻係數,確定這個計數器可以定時的時間範圍,從而確定窗口的時間範圍。

 

&& 窗口看門狗的時鐘來自於PCLK1,在時鐘配置中,其頻率爲外部時鐘經倍頻器後的二分頻時鐘,即爲36MHz,根據手冊可以知道其定時時間計算方法:

      

上窗口時間:T_min = 4096 * (2^WDGTB)*(WWDG_CR[6:0] - WWDG_CFR[6:0])/36 (us)

 

 下窗口時間: T_max = 4096 * (2^WDGTB)*(WWDG_CR[6:0] - 0x40)/36 (us)

 

 

36Mhz下相關窗口看門狗的餵狗時間範圍:

WDGTB(計數器分頻值)最早餵狗時間/us最晚餵狗時間/ms

0                         113              7.28

1                         227              14.56

2                         455              29.12

3                         910              58.25

 

本例直接寄存器實現4種測試模式,測試窗口看門狗的復位原理。

MODE_1 0   // 30ms時餵狗,在窗口範圍內餵狗,LED燈閃爍

MODE_2 0   // 10ms時餵狗,在窗口範圍外導致復位,LED燈常亮

MODE_3 0   // 100ms時餵狗,在窗口範圍外餵狗導致復位

MODE_4 1   // 主函數不執行餵狗,開啓提前喚醒中斷,在WWDG中斷函數中餵狗

庫函數實現在提前喚醒中斷中,餵狗操作,PA4LED正常閃爍。當外部中斷髮生(按下PA0按鍵),長時間不餵狗,引發窗口看門狗復位。

 

直接操作寄存器

 

相關寄存器如下:

控制寄存器WWDG->CR8位有效。

8位爲WDGA,看門狗激活位。低7[6:0]爲看門狗計數器的計數值。

 

配置寄存器WWDG->CFR:低十位有效。

10位爲EWI:提醒喚起中斷。此位置1,當計數器值到達0x40時,將產生中斷。

89WDGTB:爲計數器分頻係數設置爲:

00: CK計時器時鐘(PCLK1除以4096)除以1     01: CK計時器時鐘(PCLK1除以4096)除以2

10: CK計時器時鐘(PCLK1除以4096)除以4     11: CK計時器時鐘(PCLK1除以4096)除以8

7[6:0]:爲窗口值。

 

int main(void)

{

#ifdef DEBUG

  debug();

#endif

 

  /* System Clocks Configuration ---------------------------------------------*/

  RCC_Configuration();

    

  /* GPIO configuration ------------------------------------------------------*/

  GPIO_Configuration();

 

  /*註釋-hope:利用窗口看門狗的提前喚醒中斷服務子程序來進行獨立看門狗計數值的

       重載,每次重載一次計數值LED2就閃爍一次。*/

  /* Check if the system has resumed from WWDG reset -------------------------*/

  if(RCC_GetFlagStatus(RCC_FLAG_WWDGRST) != RESET)

  { /* WWDGRST flag set */

    /* Turn on led connected to PC.06 */

    GPIO_WriteBit(GPIOC, GPIO_Pin_6, Bit_SET);

 

       /* Clear reset flags */

    RCC_ClearFlag();

  }

  else

  { /* WWDGRST flag is not set */

    /* Turn off led connected to PC.06 */

    GPIO_WriteBit(GPIOC, GPIO_Pin_6, Bit_RESET);

  }

 

  /* Configure EXTI Line9 to generate an interrupt on falling edge -----------*/

  EXTI_Configuration();

 

/* NVIC configuration --------------------------------------------------------*/

  NVIC_Configuration();

 

/* WWDG configuration --------------------------------------------------------*/

  /* Enable WWDG clock */

  RCC_APB1PeriphClockCmd(RCC_APB1Periph_WWDG, ENABLE);

 

   /*   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

 

/* WWDG clock counter = (PCLK1/4096)/8 = 244 Hz (~4 ms) ---PCLK1=8MHZ */

 

  WWDG_SetPrescaler(WWDG_Prescaler_8);

 

  /* Set Window value to 0x41 ---設置上窗口邊界值*/

  WWDG_SetWindowValue(0x41);

 

  /* Enable WWDG and set counter value to 0x7F,  0x7f-0x41=64 --WWDG timeout = ~4 ms * 64 = 262 ms */

/*看門狗計數器的計數值0x7F---結合上面上窗口邊界,計數值從ox7f遞減到0x40*/

  WWDG_Enable(0x7F);

 

  /* Clear EWI flag */

  WWDG_ClearFlag();

 

  /* Enable EW interrupt */

  WWDG_EnableIT();

 

  while (1)

  {

  }

}

 

 

/******按鍵的優先級爲0高於窗口看門狗的優先級1*****/

void NVIC_Configuration(void)

{

  NVIC_InitTypeDef NVIC_InitStructure;

 

  /* 2 bits for Preemption Priority and  2 bits for Sub Priority */

  NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);

 

  NVIC_InitStructure.NVIC_IRQChannel = EXTI9_5_IRQChannel;

  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;

  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;

  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;

  NVIC_Init(&NVIC_InitStructure);

 

  NVIC_InitStructure.NVIC_IRQChannel = WWDG_IRQChannel;

  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;

  NVIC_Init(&NVIC_InitStructure);

}

 

 

void EXTI_Configuration(void)

{

  EXTI_InitTypeDef EXTI_InitStructure;

 

  /* Connect EXTI Line9 to PB.9 */

  GPIO_EXTILineConfig(GPIO_PortSourceGPIOB, GPIO_PinSource9);

 

  /* Configure EXTI Line9 to generate an interrupt on falling edge */

  EXTI_ClearITPendingBit(EXTI_Line9);

  EXTI_InitStructure.EXTI_Line = EXTI_Line9;

  EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;

  EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling; //下降沿有效

  EXTI_InitStructure.EXTI_LineCmd = ENABLE;

  EXTI_Init(&EXTI_InitStructure);

}

 

Stm32f10x_it.c文件中:

 

void WWDG_IRQHandler(void)

{

  /* Update WWDG counter */

  WWDG_SetCounter(0x7F);

      

  /* Clear EWI flag */

  WWDG_ClearFlag();

 

  /* Toggle led connected to PC.07 */

  GPIO_WriteBit(GPIOC, GPIO_Pin_7, (BitAction)(1-GPIO_ReadOutputDataBit(GPIOC, GPIO_Pin_7)));

}

 

/********按鍵中斷處理程序********/

//注意:這裏中斷函數裏沒有清中斷標誌的操作,這會導致窗口看門狗的提前喚醒中斷

          無法進入,最終導致因無法重載看門狗計數器而系統復位;

void EXTI9_5_IRQHandler(void)

{

  if(EXTI_GetITStatus(EXTI_Line9) != RESET)

  {  

    /* Turn off led connected to PC.07 */

       GPIO_WriteBit(GPIOC, GPIO_Pin_7, Bit_RESET);

 

       /* As EXTI line9 pending bit is not cleared, the CPU will execute indefinitely

          this ISR and when the WWDG counter falls to 3Fh the WWDG reset occurs */

  }

}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章