記錄一下,方便以後翻閱~
主要內容:
1) 獨立看門狗概述;
2) 常用寄存器和庫函數配置;
3) 獨立看門狗實驗代碼解讀。
官方資料:《STM32中文參考手冊V10》第17章——獨立看門狗
1. 看門狗的作用
在由單片機構成的微型計算機系統中,由於單片機的工作常常會受到來自外界電磁場的干擾,造成程序的跑飛,而陷入死循環,程序的正常運行被打斷,由單片機控制的系統無法繼續工作,會造成整個系統的陷入停滯狀態,發生不可預料的後果,所以出於對單片機運行狀態進行實時監測的考慮,便產生了一種專門用於監測單片機程序運行狀態的模塊或者芯片,俗稱“看門狗”(watchdog)。其主要作用爲:
1.1 在啓動正常運行的時候,系統不能復位;
1.2 在系統跑飛(程序異常執行)的情況,系統復位,程序重新執行。
2. STM32的看門狗相關知識
2.1 STM32內置兩個看門狗,提供了更高的安全性,時間的精確性和使用的靈活性。兩個看門狗設備(獨立看門狗和窗口看門狗)可以用來檢測和解決由軟件錯誤引起的故障。當計數器達到給定的超時值時,觸發一箇中斷(僅適用窗口看門狗)或者產生系統復位;
2.2 獨立看門狗(IWDG)由專用的低速時鐘(LSI)驅動,即使主時鐘發生故障它仍有效。獨立看門狗適合應用於需要看門狗作爲一個在主程序之外能夠完全獨立工作,並且對時間精度要求低的場合;
2.3 窗口看門狗由從APB1時鐘分頻後得到時鐘驅動。通過可配置的時間窗口來檢測應用程序非正常的過遲或過早操作。窗口看門狗最適合那些要求看門狗在精確計時窗口起作用的程序。
3. 獨立看門狗功能描述
3.1 在鍵值寄存器(IWDG_KR)中寫入0xCCCC,開始啓用獨立看門狗。此時計數器開始從其復位值0xFFF遞減,當計數器值計數到尾值0x000時會產生一個復位信號(IWDG_RESET);
3.2 無論何時,只要在鍵值寄存器IWDG_KR中寫入0xAAAA(通常說的餵狗), 自動重裝載寄存器IWDG_RLR的值就會重新加載到計數器,從而避免看門狗復位;
3.3 如果程序異常,就無法正常餵狗,從而系統復位。
4. 獨立看門狗框圖
4.1 鍵值寄存器IWDG_KR: 0~15位有效;
4.2 預分頻寄存器IWDG_PR:0~2位有效。具有寫保護功能,要操作先取消寫保護(即在IWDG_KR輸入0x5555);
4.3 重裝載寄存器IWDG_RLR:0~11位有效。具有寫保護功能,要操作先取消寫保護(即在IWDG_KR輸入0x5555);
4.4 狀態寄存器IWDG_SR:0~1位有效。
5. 看門狗相關寄存器解讀
5.1 鍵寄存器IWDG_KR
5.2 預分頻寄存器IWDG_PR
5.3 重裝載寄存器IWDG_RLR
5.4 狀態寄存器IWDG_SR
6. 獨立看門狗超時時間
溢出時間計算:
Timeout=((4×2^prer) ×RLR) /40 (針對M3內核)
時鐘頻率LSI=40K, 一個看門狗時鐘週期就是最短超時時間;
最長超時時間= (IWDG_RLR寄存器最大值)×看門狗時鐘週期。
7. IWDG獨立看門狗操作庫函數
7.1 往IWDG_KR寄存器中寫0x5555,取消寫保護:
void IWDG_WriteAccessCmd(uint16_t IWDG_WriteAccess);
7.2 往IWDG_PR寄存器中寫入值,設置預分頻係數:
void IWDG_SetPrescaler(uint8_t IWDG_Prescaler);
7.3 往IWDG_RLR寄存器中寫入值,設置重裝載值:
void IWDG_SetReload(uint16_t Reload);
7.4 往IWDG_KR寄存器中寫0xAAAA,餵狗:
void IWDG_ReloadCounter(void);
7.5 往IWDG_KR寄存器中寫0xCCCC,使能,啓動看門狗工作:
void IWDG_Enable(void);/ /使能看門狗:寫0xCCCC到KR//
7.6 從IWDG_SR寄存器中獲取看門狗狀態,重裝載/預分頻更新:
FlagStatus IWDG_GetFlagStatus(uint16_t IWDG_FLAG);
8. 獨立看門狗操作步驟
8.1 取消寄存器寫保護:
IWDG_WriteAccessCmd();
8.2 設置獨立看門狗的預分頻係數,確定時鐘:
IWDG_SetPrescaler();
8.3 設置看門狗重裝載值,確定溢出時間:
IWDG_SetReload();
8.4 使能看門狗:
IWDG_Enable();
8.5 應用程序餵狗:
IWDG_ReloadCounter();
8.6 溢出時間計算:
Tout=((4×2^prer) ×rlr) /40 (針對M3內核)
9. 獨立看門狗實驗相關函數
實現功能:啓動後,LED0每隔200ms閃爍,若有任何按鍵長按或每隔小於200ms的頻率連按,則LED0常亮。
跑馬燈、按鍵輸入相關代碼可參考以前的文章。
9.1 iwdg.h頭文件
#ifndef __IWDG_H
#define __IWDG_H
//添加sys.h頭文件,裏面包含的位操作所需的宏定義,且sys.h引入了stm32f10x.h文件,這樣允許使用u8,u16//
#include "sys.h"
//申明一個IWDG_Init初始化函數,包含兩個入口參數IWDG_PR(用來設置預分頻係數)和IWDG_RLR(用來設置重裝載值)//
void IWDG_Init(u8 IWDG_PR,u16 IWDG_RLR);
#endif
9.2 iwdg.c文件
#include "iwdg.h"
//編寫IWDG_Init初始化函數//
void IWDG_Init(u8 IWDG_PR,u16 IWDG_RLR)
{
IWDG_WriteAccessCmd(IWDG_WriteAccess_Enable);//取消寄存器寫保護//
IWDG_SetPrescaler(IWDG_PR); //設置獨立看門狗的預分頻係數//
IWDG_SetReload(IWDG_RLR); //設置看門狗重裝載值//
IWDG_ReloadCounter(); //餵狗,否則將從0xFFF算起//
IWDG_Enable(); //使能獨立看門狗//
}
9.3 main.c文件
#include "led.h"
#include "beep.h"
#include "key.h"
#include "iwdg.h"
#include "delay.h"
#include "sys.h"
int main(void)
{
delay_init(); //延時函數初始化
LED_Init(); //LED端口初始化
KEY_Init(); //初始化與按鍵連接的硬件接口
BEEP_Init(); //初始化蜂鳴器端口
delay_ms(200); //等待200ms
LED0=0; //先點亮紅燈
IWDG_Init(4,625); //根據預分配值和重裝載值確定溢出時間//
while(1)
{
//判斷是否有按鍵按下//
if(KEY_Scan(1)==WKUP_PRES|KEY_Scan(1)==KEY0_PRES|KEY_Scan(1)==KEY1_PRES|KEY_Scan(1)==KEY2_PRES)
{
IWDG_ReloadCounter(); //所有任何按鍵按下,則餵狗//
}
}
}
舊知識點
1)複習如何新建工程模板,可參考STM32學習心得二:新建工程模板;
2)複習基於庫函數的初始化函數的一般格式,可參考STM32學習心得三:GPIO實驗-基於庫函數;
3)複習寄存器地址,可參考STM32學習心得四:GPIO實驗-基於寄存器;
4)複習位操作,可參考STM32學習心得五:GPIO實驗-基於位操作;
5)複習延遲函數,可參考STM32學習心得九:Systick滴答定時器和延時函數解讀;
6)複習ST-LINK調試方法,可參考STM32學習心得十一:ST-LINK調試原理+軟硬件仿真調試方法。