stm32-看门狗

简介

看门狗的作用就是在程序出问题时复位程序 ,让程序从头运行。看门狗本质是定时器,计数器在自减,程序在规定时间内重置计数器(喂狗),不让计数器归0,如果程序出问题没有及时重置,导致计数归0,硬件电路就会自动复位。

独立看门狗 的独立表现在它有专用的时钟LSI ,时间要求是不能晚于一个时间点喂狗;窗口看门狗 的时钟是APB1总线时钟 ,没有专用时钟,时间要求是不能早于一个时间点喂狗,也不能晚于一个时间点喂狗,所以它比独立看门狗能处理更多问题,比如程序跑飞但依然会在一个时间点之前喂狗,程序有时比较早喂狗,有时比较晚喂狗。

IWDG结构

IWDG中预分频器是8位的,最多可以256分频,计数器是12位,最大值是4095。时钟LSI经过预分频后控制计数器自减一次的时间;预先在RLR寄存器中写入重装值,然后在键寄存器中写入特定数据0xAAAA,重装值就会复制到计数器中,完成重置喂狗。SR状态寄存器就是标准电路运行状态的。

其中的寄存器都位于1.8v供电区,工作电路位于VDD供电区。停机和待机模式下HSE,HSI时钟关闭,但是IWDG使用LSI时钟没有影响,计数器可以继续自减。

程序是可能受到干扰的,如果常规使用控制寄存器里的某一位来控制看门狗电路,有可能会因为干扰使得1变成0或者0变成1改变电路而产生问题。所以使用16位的键寄存器,用16位数据来控制电路,哪怕因为干扰改变了某几位的值,改变之后的值刚好是0xcccc,0xaaaa,0x5555的概率也是很小的,如果变成了0x5555以外的值会马上开启对寄存器的写保护,增强了抗干扰能力。

时间计算

IWDG计数器归0的时间=*预分频系数*(重装值+1)就是LSI时钟频率倒数,即0.025ms,而预分频系数就不是什么写入值+1了,这里0~7的写入值有分别对应的预分频值。0.025ms*预分频系数即为计数器自减一次所用时间,再乘上重装值即为从重装值自减到0所需时间,必须在这个时间内喂狗。

WWDG结构

来自APB1的36MHZ时钟,经过预分频后控制计数器自减的时间。在这里设计的是计数器和控制寄存器CR合二为一 了,T0~T5 位用于计数器自减,T6 位是溢出标志位,T6=1表示未溢出,T6=0表示溢出,也就是说对于整个控制寄存器来说自减到10 0000即0x40 时就相当于归0了,再减就是01 1111,T6=0了,表示溢出;对于寄存器的T5~T0位来说是自减到0就归0。需要喂狗即重置计数器时直接将值写入CR寄存器就行了。

控制寄存器中还有一位WDGA使能位 ,=1就看门狗使能,WDGA位和取反之后经过一个或门的T6位结果 会经过一个与门 控制是否复位:WDGA=0,看门狗不使能时与门直接输出为0,不复位;WDGA=1,T6=1即未归0,取反后是0,经过或门输出值由另一端确定;T6=0即归0,取反是1,输出结果为1即归0后会复位。但是看门狗一旦开启就不能关闭了,让WDGA=0也没用。

WWDG除了计数归0会复位之外,过早喂狗也会复位。这个较早的时间窗口值在CFR寄存器写入,当执行喂狗操作即写入CR寄存器时,图中另一个与门的写入CR寄存器这个输入端就=1了,比较写入重装值之前CR寄存器的值和设置的CFR寄存器的值大小后,如果CR的值大于CFR的值,说明计数器还没有自减到较早的时间值就喂狗了,即喂狗喂早了,不在设置的时间窗口内喂狗,与门另一端输入=1,输出结果1,再经过或门,输出1,最后通过与门输出1,看门狗复位。

工作特性

控制寄存器值=0x40时T6位=1,这时还不会复位,再自减一次到0x3F时T6位=0了就复位了。在0x40时会产生一个中断,提醒你马上要复位了,中断里可以重置计数器避免复位。

时间计算

PCLK1时钟在预分频前会进行一个4096分频 ,因为36MHZ还是太快了。所以在计算时间的时候会额外乘上4096,这样***4096*预分频系数** 就是计数器自减一次所用时间,再乘上寄存器的T5~T0位+1就是计数器从重装值归0的时间。预分频系数=2^写入值,范围是1、2、4、8。以T5~T0位为准,计数器最大可以自减2^6-1即63次。

窗口时间即最早喂狗时间=*4096*预分频系数*(T5~T0位的值 - CFR寄存器低五位的值),这就是计数器从重装值自减到最早喂狗的时间。

喂狗时间必须在这两个时间点之间。

对比

IWDG代码

使用IWDG,需要先开启LSI时钟,但开启看门狗时LSI时钟会自动开启,所以不需要手动开启了。接下来先解除对寄存器的写保护,之后才能写入预分频值和重装值,最后开启看门狗,在程序中不断循环喂狗。

cs 复制代码
/* 使用IWDG,需要先开启LSI时钟,但开启看门狗时LSI时钟会自动开启,所以不需要手动开启了。接下来先解除对寄存器的写保护
之后才能写入预分频值和重装值,最后开启看门狗,在程序中不断循环喂狗。
*/
int main()
{
	OLED_Init();
	key_init();
	
	OLED_ShowString(1,1,"IWDG TEST");
	if(RCC_GetFlagStatus(RCC_FLAG_IWDGRST)==SET)//用标志位来判断复位是IWDG导致的还是普通复位
	{
		OLED_ShowString(2,1,"IWDGRST");
		Delay_ms(500);
		OLED_ShowString(2,1,"       ");
		RCC_ClearFlag();//清除看门狗标志位
	}
	else
	{
		OLED_ShowString(2,1,"RST");
		Delay_ms(500);
		OLED_ShowString(2,1,"   ");
	}
	//设定IWDG设置超时时间为1000ms,1000=0.025*分频系数*(重装值+1)
	IWDG_WriteAccessCmd(IWDG_WriteAccess_Enable);//解除写保护。这个函数就是关于写保护的,enable就是在键寄存器写入了0x5555即解除写保护
	IWDG_SetPrescaler(IWDG_Prescaler_16);//预分频系数尽量选小的,频率快可以减小误差
	IWDG_SetReload(2500-1);//重装值
	
	//启动看门狗前可以喂一次狗,这样开启后就是从重装值开始自减
	IWDG_ReloadCounter();//喂狗
	IWDG_Enable();//开启看门狗
 while(1)
 {
	 key_num();//按键使用的是阻塞式写法,按住按键不松开程序会一直卡死在获取按键,就不能执行喂狗操作了,看门狗就会不断复位
	 
	 IWDG_ReloadCounter();
	 OLED_ShowString(3,1,"FEED");//喂一次狗就闪现一次FEED
		Delay_ms(500);
		OLED_ShowString(3,1,"    ");
	 Delay_ms(300);//间隔800ms或1000ms喂一次狗,满足时间要求1000ms内,看门狗不会复位,手动按下复位键时屏幕闪现"RST"。间隔1200ms就超时了,看门狗复位,屏幕会闪现"IWDGRST"
	 
 }
}

WWDG代码

使用WWDG,需要手动开启时钟,接下来写入预分频值和最早时间窗口值,最后开启看门狗,在程序中不断循环向控制寄存器CR写入值,即喂狗。

使能,也是一次喂狗。看门狗关闭时计数器也在运行着,开启看门狗时计数器可能是任何值,所以在使能的时候要再赋一次值并与上0x40将T6位置1,防止出现一打开就复位的情况,还要注意上面的使能喂狗到下面循环喂狗的间隔时间也要满足要求,因为这是两次喂狗。

cs 复制代码
/* 使用WWDG,需要手动开启时钟,接下来写入预分频值和最早时间窗口值,最后开启看门狗,在程序中不断循环向控制寄存器CR写入值,即喂狗。
*/
int main()
{
	OLED_Init();
	key_init();
	
	OLED_ShowString(1,1,"WWDG TEST");
	if(RCC_GetFlagStatus(RCC_FLAG_WWDGRST)==SET)//用标志位来判断复位是WWDG导致的还是普通复位
	{
		OLED_ShowString(2,1,"WWDGRST");
		Delay_ms(500);
		OLED_ShowString(2,1,"       ");
		RCC_ClearFlag();//清除看门狗标志位
	}
	else
	{
		OLED_ShowString(2,1,"RST");
		Delay_ms(500);
		OLED_ShowString(2,1,"   ");
	}
	
	//设定WWDG时间为30~50ms。得出预分频选择8,T5~T0位是54,窗口值是21
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_WWDG,ENABLE);
	WWDG_SetPrescaler(WWDG_Prescaler_8);
	WWDG_SetWindowValue(0x40|21);//窗口值用的是低五位,所以与上0x40把第六位置1
	WWDG_Enable(0x40|54);//使能,也是一次喂狗。看门狗关闭时计数器也在运行着,开启看门狗时计数器可能是任何值,所以在使能的时候要再赋一次值并与上0x40将T6位置1,防止出现一打开就复位的情况
	
	//注意上面的使能喂狗和下面循环的喂狗间隔时间也要满足要求,因为这是两次喂狗。
	Delay_ms(40);
	while(1)
 {
	 key_num();//按键使用的是阻塞式写法,按住按键不松开程序会一直卡死在获取按键,就不能执行喂狗操作了,看门狗就会不断复位,屏幕闪现"WWDGRST"

	WWDG_SetCounter(0x40|54);//喂狗
	 OLED_ShowString(3,1,"FEED");//喂一次狗就闪现一次FEED
		Delay_ms(20);
		OLED_ShowString(3,1,"    ");
	 Delay_ms(20);//间隔40ms喂一次狗,满足时间要求,看门狗不会复位,手动按下复位键时屏幕闪现"RST"。
	 
 }
}
相关推荐
M1582276905521 分钟前
三格串口服务器:RS232/485 设备联网解决方案
运维·服务器·单片机
自小吃多42 分钟前
PCB Editor放置元器件笔记
笔记·嵌入式硬件
736c1 小时前
STM32-NVIC 13
单片机·嵌入式硬件
国科安芯1 小时前
ASC8T245S:把 8 位并行总线稳稳“跨过“电压域的双电源收发器
网络·分布式·单片机·嵌入式硬件·fpga开发·架构
宣宣猪的小花园.1 小时前
【控制理论】稳定性为什么是一切控制的前提?
人工智能·嵌入式硬件·机器学习
Messy create1 小时前
【BMS-三级架构】
单片机·mcu·架构·能源
佳児素花痴╮1 小时前
STM32(STM32U575RIT6)基础学习(GPIO)
stm32·单片机·嵌入式硬件
星栖与芯2 小时前
# STM32MP157+LiteOS-M GCC极简工程:启动源码适配+Windows Make终极避坑
windows·stm32·单片机
深圳市恒锐丰科技杨生3 小时前
SA8330 2.5‑15V 2.0A 三相半桥无刷电机驱动芯片|低压 BLDC 预驱动方案
嵌入式硬件·硬件工程