日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

STM32-独立看门狗原理-实验

發(fā)布時間:2025/3/12 编程问答 27 豆豆
生活随笔 收集整理的這篇文章主要介紹了 STM32-独立看门狗原理-实验 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

獨(dú)立看門狗原理概述

為什么要看門狗:

在由單片機(jī)構(gòu)成的微型計(jì)算機(jī)系統(tǒng)中,由于單片機(jī)的工作常常會受到來自外界電磁場的干擾,造成程序的跑飛,而陷入死循環(huán),程序的正常運(yùn)行被打斷,由單片機(jī)控制的系統(tǒng)無法繼續(xù)工作,會造成整個系統(tǒng)的陷入停滯狀態(tài),發(fā)生不可預(yù)料的后果,所以出于對單片機(jī)運(yùn)行狀態(tài)進(jìn)行實(shí)時監(jiān)測的考慮,便產(chǎn)生了一種專門用于監(jiān)測單片機(jī)程序運(yùn)行狀態(tài)的模塊或者芯片,俗稱“看門狗”(watchdog) 。

看門狗解決的問題是什么:

在啟動正常運(yùn)行的時候,系統(tǒng)不能復(fù)位

在系統(tǒng)跑飛(程序異常執(zhí)行)的情況,使系統(tǒng)復(fù)位,程序重新執(zhí)行

獨(dú)立看門狗概述:

STM32內(nèi)置兩個看門狗:獨(dú)立看門狗和窗口看門狗。

兩個看門狗提供了更高的安全性,時間的精確性和使用的靈活性。

兩個看門狗設(shè)備(獨(dú)立看門狗/窗口看門狗)可以用來檢測和 解決由軟件錯誤引起的故障。當(dāng)計(jì)數(shù)器達(dá)到給定的超時值時,觸發(fā)一個中斷(僅適用窗口看門狗)或者產(chǎn)生系統(tǒng)復(fù)位。

獨(dú)立看門狗(IWDG)由專用的低速時鐘(LSI)驅(qū)動,即使主時鐘發(fā)生故障它仍有效。
獨(dú)立看門狗適合應(yīng)用于需要看門狗作為一個在主程序之外 能夠完全獨(dú)立工作,并且對時間精度要求低的場合。
窗口看門狗由從APB1時鐘分頻后得到時鐘驅(qū)動。通過可配置的時間窗口來檢測應(yīng)用程序非正常的過遲或過早操作.窗口看門狗最適合那些要求看門狗在精確計(jì)時窗口起作用的程序。

M7的獨(dú)立看門狗還可以配置做窗口看門狗使用。
因?yàn)镸7本身帶了窗口看門狗,所以一般情況下,我們都比較少使用此功能。

獨(dú)立看門狗工作原理描述

在鍵值寄存器(IWDG_KR)中寫入0xCCCC,開始啟用獨(dú)立看門狗。此時計(jì)數(shù)器開始從其復(fù)位值0xFFF遞減,當(dāng)計(jì)數(shù)器值計(jì)數(shù)到尾值0x000時會產(chǎn)生一個復(fù)位信號(IWDG_RESET)。
無論何時,只要在鍵值寄存器IWDG_KR中寫入0xAAAA(通常說的喂狗), 自動重裝載寄存器IWDG_RLR的值就會重新加載到計(jì)數(shù)器,從而避免看門狗復(fù)位。
如果程序異常,就無法正常喂狗,從而系統(tǒng)復(fù)位。

獨(dú)立看門狗框圖

時鐘來自于LSI,經(jīng)過分頻,產(chǎn)生一個時鐘,進(jìn)入12位遞減計(jì)數(shù)器。首先在鍵寄存器中寫入0xcccc,那么就開始從初值開始計(jì)數(shù),如果說鍵寄存器中寫入0xaaaa,那么就把RLR寄存器中的值重新加載到計(jì)數(shù)器。當(dāng)程序不正常喂狗的時候,就會一直減到零,然后產(chǎn)生復(fù)位信號。

獨(dú)立看門狗超時時間

溢出時間計(jì)算:
Tout=((4×2^prer) ×rlr) /32 (M4)

32 /(4×2^ prer)就是經(jīng)過分頻后的頻率。其中prer是設(shè)置的PR[2:0]位,然后倒過來就是周期,那么溢出時間就是((4×2^ prer) ×rlr) /32,其中rlr是重裝載寄存器的值。

時鐘頻率LSI=32K, 一個看門狗時鐘周期就是最短超時時間。

最長超時時間= (IWDG_RLR寄存器最大值)X看門狗時鐘周期.

舉個例:如果說要把看門狗溢出時間設(shè)置為1s,首先由于時鐘頻率LSI=32k,如果說預(yù)分頻是64,那么LSI/64=0.5khz,也就是說可以設(shè)置rlr的值為500,這樣的話溢出時間就是1s。注意重裝載寄存器rlr的最大值是2^12-1,不能大于它。

獨(dú)立看門狗寄存器

IWDG_KR:鍵值寄存器,0~15位有效
IWDG_PR:預(yù)分頻寄存器,0~2位有效。具有寫保護(hù)功能,要操作先取消寫保護(hù)
IWDG_RLR:重裝載寄存器,0~11位有效。具有寫保護(hù)功能,要操作先取消寫保護(hù)。
IWDG_SR:狀態(tài)寄存器,0~1位有效

鍵值寄存器:IWDG_KR

KEY[15:0]:鍵值 (Key value)(只能寫,讀為 0x0000)
必須每隔一段時間便通過軟件對這些位寫入鍵值 0xAAAA,否則當(dāng)計(jì)數(shù)器計(jì)數(shù)到 0 時,看門狗會產(chǎn)生復(fù)位。
寫入鍵值 0x5555 可使能對 IWDG_PR、IWDG_RLR 和 IWDG_WINR 寄存器的訪問
寫入鍵值 0xCCCC可啟動看門狗(選中硬件看門狗選項(xiàng)的情況除外)

預(yù)分頻寄存器:IWDG_PR

位 2:0 PR[2:0]:預(yù)分頻系數(shù) (Prescaler divider)
這些位受寫訪問保護(hù)。通過軟件設(shè)置這些位來選擇計(jì)數(shù)器時鐘的預(yù)分頻因子。若要更改預(yù)分頻器的分頻系數(shù),IWDG_SR 的 PVU 位必須為 0。
000:4 分頻
001:8 分頻
010:16 分頻
011:32 分頻
100:64 分頻
101:128 分頻
110:256 分頻
111:256 分頻

重裝載寄存器:IWDG_RLR

位 11:0 RL[11:0]:看門狗計(jì)數(shù)器重載值 (Watchdog counter reload value)
這些位受寫訪問保護(hù)。這個值由軟件設(shè)置,每次對 IWDG_KR 寄存器寫入值 0xAAAA 時,這個值就會重裝載到看門狗計(jì)數(shù)器中。之后,看門狗計(jì)數(shù)器便從該裝載的值開始遞減計(jì)數(shù)。超時周期由該值和時鐘預(yù)分頻器共同決定。
若要更改重載值,IWDG_SR 中的 RVU 位必須為 0

狀態(tài)寄存器:IWDG_SR

位 31:3 保留,必須保持復(fù)位值。

位 2 WVU:看門狗計(jì)數(shù)器窗口值更新 (Watchdog counter window value update) 可通過硬件將該位置 1 以指示窗口值正在更新。當(dāng)在 VDD 電壓域下完成重載值更新操作后(需 要多達(dá) 5 個 RC 40 kHz 周期),會通過硬件將該位復(fù)位。 窗口值只有在 WVU 位為 0 時才可更新。 此位只有在通用“窗口”= 1 時才生成。

位 1 RVU:看門狗計(jì)數(shù)器重載值更新 (Watchdog counter reload value update) 可通過硬件將該位置 1 以指示重載值正在更新。當(dāng)在 VDD 電壓域下完成重載值更新操作后(需 要多達(dá) 5 個 RC 40 kHz 周期),會通過硬件將該位復(fù)位。 重載值只有在 RVU 位為 0 時才可更新。

位 0 PVU:看門狗預(yù)分頻器值更新 (Watchdog prescaler value update) 可通過硬件將該位置 1 以指示預(yù)分頻器值正在更新。當(dāng)在 VDD 電壓域下完成預(yù)分頻器值更新操 作后(需要多達(dá) 5 個 RC 40 kHz 周期),會通過硬件將該位復(fù)位。 預(yù)分頻器值只有在 PVU 位為 0 時才可更新。

IWDG獨(dú)立看門狗操作HAL庫函數(shù)

HAL_StatusTypeDef HAL_IWDG_Init(IWDG_HandleTypeDef *hiwdg);獨(dú)立看門狗的初始化函數(shù)

找到參數(shù)的定義:可以發(fā)現(xiàn)和其他外設(shè)的句柄類似。第一個成員變量是外設(shè)的基地址。

typedef struct {IWDG_TypeDef *Instance; /*!< Register base address */ IWDG_InitTypeDef Init; /*!< IWDG required parameters */HAL_LockTypeDef Lock; /*!< IWDG Locking object */__IO HAL_IWDG_StateTypeDef State; /*!< IWDG communication state */ }IWDG_HandleTypeDef;

然后找到第二個變量IWDG_InitTypeDef的定義:Prescaler配置的是預(yù)分頻系數(shù),Reload配置的是重裝載值。

typedef struct {uint32_t Prescaler; /*!< Select the prescaler of the IWDG. This parameter can be a value of @ref IWDG_Prescaler */uint32_t Reload; /*!< Specifies the IWDG down-counter reload value. This parameter must be a number between Min_Data = 0 and Max_Data = 0x0FFF */ }IWDG_InitTypeDef;

void HAL_IWDG_MspInit(IWDG_HandleTypeDef *hiwdg);初始化回調(diào)函數(shù)

HAL_StatusTypeDef HAL_IWDG_Start(IWDG_HandleTypeDef *hiwdg);啟動獨(dú)立看門狗

HAL_StatusTypeDef HAL_IWDG_Refresh(IWDG_HandleTypeDef *hiwdg);喂狗

獨(dú)立看門狗操作步驟

1.初始化看門狗:預(yù)分頻系數(shù),重裝載值。
HAL_IWDG_Init();
該函數(shù)在操作PR和RLR寄存器之前會取消寫保護(hù)。
2.啟動看門狗
HAL_IWDG_Start();
3.喂狗:
HAL_IWDG_Refresh();

獨(dú)立看門狗實(shí)驗(yàn)

初始化看門狗

如何寫,首先看文件里面的函數(shù)都有啥,然后找參數(shù),然后調(diào)函數(shù)。

根據(jù)步驟1調(diào)用HAL_IWDG_Init函數(shù):

首先找到HAL_IWDG_Init獨(dú)立看門狗的初始化函數(shù):

HAL_StatusTypeDef HAL_IWDG_Init(IWDG_HandleTypeDef *hiwdg) {/* Check the IWDG handle allocation */if(hiwdg == NULL){return HAL_ERROR;}/* Check the parameters */assert_param(IS_IWDG_ALL_INSTANCE(hiwdg->Instance));assert_param(IS_IWDG_PRESCALER(hiwdg->Init.Prescaler));assert_param(IS_IWDG_RELOAD(hiwdg->Init.Reload)); if(hiwdg->State == HAL_IWDG_STATE_RESET){ /* Allocate lock resource and initialize it */hiwdg->Lock = HAL_UNLOCKED;/* Init the low level hardware */HAL_IWDG_MspInit(hiwdg);}/* Change IWDG peripheral state */hiwdg->State = HAL_IWDG_STATE_BUSY; /* Enable write access to IWDG_PR and IWDG_RLR registers */ IWDG_ENABLE_WRITE_ACCESS(hiwdg);/* Write to IWDG registers the IWDG_Prescaler & IWDG_Reload values to work with */MODIFY_REG(hiwdg->Instance->PR, IWDG_PR_PR, hiwdg->Init.Prescaler);MODIFY_REG(hiwdg->Instance->RLR, IWDG_RLR_RL, hiwdg->Init.Reload);/* Change IWDG peripheral state */hiwdg->State = HAL_IWDG_STATE_READY;/* Return function status */return HAL_OK; }

現(xiàn)在知道參數(shù)是個結(jié)構(gòu)體,然后在main里面寫:

IWDG_HandleTypeDef iwdg_handler;

HAL_IWDG_Init(&iwdg_handler);

然后開始對iwdg_handler的參數(shù)進(jìn)行設(shè)置,可以首先看到HAL_IWDG_Init函數(shù)中,有對IWDG_HandleTypeDef類型操作的函數(shù)。那我們可以找到這個函數(shù)的定義。

assert_param(IS_IWDG_ALL_INSTANCE(hiwdg->Instance));assert_param(IS_IWDG_PRESCALER(hiwdg->Init.Prescaler));assert_param(IS_IWDG_RELOAD(hiwdg->Init.Reload));

IS_IWDG_ALL_INSTANCE定義如下:

#define IS_IWDG_ALL_INSTANCE(INSTANCE) ((INSTANCE) == IWDG)

所以說就知道了INSTANCE應(yīng)該被設(shè)置為IWDG。這就叫做有效性判斷。

所以main中寫: iwdg_handler.Instance = IWDG;

所以一個成員變量就設(shè)置好了,同理設(shè)置其他的變量。

可以找到Prescaler相關(guān)的定義,然后可以在main中寫

iwdg_handler.Init.Prescaler = IWDG_PRESCALER_64;

#define IS_IWDG_PRESCALER(__PRESCALER__) (((__PRESCALER__) == IWDG_PRESCALER_4) || \((__PRESCALER__) == IWDG_PRESCALER_8) || \((__PRESCALER__) == IWDG_PRESCALER_16) || \((__PRESCALER__) == IWDG_PRESCALER_32) || \((__PRESCALER__) == IWDG_PRESCALER_64) || \((__PRESCALER__) == IWDG_PRESCALER_128)|| \((__PRESCALER__) == IWDG_PRESCALER_256))

如果說要把看門狗溢出時間設(shè)置為1s,首先由于時鐘頻率LSI=32k,如果說預(yù)分頻是64,那么LSI/64=0.5khz,也就是說可以設(shè)置rlr的值為500,這樣的話溢出時間就是1s。

iwdg_handler.Init.Reload = 500;

啟動看門狗

然后開始調(diào)用HAL_IWDG_Start函數(shù)。

? HAL_IWDG_Start(&iwdg_handler);

喂狗

HAL_IWDG_Refresh(&iwdg_handler);//喂狗

main代碼:

系統(tǒng)復(fù)位后按鍵一直沒有按下(喂狗),一旦到了溢出時間(1s),就會產(chǎn)生復(fù)位。系統(tǒng)如果復(fù)位,led燈會熄滅,系統(tǒng)初始化時候是led燈亮,所以說如果一直不按按鍵,那么系統(tǒng)的led燈會一閃一閃。

如果說按下按鍵,也就是說喂狗的周期小于溢出時間的話,那么程序就不會復(fù)位了,那么led燈就常亮了,這是因?yàn)樵趙hile執(zhí)行之前初始化led燈是亮的,如果一直喂狗的話程序就一直在while循環(huán)里執(zhí)行。

#include "sys.h" #include "delay.h" #include "usart.h" #include "led.h" #include "key.h" #include "exti.h"IWDG_HandleTypeDef iwdg_handler;int main(void) {HAL_Init(); //初始化HAL庫 Stm32_Clock_Init(360,25,2,8); //設(shè)置時鐘,180Mhzdelay_init(180); //初始化延時函數(shù)uart_init(115200); //初始化USARTLED_Init(); //初始化LED EXTI_Init();delay_ms(100);iwdg_handler.Instance = IWDG;iwdg_handler.Init.Prescaler = IWDG_PRESCALER_64;iwdg_handler.Init.Reload = 500;HAL_IWDG_Init(&iwdg_handler);HAL_IWDG_Start(&iwdg_handler);LED0=0;while(1){if(KEY_Scan(0)==WK_UP)//檢測WK_UP按鍵是否按下{HAL_IWDG_Refresh(&iwdg_handler);//喂狗delay_ms(10);}} }

總結(jié)

以上是生活随笔為你收集整理的STM32-独立看门狗原理-实验的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。