IWDG独立看门狗

     独立看门狗 (IWDG) 由专用的低速时钟 (LSI) 驱动,即使主时钟发生故障它也仍然有效。窗口看门狗由从 APB1时钟分频后得到的时钟驱动,通过可配置的时间窗口来检测应用程序非正常的过迟或过早的操作。

IWDG最适合应用于那些需要看门狗作为一个在主程序之外,能够完全独立工作,并且对时间精度要求较低的场合。

 

配置参数

在了解如何配置 IWDG之前,我们先分析以下它的功能框图: 

 

 

 

 

配置代码

bsp_idwg.c 源文件

#include "bsp_iwdg.h"
 
 
/*
 * 设置 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
 *
 *        独立看门狗使用LSI作为时钟。
 *        LSI 的频率一般在 30~60KHZ 之间,根据温度和工作场合会有一定的漂移,我
 *        们一般取 40KHZ,所以独立看门狗的定时时间并一定非常精确,只适用于对时间精度
 *        要求比较低的场合。
 *
 * Rlv:重装载寄存器的值,取值范围为:0-0XFFF
 * 函数调用举例:
 * IWDG_Config(IWDG_Prescaler_64 ,625);  // IWDG 1s 超时溢出 
 *                        (64/40)*625 = 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();
}
 
 
/*---------------------------- END OF FILE ----------------------------*/
 

bsp_adc.h 头文件

#ifndef __BSP_IWDG_H
#define __BSP_IWDG_H
 
 
#include "stm32f10x.h"
 
 
void IWDG_Config(uint8_t Prv ,uint16_t Rlv);
void IWDG_Feed(void);
 
 
#endif /* __BSP_IWDG_H */
 
 
/*---------------------------- END OF FILE ----------------------------*/
 

  

设计思维

1、单一主循环、非多线程

这个是我们最常见的,往往出现在裸机程序上面,只需要在 main函数的 while主循环里及时进行喂狗就可以了:

#include "bsp_iwdg.h"
 
 
/************************************************
函数名称 : main
功    能 : 主函数入口
参    数 : 无
返 回 值 : 无
*************************************************/
int main(void)
{
	/* Initial Configuration */
	System_Starts();
	
	/* -------- End -------- */
 
    IWDG_Config(IWDG_Prescaler_128 ,625);	// 4S
 
		
    if (RCC_GetFlagStatus(RCC_FLAG_IWDGRST) != RESET){ /* 是否为 iwdg复位 */	
		RCC_ClearFlag();
		printf("%s\n", "iwdg reset\n");
	}
 
	/* Infinite loop */
    while (1)
    {
        /* User handling code */
        ...
        ...
 
        IWDG_Feed();        // 喂狗
    }
}

  

 

posted @ 2022-05-02 17:22  流水江湖  阅读(187)  评论(0编辑  收藏  举报