獨立看門狗(庫函式)
?? 注:本文程式基于STM32F10X版本撰寫
一、獨立看門狗(IWDG)的作用
根據《STM32中文參考手冊》,STM32F10X內置了兩個看門狗,一個是獨立看門狗(IWDG),另一個是視窗看門狗(WWDG),
看門狗在百度百科中給出的解釋是:“看門狗,又叫 watchdog,從本質上來說就是一個定時器電路,一般有一個輸入和一個輸出,其中輸入叫做喂狗,輸出一般連接到另外一個部分的復位端,一般是連接到單片機, 看門狗的功能是定期的查看芯片內部的情況,一旦發生錯誤就向芯片發出重啟信號,看門狗命令在程式的中斷中擁有最高的優先級,”
二、IWDG的原理
如果打個比方的話就是,你從外邊騙來一條狗(定時),只要你定時去喂狗(執行某個操作),這條狗就不會回到原來的地方(不復位),但你有一天沒有喂狗,這條狗就會跑回原來的地方(復位),
由于本人沒有學暫存器撰寫所以,在暫存器層面的看門狗學習就拜托各位大神了,
1.獨立看門狗框圖

2.IWDG韌體庫檔案的簡單解讀
#include "stm32f10x_iwdg.h"
/** @addtogroup STM32F10x_StdPeriph_Driver
* @{
*/
/** @defgroup IWDG
* @brief IWDG driver modules
* @{
*/
/** @defgroup IWDG_Private_TypesDefinitions
* @{
*/
/** @defgroup IWDG_Private_Defines
* @{
*/
/* ---------------------- IWDG registers bit mask (IWDG暫存器位掩碼)----------------------------*/
/* KR register bit mask */
#define KR_KEY_Reload ((uint16_t)0xAAAA)
#define KR_KEY_Enable ((uint16_t)0xCCCC)
/**
* @brief Enables or disables write access to IWDG_PR and IWDG_RLR registers.(@brief啟用或禁用IWDG_PR和IWDG_RLR暫存器的寫訪問,)
* @param IWDG_WriteAccess: new state of write access to IWDG_PR and IWDG_RLR registers.(@param IWDG_WriteAccess: IWDG_PR和IWDG_RLR暫存器的寫訪問新狀態,)
* This parameter can be one of the following values:(該引數可以是以下值之一)
* @arg IWDG_WriteAccess_Enable: Enable write access to IWDG_PR and IWDG_RLR registers(@arg IWDG_WriteAccess_Enable:開啟IWDG_PR和IWDG_RLR暫存器的寫訪問)
* @arg IWDG_WriteAccess_Disable: Disable write access to IWDG_PR and IWDG_RLR registers(@arg IWDG_WriteAccess_Disable:關閉IWDG_PR和IWDG_RLR暫存器的寫訪問)
* @retval None
*/
void IWDG_WriteAccessCmd(uint16_t IWDG_WriteAccess)// 開啟/取消寫保護
{
/* Check the parameters */(/*檢查引數*/)
assert_param(IS_IWDG_WRITE_ACCESS(IWDG_WriteAccess));
IWDG->KR = IWDG_WriteAccess;
}
/**
* @brief Sets IWDG Prescaler value. //設定IWDG預分頻器值,
* @param IWDG_Prescaler: specifies the IWDG Prescaler value.
* This parameter can be one of the following values:
* @arg IWDG_Prescaler_4: IWDG prescaler set to 4 (IWDG預分頻器設定為4)
* @arg IWDG_Prescaler_8: IWDG prescaler set to 8
* @arg IWDG_Prescaler_16: IWDG prescaler set to 16
* @arg IWDG_Prescaler_32: IWDG prescaler set to 32
* @arg IWDG_Prescaler_64: IWDG prescaler set to 64
* @arg IWDG_Prescaler_128: IWDG prescaler set to 128
* @arg IWDG_Prescaler_256: IWDG prescaler set to 256
* @retval None
*/
void IWDG_SetPrescaler(uint8_t IWDG_Prescaler)
{
/* Check the parameters */
assert_param(IS_IWDG_PRESCALER(IWDG_Prescaler));
IWDG->PR = IWDG_Prescaler;
}
/**
* @brief Sets IWDG Reload value. (設定IWDG多載值,)
* @param Reload: specifies the IWDG Reload value.
* This parameter must be a number between 0 and 0x0FFF. (取值范圍為0 ~ 0x0FFF,)
* @retval None
*/
void IWDG_SetReload(uint16_t Reload)
{
/* Check the parameters */
assert_param(IS_IWDG_RELOAD(Reload));
IWDG->RLR = Reload;
}
/*看門狗的溢位時間(也就是到時間就復位)的計算在后邊*/
/**
* @brief Reloads IWDG counter with value defined in the reload register //用多載暫存器中定義的值重新加載IWDG計數器
* (write access to IWDG_PR and IWDG_RLR registers disabled {禁用IWDG_PR和IWDG_RLR暫存器的寫訪問}).
* @param None
* @retval None
*/
void IWDG_ReloadCounter(void) //利用這個函式,我們能實作禁止IWDG復位的操作(也就是喂狗)
{
IWDG->KR = KR_KEY_Reload;
}
/**
* @brief Enables IWDG (write access to IWDG_PR and IWDG_RLR registers disabled). {brief啟用IWDG(禁用IWDG_PR和IWDG_RLR暫存器的寫訪問),}
* @param None
* @retval None
*/
void IWDG_Enable(void) //IWDG庫函式的初始化
{
IWDG->KR = KR_KEY_Enable;
}
/**
* @brief Checks whether the specified IWDG flag is set or not.(@brief檢查是否設定了指定的IWDG標志,)
* @param IWDG_FLAG: specifies the flag to check.
* This parameter can be one of the following values:
* @arg IWDG_FLAG_PVU: Prescaler Value Update on going
* @arg IWDG_FLAG_RVU: Reload Value Update on going
* @retval The new state of IWDG_FLAG (SET or RESET).
*/
FlagStatus IWDG_GetFlagStatus(uint16_t IWDG_FLAG) //FlagStatus 回傳值是中斷標志位狀態(讀SR暫存器)
{
FlagStatus bitstatus = RESET;
/* Check the parameters */
assert_param(IS_IWDG_FLAG(IWDG_FLAG));
if ((IWDG->SR & IWDG_FLAG) != (uint32_t)RESET)
{
bitstatus = SET;
}
else
{
bitstatus = RESET;
}
/* Return the flag status */
return bitstatus;
}
3.IWDG溢位時間的計算
如果你手頭有參考書的話大概率是這么個公式:

其中
???? Tout:溢位時間
?? ??prer:IWDG時鐘預分頻值(范圍為0~7)
?? ??rlr:IWDG重裝載值
關于prer與rlr,這里有兩個點需要get:
??(1).prer值的取法:

??(2).rlr值的取法

三、IWDG源檔案的撰寫
/***************頭檔案*****************/
#ifndef __WDG_H
#define __WDG_H
#include "sys.h"
void IWDG_Init(u8 prer,u16 rlr);
void IWDG_Feed(void);
#endif
/***************c檔案*****************/
#include "wdg.h"
void IWDG_Init(u8 prer,u16 rlr)
{
IWDG_WriteAccessCmd(IWDG_WriteAccess_Enable); //關閉or開啟寫保護
IWDG_SetPrescaler(prer); //設定IWDG預分頻值;
IWDG_SetReload(rlr); //設定IWDG重裝載值
IWDG_ReloadCounter(); //按照IWDG重裝載暫存器的值重裝載IWDG計數器
IWDG_Enable(); //使能IWDG
}
void IWDG_Feed(void)
{
IWDG_ReloadCounter(); //多載
}
四、結束語
就我而言,我覺得,不論是學庫函式,還是集成度更高的HAL/LL庫,都應該或多或少了解一些底層的東西,這樣你才能對它把握得更好,
下一篇預告:《視窗看門狗》
本文作者是個小白,文中如有謬誤,還請各位大佬不吝賜教,感謝!
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/281711.html
標籤:其他
上一篇:第七屆工程訓練比賽之智能垃圾分類
