1.独立ウォッチドッグ(IWDG)の基礎知識
1.IWDGの概要
- 独立したウォッチドッグは、専用の低速バス、つまりLSIバス(クロック周波数40KHz)によって駆動されます。これは、メインクロックに障害が発生した場合でも機能します。
- 独立ウォッチドッグは、ウォッチドッグがメインプログラムの外部で完全に独立して動作する必要があり、時間精度が低い必要があるアプリケーションに適しています。
2.IWDG機能の説明
キー値レジスタ(IWDG_KR)に0xCCCCを書き込んで、独立ウォッチドッグを開始します。このとき、カウンタはリセット値0xFFFからデクリメントを開始し、カウンタ値が終了値0x000までカウントされるとリセット信号(IWDG_RESET)が生成されます。
キー値レジスタIWDG_KR(通常は犬の餌付けと呼ばれます)に0xAAAAを書き込むと、ウォッチドッグのリセットを回避するために、自動リロードレジスタIWDG_RLRの値がカウンターにリロードされます。
プログラムが異常な場合、犬は正常に給餌できず、システムがリセットされます。
3.IWDGレジスタ
STM32中国語リファレンスマニュアルでのIWDGレジスタの紹介は次のとおりです。
4.IWDGタイムアウト
STM32中国語リファレンスマニュアルでのIWDGタイムアウト時間の紹介は次のとおりです。
- オーバーフロー時間の計算: Tout =((4 * 2 ^ prer)* rlr)/ 40(ms)
- prer:プリスケーラ係数:0〜7(下位3ビットのみが有効)、プリスケーラレジスタ(IWDG_PR)によって設定されます。
- rlr:レジスタ(IWDG_RLR)の値をリロードします(下位11ビットが有効です)。
第二に、独立ウォッチドッグ(IWDG)プログラムの実装
1.IWDG関連のライブラリ関数
void IWDG_WriteAccessCmd(uint16_t IWDG_WriteAccess);//取消写保护:0x5555使能
void IWDG_SetPrescaler(uint8_t IWDG_Prescaler); //设置预分频系数:写PR
void IWDG_SetReload(uint16_t Reload); //设置重装载值:写RLR
void IWDG_ReloadCounter(void); //喂狗:写0xAAAA到KR
void IWDG_Enable(void); //使能看门狗:写0xCCCC到KR
2.IWDG制御プログラム
iwdg.h
#ifndef __IWDG_H
#define __IWDG_H
#include "stm32f10x.h"
void IWDG_Init(u8 prer,u16 rlr) ;
void IWDG_Feed(void);
#endif
iwdg.c
#include "iwdg.h"
/*******************************************************************************
* 函 数 名 : IWDG_Init
* 函数功能 : IWDG初始化
* 输 入 : pre:预分频系数(0-6)
rlr:重装载值(12位范围0xfff)
独立看门狗复位时间计算公式:t=(4*2^pre*rlr)/40 (ms)
* 输 出 : 无
*******************************************************************************/
void IWDG_Init(u8 prer,u16 rlr)
{
IWDG_WriteAccessCmd(IWDG_WriteAccess_Enable); //使能对寄存器IWDG_PR和IWDG_RLR的写操作,即取消写保护
IWDG_SetPrescaler(prer); //设置IWDG预分频值
IWDG_SetReload(rlr); //设置IWDG重装载值
IWDG_ReloadCounter(); //按照IWDG重装载寄存器的值重装载IWDG计数器
IWDG_Enable(); //使能IWDG
}
//喂独立看门狗
void IWDG_Feed(void)
{
IWDG_ReloadCounter();//重装载初值
}
main.c
#include "stm32f10x.h"
#include "iwdg.h"
int main()
{
/**
其它初始化省略
**/
IWDG_Init(IWDG_Prescaler_64,625); //独立看门狗初始化,超时时间1s
while(1)
{
/**
其它程序省略
如果其中程序的运行时间超过1s,需要在其中添加喂看门狗函数 IWDG_Feed();
**/
IWDG_Feed(); //喂看门狗
}
}