stm32专题三十四:独立看门狗 IWDG

发布者:JoyfulMelody最新更新时间:2021-11-01 来源: eefocus关键字:stm32  独立看门狗  IWDG 手机看文章 扫描二维码
随时随地手机看文章

独立看门狗简介

IWDG结构框图

(1)独立看门狗时钟


独立看门狗的时钟由独立的 RC 振荡器 LSI 提供, 即使主时钟发生故障它仍然有效,非常独立。 LSI 的频率一般在 30~60KHZ 之间,根据温度和工作场合会有一定的漂移,我们一般取 40KHZ,所以独立看门狗的定时时间并一定非常精确,只适用于对时间精度要求比较低的场合。


(2)计数器时钟

实际的计数频率为:

CK CNT = 40 000 / (4 * 2^{PRV}) Hz

(3)计数器

(4)重装载寄存器


重装载寄存器是一个 12 位的寄存器,里面装着要刷新到计数器的值,这个值的大小决定着独立看门狗的溢出时间。

T_O_U_T = (1 / CKCNT)*RLV = RLV*(4*2^{PRV}) / 40000 left ( s right )

(5)键寄存器

寄存器说明:

(6)状态寄存器:

如何使用IWDG

RCC复位描述


STM32F10xxx支持三种复位形式,分别为系统复位、上电复位和备份区域复位。


1 系统复位

2 电源复位

3 备份域复位

*************************************************************************************************************************


如果独立看门狗 IWDG 产生复位,我们可以从RCC复位和时钟控制寄存器中获取复位原因:

以下是各种复位标志位:

代码分析


标准库中,关于 IWDG 总共就只有以下几个函数,都是配置或读取寄存器,非常简单,就不看源码了:


/** @defgroup IWDG_Exported_Functions

  * @{

  */

 

void IWDG_WriteAccessCmd(uint16_t IWDG_WriteAccess);

void IWDG_SetPrescaler(uint8_t IWDG_Prescaler);

void IWDG_SetReload(uint16_t Reload);

void IWDG_ReloadCounter(void);

void IWDG_Enable(void);

FlagStatus IWDG_GetFlagStatus(uint16_t IWDG_FLAG);

常用的独立看门狗配置 和喂狗操作:


/*

 * 设置 IWDG 的超时时间

 * Tout = prv/40 * rlv (s)

 *      prv可以是[4,8,16,32,64,128,256]

 * prv:预分频器值,取值如下:

 *     @arg IWDG_Prescaler_4: IWDG prescaler set to 4

 *     @arg IWDG_Prescaler_8: IWDG prescaler set to 8

 *     @arg IWDG_Prescaler_16: IWDG prescaler set to 16

 *     @arg IWDG_Prescaler_32: IWDG prescaler set to 32

 *     @arg IWDG_Prescaler_64: IWDG prescaler set to 64

 *     @arg IWDG_Prescaler_128: IWDG prescaler set to 128

 *     @arg IWDG_Prescaler_256: IWDG prescaler set to 256

 *

 * rlv:预分频器值,取值范围为:0-0XFFF

 * 函数调用举例:

 * IWDG_Config(IWDG_Prescaler_64 ,625);  // IWDG 1s 超时溢出

 */

 

void IWDG_Config(uint8_t prv ,uint16_t rlv)

{

// 使能 预分频寄存器PR和重装载寄存器RLR可写

IWDG_WriteAccessCmd( IWDG_WriteAccess_Enable );

// 设置预分频器值

IWDG_SetPrescaler( prv );

// 设置重装载寄存器值

IWDG_SetReload( rlv );

// 把重装载寄存器的值放到计数器中

IWDG_ReloadCounter();

// 使能 IWDG

IWDG_Enable();

}

 

 

// 喂狗

void IWDG_Feed(void)

{

// 把重装载寄存器的值放到计数器中,喂狗,防止IWDG复位

// 当计数器的值减到0的时候会产生系统复位

IWDG_ReloadCounter();

}

然后在主函数中进行测试,如果 看门狗复位,那么就能够检测到相应的复位标志。


main.c


int main(void)

{

// 配置LED GPIO,并关闭LED

LED_GPIO_Config();

 

Delay(0X8FFFFF);

/*------------------------------------------------------------*/

/* 检查是否为独立看门狗复位 */

  if (RCC_GetFlagStatus(RCC_FLAG_IWDGRST) != RESET)

  {

    /* 独立看门狗复位 */

    /*  亮红灯 */

    LED_RED;

 

    /* 清除标志 */

    RCC_ClearFlag();

/*如果一直不喂狗,会一直复位,加上前面的延时,会看到红灯闪烁

在1s 时间内喂狗的话,则会持续亮绿灯*/

  }

  else

  {

    /*不是独立看门狗复位(可能为上电复位或者手动按键复位之类的) */

    /* 亮蓝灯 */

    LED_BLUE;

  }

/*--------------------------------------------------------------*/

// 配置按键GPIO

Key_GPIO_Config();

// IWDG 1s 超时溢出

IWDG_Config(IWDG_Prescaler_64 ,625);

//while部分是我们在项目中具体需要写的代码,这部分的程序可以用独立看门狗来监控

    //如果我们知道这部分代码的执行时间,比如是500ms,那么我们可以设置独立看门狗的

//溢出时间是600ms,比500ms多一点,如果要被监控的程序没有跑飞正常执行的话,那么

//执行完毕之后就会执行喂狗的程序,如果程序跑飞了那程序就会超时,到达不了喂狗

//的程序,此时就会产生系统复位。但是也不排除程序跑飞了又跑回来了,刚好喂狗了,

//歪打正着。所以要想更精确的监控程序,可以使用窗口看门狗,窗口看门狗规定必须在

//规定的窗口时间内喂狗。

while(1)                        

{

// 这里添加需要被监控的代码,如果有就去掉按键模拟喂狗,把按键扫描程序去掉

//--------------------------------------------------------------------------

if( Key_Scan(KEY1_GPIO_PORT,KEY1_GPIO_PIN) == KEY_ON  )

{

// 喂狗,如果不喂狗,系统则会复位,LED1则会灭一次,如果在1s

// 时间内准时喂狗的话,则绿会常亮

IWDG_Feed();

//喂狗后亮绿灯

LED_GREEN;

}   

}

//---------------------------------------------------------------------------

}

关键字:stm32  独立看门狗  IWDG 引用地址:stm32专题三十四:独立看门狗 IWDG

上一篇:stm32专题三十三:RTC实时时钟
下一篇:stm32专题三十五:DAC

小广播
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved