[STM32] 13-Independent_Watch Dog Timer

Morgan Ting
閱益如美
Published in
10 min readMay 14, 2022
Photo by Marek Szturc on Unsplash

看門狗計時器 ( Watch Dog Timer, WDT ) 是一組獨立計時器,用於當系統陷入無限循環或其他因素造成系統無法順利執行,看門狗便會將系統重啟讓系統回到初始通電狀態。本文章介紹 STM32 的獨立看門狗 ( Independent Watch Dog ) 功能並以 STM32CubeIDE 開發環境搭配 Hardware Abstraction Layer, HAL 函式庫實作。

文章內容

  1. Watch Dog 簡介
  2. Independent Watch Dog 介紹
  3. 實作
  4. 成果展示

工具與材料

  1. STM32CubeIDE
  2. Blue Pill ( STM32F103C8T6 ) 開發板
  3. ST-LINK v2

Watch Dog 簡介

Watch Dog Timer, WDT 看門狗計時器簡稱為看門狗,是一組位於微處理器中的獨立計時器,其功能是當系統陷入死循環或是跑到出神時,將系統重置 ( Reset ) 使得系統回復到一開始通電狀態。那麼,WDT 如何得知何時該重置系統呢 ? 方法在於系統是否進行 「餵狗」程序,所謂的餵狗其實就是將 WDT 計時器重置讓計數器從設定值開始倒數,由於微處理器系統通常會循環執行因此在執行階段放入一個餵狗指令就可以重置 WDT 計時器。

Independent Watch Dog 介紹

STM32 的獨立看門狗計時器系統方塊如下。

reference : datasheet

從系統方塊圖可以了解並不複雜,其內部裝置說明如下:

  • 以硬體啟動獨立看門狗時,一通上電源就會自動啟動。
  • 獨立看門狗由系統電源供電。
  • 獨立看門狗的計數器時脈由 LSI 內部震盪器提供,依型號不同有 32 Khz 或 40 KHz。
  • 可設定分頻係數為 4、8、16、32 、 64、128 與 256。
  • 12 位元計數器,最大值為 0xFFF ,當計數器倒數至 0 以下會觸發 IWDG Reset重置系統。
  • IWDG_RLR 是 Reload 暫存器,功能為設定計數器上限值,進行餵狗程序會將此暫存器內容讀入計數器,讓計數器從此數值倒數。
  • IWDG_KR 是一個控制開關,依控制對象不同有以下操作
  1. 對 IWDG_PR 與 IWDG_RLR寫入數值時,需先對 IWDG_KR 寫入 0x5555。
  2. 重刷計數器,也就是餵狗程序,對 IWDG_KR 寫入 0xAAAA。
  3. 以軟體啟動獨立看門狗,對 IWDG_KR 寫入 0xCCCC。

STM32 官方說明文件列出了有關於獨立看門狗的時間設定。

reference : datasheet

以表格第一行為例,看門狗時脈為 40 KHz,分頻係數為 4 此時計時器頻率為 40 K / 4 = 10 KHz,也就是每隔 0.1 ms 計數器會減 1 ( 看門狗計數器是倒數計時 ),若 12 位元長度的計數值上限設為最大值 0xFFF ( 4095 ),那麼經過 0.1 m * 4095 = 409.5 ms 便會歸零,而計數器小於 0 就會觸發重置因此計數器歸零後再經過一個計數週期 0.1 ms 就會觸發系統重置,所以是 409.5 + 0.1 = 409.6 ms 。因此計數頻率越低、計數上限越大,餵狗間隔時間就越長。

實作

本次實作我們利用獨立看門狗做重置動作,以 LED 燈做為標示。程式一開始會稍作延遲後點亮 LED 燈再延遲 1 秒鐘,由於已延遲超過 1 秒鐘因此寫在延遲語句後的餵狗指令永遠部會被執行,於是不斷被重啟。重啟後 I/O 腳位無輸出因此 LED 燈會再重啟後熄滅,我們便可以觀察到 LED 燈一直重複亮滅。

我們把餵狗時間設定在約 1 秒鐘,即系統啟動後每一秒鐘內要餵狗一次,否則系統會重置。由資料手冊得知分頻係數設定為 16 便可以達到此目的,因此計時器時脈為 40 Khz / 16 = 0.4 ms ,1 秒 / ( 0.4 m ) = 2500 ,所以將計數值上限設為 2500 ( 0x9C4 )會在 1 秒鐘後歸零。

電路圖

circuit

一、開啟 STM32CubeIDE 開發環境,建立一個新的專案。

start new project

二、選擇微處理器型號,輸入F103C8 可以快速找到,選擇該型號後按下 「NEXT」鍵。

target select

三、輸入專案名稱後按下「Finish」鍵。

project name

四、來到 系統設定畫面,按順序首先設定 SYS ,由於我們是用 ST-Link V2 燒錄器將程式上傳到晶片,所以這邊的 Debug 選項選擇 「Serial Wire」。

serial wire

五、RCC 時脈源,HSE 選擇 「Crystal / Ceramic Resonator」,其中 HSE 是連接開發板上的 8 MHz 震盪器提供系統使用,LSE 不做設定因為獨立看門狗計時器時脈由內部 40 K Hz 之RC 震盪器提供。

clock source

六、IWDG 獨立看門狗設定,將 Activated 選項打勾。parameter settings 設定預分頻與計數初始值,預分頻設定 16 ,reload value 設定 2500。

WDT setting

七、設定 PA1 為輸出模式,並將 PA1 取一個別名 「LED 」。點擊 PA1 選擇 「GPIO_Output」,之後在 PA1 上按滑鼠右鍵選擇 「Enter User Label 」輸入 LED 作為 PA1 腳位的別名。

pin setting
pin setting

八、Clock Configuration 設定獨立看門狗時脈源與系統時脈源。獨立看門狗時脈源預設 40 KHz,系統時脈選 「HSE 」選擇外接震盪器訊號。

clock configuration

九、Project Manager 專案管理,這裡不太需要設定,可以看一下專案名稱以及程式碼自動產生的設定是否符合需求即可。

project manager

十、產生程式碼,可以按存檔鍵或是點擊上方 「Project 」=> 「Generate Code 」產生程式碼。

generate code

十一、進入程式碼編輯畫面後,往下捲動可以看到獨立看門狗初始化程式碼。

WDT initialization

十二、接下來在 「 USER CODE BEGIN 2 」區塊裡寫兩行程式。

HAL_Delay(200) ; // 延遲 200 毫秒HAL_GPIO_WritePin(LED_GPIO_Port, LED_Pin, GPIO_PIN_SET) ; // 點亮 LED 燈

在 While 迴圈裡寫兩行程式

HAL_Delay(1000) ; // 延遲 1 秒HAL_IWDG_Refresh(&hiwdg); // 餵狗,重刷計數器內容

把滑鼠移到 HAL_IWDG_Refresh 上頭會顯示這一項程式碼的說明,我們可以看到實際上做了刷新 Reload 暫存器的動作,也就是重新將計數器裝載 2500 。

十三、完成程式碼撰寫後進行編譯程序,按下綠色箭頭按鈕。

run code

十四、在 Debugger 項目將 「ST-LINK S/N 」打勾並點擊右方 「SCAN」按鈕。

此時會顯示 ST-Link v2 編號,沒問題後按下 「OK 」按鈕即開始編譯並上傳程式到開發板。

debugger

總結

本次獨立看門狗實驗以 LED 燈做為指示燈,由於程式一開始延遲了 200 毫秒,在 while 迴圈又延遲 1 秒早已超過看門狗餵食時間,因此餵狗程序永遠不會被執行導致系統一直被重啟,LED 燈也因此反覆亮滅。

對於獨立看門狗總結如下:

  • Independent Watch Dog Timer , IWDT獨立看門狗由系統電源供電。
  • IWDT 由內部 RC 震盪器提供 40 Khz 時脈訊號。
  • 預分頻可以設定 4、8、16、32、64、128、256,降低計數頻率。
  • 看門狗計數器由 12 位元重載暫存器 Reload Register 設定計數初始值,最大為 0xFFF 。
  • 看門狗計數器計數到 0 以下 ( 注意不是 0 ) 會觸發 IWDT_Reset 重置系統。

參考資料

  1. STM32F103 手冊 [ 連結 ]
  2. STM32F1 HAL and Low-layer drivers [ 連結 ]
  3. STMicroelectronics 官方教學 [ 連結 ]

感謝讀者

若文章有幫助到您可以拍手給我鼓勵,免費支持我。

相關文章

  • [STM32] 00-Install STM32CubeIDE [連結]
  • [STM32] 01-ST-LINK [連結]
  • [STM32] 02-STM32F103C8T6 [連結]
  • [STM32] 03-GPIO-Output [連結]
  • [STM32] 04-GPIO-Input [連結]
  • [STM32] 05-Ext-Interrupt [連結]
  • [STM32] 06-Timer-Basic [連結]
  • [STM32] 07-Timer-Interrupt [連結]
  • [STM32] 08-Timer-Output_Compare [連結]
  • [STM32] 09-Timer-PWM [連結]
  • [STM32] 10-Timer-Input_Capture [連結]
  • [STM32] 11-RTC-Second-Interrupt [連結]
  • [STM32] 12-RTC-Alarm_Interrupt [連結]
  • [STM32] 13-Independent_Watch_Dog [連結]
  • [STM32] 14-Windows_Watch_Dog [連結]
  • [STM32] 15-ADC_Conversion [連結]
  • [STM32] 16-ADC_Conversion_Temperature_Sensor [連結]
  • [STM32] 17-ADC_Convversion_DMA [連結]
  • [STM32] 18-SPI [連結]
  • [STM32] 19-UART [連結]
  • [STM32] 20-I2C [連結]

--

--

Morgan Ting
閱益如美

用好奇心探索世界。喜愛學習樂於分享。