STM32 入門チュートリアル (WDG ウォッチドッグ)

リファレンス チュートリアル:[14-1] WDG watchdog_bilibili_bilibili

1. WDG (ウォッチドッグ) ウォッチドッグ:

(1) ウォッチドッグはプログラムの実行ステータスを監視できます。設計の抜け穴、ハードウェア障害、電磁干渉などによりプログラムが停止したり暴走したりすると、ウォッチドッグはプログラムを適時にリセットして、 プログラムが長期的なストライク状態に陥るのを防ぎ、システムの信頼性と安全性を確保します。

(2) ウォッチドッグは本質的にはタイマーです。プログラムが指定された時間範囲内にドッグフィード (カウンタのリセット) 操作を実行しない場合、ウォッチドッグ ハードウェア回路リセット信号を自動的に生成します。

(3) STM32 には 2 つの組み込みウォッチドッグがあります。

①独立ウォッチドッグ (IWDG): 独立して動作し、時間精度の要件は低くなります。

②ウィンドウ ウォッチドッグ (WWDG): ウォッチドッグは正確なタイミング ウィンドウで機能する必要があります。

2. 独立監視機関 (IWDG):

(1) IWDG ブロック図:

① クロック生成回路には 4 つの発振源があり、そのうちの 1 つは内部 40kHz 低速 RC 発振器 (LSI RC 40kHz) で、独立したウォッチドッグにクロックを供給します。ユーザーが手動でオンにします。

②LSIクロックはプリスケーラに入力され分周され、プリスケーラレジスタにより分周係数が設定されます。

LSI クロックは事前に分周され、ダウン カウンタを駆動してカウントダウンします (12 ビット カウンタの最大値は4095)、カウンタ値が 0 になると、IWDG リセット信号が生成されます

IWDG がリセット信号を生成したくない場合は、カウンタ値が 0 にデクリメントされる前に、適切な値でカウンタをリロードします。 (つまり、「犬に餌をやる」)。この値は、リロード レジスタを通じてダウン カウンタに書き込まれます。ダウン カウンタをいつリロードするかは、キー レジスタによって制御されます。

(2) IWDG キーレジスタ:

①キー レジスタは本質的に制御レジスタであり、ハードウェア回路の動作を制御するために使用されます。

② 干渉の可能性がある場合、 は通常、制御レジスタに 1 ビットを書き込む機能をキー レジスタ全体に特定の値を書き込むことで置き換え、ハードウェアへの干渉を軽減します。回路。 確率

キーレジスタに書き込まれる値

効果

0xCCCC

独立したウォッチドッグを有効にする

0xAAAA

IWDG_RLR の値がカウンターに再ロードされます (ドッグに餌を与えます)

0x5555

IWDG_PR および IWDG_RLR から書き込み保護を削除します

0x5555以外の値

IWDG_PR および IWDG_RLR の書き込み保護を有効にする

(3) IWDG タイムアウト:

3. ウィンドウ ウォッチドッグ (WWDG):

(1) WWDG ブロック図:

①ウィンドウ ウォッチドッグのクロック ソースは PCLK1 (36MHz) であり、クロックはプリスケーラ (図には示されていません) に入る前に 4096 で分周されます。

WWDG_CR はカウンターをデクリメントします (T0 ~ T5 は有効なカウント ビット、T6 は有効なカウント ビットです)オーバーフロー フラグ ビット、カウント値のデクリメント プロセス中に T6 ビットは 0 となり、 オーバーフロー) および制御レジスタ ( WDGA ビットが 1 の場合、ウィンドウ ウォッチドッグが開始されます) を 1 つに結合した は、T6 ビットが 0 であることを満たす必要があります。 WDGA ビットが 1 の場合、WWDG は 2 つの条件下でのみリセット信号を生成します。ウィンドウ ウォッチドッグはレジスタをリロードせず、 をリロードする必要があります (犬に餌をやる)ダウンカウンターに直接値を書き込むだけです

窓番犬の最も早い犬の餌やり時間は WWDG_CFR に書き込まれます。犬の餌やり時間が早すぎると、窓番犬はリセット信号が発生します。

ダウン カウンタに書き込むとき (犬に餌を与えるとき)、コンパレータが有効になり、コンパレータはダウン カウンタと比較します (犬に餌をやる直前) の値とコンフィギュレーション レジスタの値 ダウン カウンタの値が大きいほど、犬に餌をやる時間が早すぎることを意味し、 WDGA=1 の場合、 コンパレータ出力はハイレベルとなり、 リセット信号が生成されます。

(2) WWDG の動作特性:

①ダウンカウンターT[6:0]の値が0x40未満(つまりT6=0)の場合(犬の餌やりが間に合わなかった) 、WWDG はリセットを生成します。

②ダウンカウンタ T[6:0] がウィンドウ W[6:0] の外でリロードされたとき (犬の餌やりの時間が早すぎます)、WWDG はリセットを生成します。

③ダウンカウンタT[6:0]が0x40に等しい場合、早期ウェイクアップ割り込み(EWI、「プリデス割り込み」とも呼ばれます)を生成できます。カウンタはWWDGを回避するために割り込み関数でリロードできます。リセット(犬に餌を与える最後の時間)犬に餌を与えるために中断を使用します)。

④WWDGリセットを避けるため、定期的にWWDG_CRレジスタへの書き込み(ドッグ送り)を行ってください。

(3) WWDG タイムアウト時間:

4. IWDG と WWDG の比較:

IWDGの独立監視機関

WWDG ウィンドウ ウォッチドッグ

リセット

カウンタが0になった後

カウンタ T[5:0] が 0 に減少した後、カウンタは途中でリロードされます。

割り込み

なし

早期ウェイクアップ割り込み

クロックソース

LSI(40KHz)

PCLK1(36MHz)

プリスケーラ係数

4、8、32、64、128、256

1、2、4、8

カウンター

12ビット

6ビット(有効数)

残業時間

0.1ms~26214.4ms

113us~58.25ms

犬に餌を与える方法

キーレジスタを書き込み、固定値RLRをリロード

カウンターに直接書き込み、書き込んだ分だけリロードします。

誤用の防止

キーレジスタと書き込み保護

なし

使用

独立して作業し、時間精度の要件が低い

ウォッチドッグが正確なタイミング ウィンドウ内で機能することを要求する

5. 独立したウォッチドッグの使用例:

(1) 下図のように回路を接続し、OLED ディスプレイのプロジェクトフォルダーをコピーしてテンプレートとして使用します。

(2) stm32f10x_iwdg.h ファイルには、IWDG モジュールに関連する関数があります。

[1]IWDG_WriteAccessCmd 関数: 書き込みイネーブル制御 (キー レジスタに 0x5555 を書き込み、IWDG_PR および IWDG_RLR の書き込み保護を解除または有効にします) )。

[2]IWDG_SetPrescaler 関数: プリスケーラーの分周係数を設定します (IWDG_PR を書き込みます)。

[3]IWDG_SetReload 関数: リロード値を設定します (IWDG_RLR を書き込みます)。

[4]IWDG_ReloadCounter 関数: ダウン カウンターをリロードします (キー レジスタに 0xAAAA を書き込みます。つまり、犬に餌を与えます)。

[5]IWDG_Enable 関数: 独立したウォッチドッグを開始します (キー レジスタには 0xCCCC が書き込まれます)。

[6]IWDG_GetFlagStatus関数:ステータスフラグビットを取得します。

(3) 次のコードを main.c ファイルに貼り付けてコンパイルし、デバッグ用にプログラムを開発ボードにダウンロードします。

① 通常の状況では、プログラムを開発ボードにダウンロードした後、OLED 画面に「RST」が 1 回表示され、その後「FFED」が点滅し続けます。リセット ボタンを押すと、OLED 画面に再び「RST」が表示されます。が点滅し続け、「FFED」と表示されます。

キーを押し続けると、プログラムは Key_GetNum 関数プログラムは犬に時間内に餌を与えることができないため、ウォッチドッグはリセット信号を生成し、IWDGRST を 1 にすると、プログラムが最初から始まります。IWDG によるリセットにより、OLED 画面には「RST」が表示されず、「IWDGRST」が表示され、その後「FFED」が点滅し続けます。

#include "stm32f10x.h"                  // Device headerCmd
#include "OLED.h"
#include "Delay.h"
#include "Key.h"

int main()
{
	OLED_Init();
Key_Init();
	
	OLED_ShowString(1,1,"IWDG TEXT");
	
	if(RCC_GetFlagStatus(RCC_FLAG_IWDGRST) == SET)  //判断IWDG是否产生复位
	{
		OLED_ShowString(2,1,"IWDGRST");  //看门狗导致的复位
		Delay_ms(500);
		OLED_ShowString(2,1,"       ");
		Delay_ms(100);
		
		RCC_ClearFlag();  //清除复位标志
	}
	else
	{
		OLED_ShowString(3,1,"RST");  //不是看门狗导致的复位
		Delay_ms(500);
		OLED_ShowString(3,1,"   ");
		Delay_ms(100);
	}
	
	//解除IWDG的写保护
	IWDG_WriteAccessCmd(IWDG_WriteAccess_Enable);
	
	//配置分频系数(40MHz经过16分频为2.5MHz)
	IWDG_SetPrescaler(IWDG_Prescaler_16);
	
	//配置重装值
	IWDG_SetReload(2500 - 1);  //超时时间为1000ms
	
	//先喂一次狗(键寄存器写入0x5555以外的值,同时开启写保护)
	IWDG_ReloadCounter();
	
	//启动看门狗
	IWDG_Enable();
	
	while(1)
	{
		Key_GetNum();
		//按下按键不放,程序会卡死在Key_GetNum函数的死循环中
		
		IWDG_ReloadCounter();   //喂狗
		
		OLED_ShowString(4,1,"FFED");
		Delay_ms(400);
		OLED_ShowString(4,1,"FFED");
		Delay_ms(200);
	}
}

6. ウィンドウ ウォッチドッグの使用例:

(1) 下図のように回路を接続し、上記例のプロジェクトフォルダをコピーしてテンプレートとして使用します。

(2) stm32f10x_wwdg.h ファイルには、WWDG モジュールに関連する関数があります。

[1]WWDG_DeInit 関数: デフォルト設定を復元します。

[2]WWDG_SetPrescaler 関数: プリスケーラーの分周係数を設定します。

[3]WWDG_SetWindowValue 関数: ウィンドウ値を構成します。つまり、最も早い犬の餌やり時間を設定します (WWDG_CFR と書き込みます)。

[4]WWDG_EnableIT 関数: 早期ウェイクアップ割り込みを有効にします。

[5]WWDG_SetCounter 関数: ダウン カウンターをリロードします (WWDG_CR を書き込み、つまり犬に餌を与えます)。

[6]WWDG_Enable 関数: ウィンドウ ウォッチドッグを開始します (ダウン カウンターに初期値を与えます)。

[7]WWDG_GetFlagStatus関数:フラグビットを取得します。

[8]WWDG_ClearFlag関数: フラグビットをクリアします。

(3) 次のコードを main.c ファイルに貼り付けてコンパイルし、デバッグ用にプログラムを開発ボードにダウンロードします。

① 通常の状況では、プログラムを開発ボードにダウンロードした後、OLED 画面に「RST」が 1 回表示され、その後「FFED」が点滅し続けます。リセット ボタンを押すと、OLED 画面に再び「RST」が表示されます。が点滅し続け、「FFED」と表示されます。

キーを押し続けると、プログラムは Key_GetNum 関数プログラムは犬に時間内に餌を与えることができないため、ウォッチドッグはリセット信号を生成し、WWDGRST

③ ドッグの餌やり時間が 30ms より早くなるように、while ループ内の遅延関数のパラメータを変更します。 、ドッグに餌を与えた後にリセットが行われます < a i=2> 信号は WWDGRST に 1 に連結され、プログラムは最初から開始されます。WWDG によるリセットにより、OLED 画面が表示されます。 「RST」は表示されず、「WWDGRST」が表示され、その後「FFED」が点滅します

#include "stm32f10x.h"                  // Device headerCmd
#include "OLED.h"
#include "Delay.h"
#include "Key.h"

int main()
{
	OLED_Init();
	Key_Init();
	
	OLED_ShowString(1,1,"WWDG TEXT");
	
	if(RCC_GetFlagStatus(RCC_FLAG_WWDGRST) == SET)  //判断WWDG是否产生复位
	{
		OLED_ShowString(2,1,"WWDGRST");  //看门狗导致的复位
		Delay_ms(500);
		OLED_ShowString(2,1,"       ");
		Delay_ms(100);
		
		RCC_ClearFlag();  //清除复位标志
	}
	else
	{
		OLED_ShowString(3,1,"RST");  //不是看门狗导致的复位
		Delay_ms(500);
		OLED_ShowString(3,1,"   ");
		Delay_ms(100);
	}
	
	//开启WWDG时钟
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_WWDG, ENABLE);
	
	//配置分频系数(36MHz经过8×4096分频为1098.63Hz)
	WWDG_SetPrescaler(WWDG_Prescaler_8);
	
	//配置窗口值(这个值多多少少会有误差,但不大)
	WWDG_SetWindowValue(21|0x40);  //最早喂狗时间为30ms,过早喂狗会复位(0x40的作用是置W6为1,21由公式计算而得)
	
	//启动看门狗(这个值多多少少会有误差,但不大)
	WWDG_Enable(54|0x40);          //最晚喂狗时间为50ms,过晚喂狗会复位(0x40的作用是置T6为1,54由公式计算而得)
	
	while(1)
	{
		Key_GetNum();
		//按下按键不放,程序会卡死在Key_GetNum函数的死循环中
		
		OLED_ShowString(4,1,"FFED");
		Delay_ms(20);
		OLED_ShowString(4,1,"    ");
		Delay_ms(20);
		
		WWDG_SetCounter(54|0x40);   //喂狗(0x40的作用是置T6为1)
	}
}

おすすめ

転載: blog.csdn.net/Zevalin/article/details/134804944