stm32CubeMx中實現窗口看門狗功能

stm32CubeMx中實現窗口看門狗功能

     
        stm32CubeMx..........多數嵌入式編程人員可能已程習慣使用stm32的庫開發方式來實現功能,庫版本v3.5.0本人之前也一直使用,開始使用stm32CubeMx開發方式,發現和原先庫開發方式與很多不同,實現方法也有區別。
本文旨在將個人在stm32CubeMx開發方式中總結的一些經驗寫出來,供大家參考。

      對於看門狗而言,stm32中有兩種,分爲獨立看門狗(IWDG)和窗口看門狗(WWDG),在此大概介紹下兩條警犬,本文重點介紹窗口看門狗。
獨立看門狗:獨立看門狗(IWDG)由專用的40kHz的低速時鐘驅動,即使主時鐘發生故障它也仍然有效。IWDG最適合應用於那些需要看門狗作爲一個在主程序之外,能夠完全獨立工作,並且對時間精度要求較低的場合。
窗口看門狗:窗口看門狗通常被用來監測由外部干擾或不可預見的邏輯條件造成的應用程序背離正常的運行序列而產生的軟件故障。通俗說就是會產生兩個復位。復位條件:(1)當計數器的數值從0x40減到0x3F;(2)當刷新看門狗時計數器的數值大於窗口上限值時。滿足任何一條都可以產生復位信號。通常情況下設置窗口上限值爲0x7F,下限值默認爲0x40,計數器向下數到0x40就會產生中斷,下個910us後變爲0x3F就會復位系統。也就是喂狗操作不能早喂,即大於窗口值時會發生復位;喂的晚了,即計數器的數值從0x40減到0x3F時沒有及時喂狗,也會產生復位。

實驗說明:板子型號爲stm32F103VET6, 每次喂狗並通過串口打印出來
下面來看下在stm32CubeMx中窗口看門狗的實現。
1、在stm32cubemx中設值

我們設置分頻係數爲8;窗口值爲0x5f;計數值爲0x7f;其中窗口默認下限值爲0x40。並打開中斷,打開中斷後,會置1中斷位,如圖:


(2)寫WWDG初始化函數

void WWDG_Init(void)
{
__WWDG_CLK_ENABLE(); //使能WWDG時鐘
   
MX_WWDG_Init(); //調用系統初始化函數,也就是我們在圖形界面設置好值後,會將我們剛纔設置的值轉化爲代碼。在本函數裏直接調用即可


__HAL_WWDG_CLEAR_FLAG(&hwwdg, WWDG_FLAG_EWIF);  // 開啓中斷前,先清除中斷標誌位

HAL_WWDG_Start_IT(&hwwdg);   //設置中斷標誌位,並開啓中斷,

}

(3)我們再來開下在中斷函數,cubemx的中斷函數處理和庫開發方式還是有區別的。
/**
* @brief This function handles Window watchdog interrupt.
*/
void WWDG_IRQHandler(void)
{
  /* USER CODE BEGIN WWDG_IRQn 0 */


  /* USER CODE END WWDG_IRQn 0 */
 
HAL_WWDG_IRQHandler(&hwwdg);
  /* USER CODE BEGIN WWDG_IRQn 1 */


  /* USER CODE END WWDG_IRQn 1 */
}

我們看到在它的中斷函數裏調用了一個函數, HAL_WWDG_IRQHandler(&hwwdg); 我們再來看這個函數,在該函數裏出現了一個在cubemx方式裏獨有的,回調函數,當中斷開啓,並且中斷標誌位滿足後將會調用該函數,而我們的操作將會在這裏實現。


void HAL_WWDG_IRQHandler(WWDG_HandleTypeDef *hwwdg)

  /* Check if Early Wakeup Interrupt is enable */
  if(__HAL_WWDG_GET_IT_SOURCE(hwwdg, WWDG_IT_EWI) != RESET)
  {
    /* Wheck if WWDG Early Wakeup Interrupt occurred */
  if(__HAL_WWDG_GET_FLAG(hwwdg, WWDG_FLAG_EWIF) != RESET)
  {
    /* Early Wakeup callback */ 
    HAL_WWDG_WakeupCallback(hwwdg);
    
    /* Change WWDG peripheral state */
    hwwdg->State = HAL_WWDG_STATE_READY; 
    
      /* Clear the WWDG Early Wakeup flag */
    __HAL_WWDG_CLEAR_FLAG(hwwdg, WWDG_FLAG_EWIF);
    
    /* Process Unlocked */
    __HAL_UNLOCK(hwwdg);
  }

}

(4)下面我們來討論看門狗的喂狗時間,很容易計算在stm32f103系列裏窗口看門狗的最大喂狗時間也就58ms,在一些程序裏我們沒必要這麼密集的去喂狗。那麼如何增大喂狗時間呢。蒐集了網上的一些方法後,本人根據具體事例實現了一個增大看門狗喂狗時間的方法:就是在中斷函數中再做一個額外計數器,如果計數器沒有達到設定值,就就行喂狗操作,同時使設定值加1,當計數器達到設定值時,就不加載喂狗定時器初值,這時看門狗定時器就會從從0x40減到0x3F產生系統復位。使用這個方法可以將定時時間拓展到 58ms*額外計數器設定值,定個幾十秒都不是問題。 當達到計數值後如果我們清零計數值,那麼看門狗系統就會復位,所以我們只要在主函數裏定期的將該計數值清零,也就是變相的增大了喂狗時間。下面具體看事例:
每次產生看門狗中斷都會調用回調函數,我在回調函數裏做如下操作:
/*****************************看門狗回調函數********************************/
void HAL_WWDG_WakeupCallback(WWDG_HandleTypeDef* hwwdg)
{
if(time <=50)
{
HAL_WWDG_Refresh(hwwdg, WWDG_CNT); //喂狗函數
printf("喂狗\r\n");    //每喂一次狗,打印一次,無實際作用
time++;
}
}

/**************************main函數中部分函數********************************/
  while (1)
  {
if(time > 50)
{
time = 0;
printf("time清零 \r\n");
}
  }

我設置看門狗最大喂狗時間爲58ms,那麼計數50次,大概是2.9s時間,也就是我在主函數中必須在2.9s內,只要對計數器清零,系統就不會復位了。相應的可以把計數值設置更大,這就根據個人需要了。這樣是不是變相的增大喂狗時間了。
下面是我的串口打印效果:


大家看一下是不是每喂一次狗就會打印一個“喂狗”,同時在11點55分20秒有一次time清零,到11點55分23秒有一次time清零,是不是間隔大概3秒了。


好了,本人也是剛開始使用stm32CubeMx開發,如果內容中有問題,希望指出來,共同進步







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