1、IWDG的簡介?
????????IWDG:Independent watchdog,即獨立看門狗
????????獨立看門狗本質上是一個定時器,該定時器是一個12位的遞減計數器,當計數器的值減到0的時候,就會產生一個復位信號
????????如果在計數沒減到0之前,重置計數器的值的話,那么就不會產生復位信號,這個動作我們稱為喂狗
(1)本質:能產生系統復位信號的計數器
(2)特性:12位的遞減的計數器,時鐘由獨立的RC振蕩器提供(可在待機和停止模式下運行),看門狗被激活后,當遞減計數器計數到0x000時產生復位
(3)喂狗:在計數器計數到0之前,重裝載計數器的值,防止復位
(4)作用:主要用于檢測外界電磁干擾或硬件異常導致的程序跑飛問題,即檢測異常?
什么是異常?
外界電磁干擾或者自身系統(硬件或軟件)異常,造成程序跑飛,如:陷入某個不正常的死循環,打斷正常的程序運行?
(5)應用:在一些需要高穩定性的產品中,并且對時間精度要求較低的場合
2、IWDG框圖
簡圖如下所示:
3、IWDG溢出時間計算
:看門狗溢出時間
:看門狗的時鐘源頻率(30~60Khz),一般以40Khz來計算
prer:IWDG_PR的值(000~111)
rlr:看門狗重裝載值(0~4095)?
4、IWDG的配置步驟
(1)取消PR/RLR寄存器寫保護,設置IWDG,預分頻系數和重裝載值,啟動IWDG
HAL_IWDG_Init();
(2)及時喂狗,即寫入0xAAAA到IWDG_KR
HAL_IWDG_Refresh();
IWDG配置:
IWDG_HandleTypeDef iwdg_handle; ?//iwdg句柄
//初始化iwdg
void iwdg_init(uint8_t psc,uint16_t alr){
? ? iwdg_handle.Instance=IWDG; ?//寄存器基地址
? ? iwdg_handle.Init.Prescaler=psc; ?//預分頻系數
? ? iwdg_handle.Init.Reload=alr; ?//重裝載值
? ? HAL_IWDG_Init(&iwdg_handle); ?//取消寫保護
}//喂狗
void iwdg_refresh(void){
? ? HAL_IWDG_Refresh(&iwdg_handle);
}
HAL_IWDG_Init
功能:使能IWDG,設置預分頻系數和重裝載值等?
HAL_StatusTypeDef HAL_IWDG_Init(IWDG_HandleTypeDef *hiwdg)?
typedef struct{
? IWDG_TypeDef ? ? ? ? ? ? ? ? *Instance; ?/*? 寄存器基地址? */? IWDG_InitTypeDef ? ? ? ? ? ? Init;? ? ? ? ? ?/*? IWDG必需參數? */
} IWDG_HandleTypeDef;
typedef struct{
? uint32_t Prescaler; ?/*? 預分頻系數? */? uint32_t Reload;? ? ? /*? 重裝載值(0~0x0FFF)? */
} IWDG_InitTypeDef;
Prescaler預分頻系數如下所示:
#define IWDG_PRESCALER_4 ? ?? 0x00000000U? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?/*? 4? */
#define IWDG_PRESCALER_8 ? ???IWDG_PR_PR_0? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? /*? 8 ? */
#define IWDG_PRESCALER_16 ? ? IWDG_PR_PR_1? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?/*? 16 ?*/
#define IWDG_PRESCALER_32 ? ??(IWDG_PR_PR_1 | IWDG_PR_PR_0) ? ? ?/*? 32 ?*/
#define IWDG_PRESCALER_64 ? ? IWDG_PR_PR_2? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?/*? 64 ?*/
#define IWDG_PRESCALER_128 ? ?(IWDG_PR_PR_2 | IWDG_PR_PR_0) ? ??/*? 128 */
#define IWDG_PRESCALER_256 ?? (IWDG_PR_PR_2 | IWDG_PR_PR_1)? ? ?/*? 256 */?
HAL_IWDG_Refresh?
功能:把重裝載寄存器的值重載到計數器中,喂狗?
HAL_StatusTypeDef HAL_IWDG_Refresh(IWDG_HandleTypeDef *hiwdg)?
5、實現喂狗操作
int main(void){
? ? uint8_t key;
? ? HAL_Init();
? ? sys_stm32_clock_init(RCC_PLL_MUL9); ?//設置系統時鐘
? ? delay_init(72);
? ??
? ? led_init();
? ? beep_init();
? ? key_init();
? ? usart_init(115200); ?//串口
? ? HAL_Delay(100);
? ??
? ? HAL_GPIO_WritePin(GPIOB,GPIO_PIN_5,GPIO_PIN_RESET);
? ? iwdg_init(IWDG_PRESCALER_64,625); ?//初始化iwdg ? ?設置預分頻系數64 ? ? 重裝值625 ? ?溢出時間1s
? ? while (1){
? ? ? ? key=scan(0);
? ? ? ? if(key==4){? ? ? ? //當按下KEY_UP鍵時喂狗
? ? ? ? ? ? iwdg_refresh();
? ? ? ? }
? }
}
?