STM32:看门狗

发布于:2025-05-01 ⋅ 阅读:(22) ⋅ 点赞:(0)

独立看门狗

简介

独立看门狗(IWDG)由独立的低速时钟(LSI)驱动,即便主时钟发生故障,它依然能够正常工作。其主要作用是在程序出现异常时,通过复位来保障系统的稳定性。独立看门狗的喂狗操作相对简单,只需在规定时间内对相关寄存器进行写入操作即可。它适用于对可靠性要求较高,且主时钟可能出现故障的场景。

窗口看门狗

简介

窗口看门狗(WWDG)由系统时钟(PCLK1)分频后驱动,其工作依赖于系统时钟的正常运行。它相较于独立看门狗,具有更严格的时间监控机制。窗口看门狗设置了一个时间窗口,喂狗操作必须在这个时间窗口内完成,早于或晚于该窗口都会导致系统复位。这种特性使其能够更精准地监控程序的运行状态,适用于对程序运行时序要求较为严格的场景。

两个看门狗的区别

在这里插入图片描述

独立看门狗使用方法

在独立看门狗(IWDG)中,看门狗的超时时间
计算公式为
在这里插入图片描述
prer
是预分频器的值,
rlr
是重装载寄存器的值,40 是独立看门狗的时钟频率(单位:kHz)。

int init_iwdg(u8 prer,u16 rlr)
{
    IWDG_WriteAccessCmd(IWDG_WriteAccess_Enable);
    IWDG_SetPrescaler(prer);
    IWDG_SetReload(rlr);
    IWDG_ReloadCounter(); 
	IWDG_Enable();
}
void IWDG_Feed(void)
{
    IWDG->KR=0xAAAA;
}
int main(void)
{

    IWDG_Init(41875);
    
    while(1)
    {
       IWDG_Feed();
       delay_ms(2500);
    }
}

窗口看门狗使用方法

窗口值:当计数器的值大于窗口值时进行喂狗操作,系统会发生复位。
下限值(固定为 0x40):如果计数器的值递减到 0x40 还没有进行喂狗操作,那么计数器再减一次到 0x3F 时,系统就会复位。
自动喂狗应该在上窗口值和下限值之间
在递减计数器减到 0X40 的时候,进入中断,称它为死前中断或者 叫遗嘱中断,在中函数里面我们应该出来最重要的事情,而且必须得快,因为递减计数器再减 一次,就会产生系统复位。


static void WWDG_NVIC_Config(void)
{
  NVIC_InitTypeDef NVIC_InitStructure; 
  
  NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1); 
  NVIC_InitStructure.NVIC_IRQChannel = WWDG_IRQn;
  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
  NVIC_Init(&NVIC_InitStructure);
}

void WWDG_Config(uint8_t tr, uint8_t wr, uint32_t prv)
{	
	// 开启 WWDG 时钟
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_WWDG, ENABLE);
	
	// 设置递减计数器的值
	WWDG_SetCounter( tr );
	
	// 设置预分频器的值
	WWDG_SetPrescaler( prv );
	
	// 设置上窗口值
	WWDG_SetWindowValue( wr );
	
	// 设置计数器的值,使能WWDG
	WWDG_Enable(WWDG_CNT);	
	
	// 清除提前唤醒中断标志位
	WWDG_ClearFlag();	
	// 配置WWDG中断优先级
	WWDG_NVIC_Config();	
	// 开WWDG 中断
	WWDG_EnableIT();
}

// 喂狗
void WWDG_Feed(void)
{
	// 喂狗,刷新递减计数器的值,设置成最大WDG_CNT=0X7F
	WWDG_SetCounter( WWDG_CNT );
}

void WWDG_IRQHandler(void)
{
	// 清除中断标志位
	WWDG_ClearFlag();
	//真正使用的时候,这里应该是做最重要的事情

}


int main(void)
{
	uint8_t wwdg_tr, wwdg_wr;
	//初始化窗口看门狗,设置计数器初始值为0X7F,上窗口值为0X5F,预分频器为WWDG_Prescaler_8
	WWDG_Config(0X7F, 0X5F, WWDG_Prescaler_8);
	
	
	wwdg_wr = WWDG->CFR & 0X7F//wwdg_wr获得上窗口的值
	while(1)
	{
		wwdg_tr = WWDG->CR & 0X7F;  //获得计数器值
		
		if( wwdg_tr < wwdg_wr )//当计数器的值减小到小于上窗口值的时候
		{
			// 喂狗,重新设置计数器的值为最大0X7F
			WWDG_Feed();
		}
	}
}

在调用 WWDG_Config(0X7F, 0X5F, WWDG_Prescaler_8) 函数时,把计数器初始值设为 0X7F,意味着将计数器设置成了其所能表示的最大值。窗口看门狗开启后,计数器会从这个最大值开始逐次递减。当计数器的值大于上窗口值(这里是 0X5F)时进行喂狗操作,系统会复位;而当计数器递减到 0X40 还未喂狗,再减一次到 0X3F 时系统也会复位。因此,需要在计数器的值处于 0X5F 和 0X40 之间时进行喂狗操作,以此保证系统正常运行。


网站公告

今日签到

点亮在社区的每一天
去签到