WWDG窗口看门狗

参考:bilibili:江协科技,看着视频写了个文字版的,相当于总结笔记,也方便以后查看。

简介:
       窗口看门狗通常被用来监测,由外部干扰或不可预见的逻辑条件造成的应用程序背离正常的运行序列而产生的软件故障。除非递减计数器的值在T6位变成0前被刷新,看门狗电路在达到预置的时间周期时,会产生一个MCU复位。在递减计数器达到窗口寄存器数值之前,如果7位的递减计数器数值(在控制寄存器中)被刷新, 那么也将产生一个MCU复位。这表明递减计数器需要在一个有限的时间窗口中被刷新,意思就是喂狗的时间要在一个范围内,不能过早也不能过晚,否则就会导致复位。

下面是窗口看门狗的框图:




        先看下半部分,可以看到时钟源是PCLK1,也就是APB1的时钟,默认是36Mhz,再看右边,是一个预分频器和一个看门狗控制寄存器WWDG_CR,这个控制寄存器包括了CNT递减计数器,并且这里没有重装载寄存器,所以我们直接往CNT里写值让他递减即可。

        从图中可以看到CNT是6位寄存器,T6的作用就是当作溢出标志位,当T6 == 1时表示没有溢出,当T6 == 0时表示溢出。那么我们算上T6,看这7位,当这7位的计数器减到0x40时,这时6位CNT计数器就减为0了,这时再来一个时钟信号,计数器的值减为0x3F,T6变为0,表示溢出。

        WDGA是窗口看门狗的使能位,当我们使WDGA置为1时,表示启动看门狗。当计数器减至0x3F时,T6位为0,顺着T6头上的那条线,取反之后传到一个或门,或门输出1,上面的与门也就输出1,导致复位。

        接着来看上面的部分,下面的部分可以看作是设置最大时间,那么上面这部分大概率就是设置最小时间了。首先,我们要提前写入一个值给上面的看门狗配置寄存器,当我们一旦执行写入CR操作也就是喂狗操作时,比较器就会比较当前的7位的计数器和上面的配置寄存器的值,如果计数器的值更大,则会输出1至一个与门,与门输出1到或门,或门再输出1到上面的与门导致复位。这个意思就是我们不能过早的喂狗,会导致复位。

        下面是时序图:



 

        可以看到CNT在递减过程中,如果你在不允许刷新的时间写入CR操作也就是喂狗,会导致CNT计数器大于配置寄存器的值而导致复位,如果你在刷新窗口结束了还没有喂狗,会导致T6位变为0导致复位。我们应该在刷新窗口内喂狗。

下面来写代码:
        首先我们使用到APB1的时钟,应该开启对应的时钟,代码如下:

RCC_APB1PeriphClockCmd(RCC_APB1Periph_WWDG, ENABLE);

        然后我们可以设置预分频器的值了,在设置预分频器之前先看这张图:



        这图包含了超时时间的计算公式和最小最大超时值的范围,我们本次实验将采用最大时间50ms,最小时间20ms。所以WDGTB应为3,对应手册里的寄存器描述也就是8分频。所以我们调用函数WWDG_SetPrescaler来设置分频值即可。

WWDG_SetPrescaler(WWDG_Prescaler_8);

       设置好分频器,我们就可以来设置最小最大超时时间了。我们想采用50ms作为最大超时时间,代入上面公式可以得出 50ms = 1/36000 x 4096 x 8 x (T[5:0] + 1)。可以得出(T[5:0] + 1)为55,那么我们可以设置 T[5:0] 为54,这里乘以4096是因为还有一个分频器,但是框图没画出来,我们直接按照公式计算即可。

        最大超时时间算出来了,最小超时时间的公式呢,直接参考up主江协科技的公式:TWIN = TPCLK1 × 4096 × WDGTB预分频系数 × (T[5:0] - W[5:0]),前面和最大超时时间的公式一样,后面从(T[5:0] + 1)变为(T[5:0] - W[5:0])套公式,20ms = 1/36000 x 4096 x 8 x(T[5:0] - W[5:0])可以得到 W[5:0]的值为21。调用函数设置即可,代码如下:

WWDG_SetWindowValue(0x40 | 21);
WWDG_Enable(0x40 | 54);

        注意,这里要或上0x40,因为我们计算没有算上T6位和W6位,但是调用函数要带上这两位,所以这两个函数要或上0x40。

最后在时间范围内调用函数 WWDG_Enable 来喂狗即可,下面我们来看整体代码:

int main(void)
{
	OLED_Init();
	Key_Init();
	
	OLED_ShowString(1, 1, "WWDG_TEST");
	
	if(RCC_GetFlagStatus(RCC_FLAG_WWDGRST) == SET )
	{
		OLED_ShowString(2, 1, "WWDG_RST");
		Delay_ms(500);
		OLED_ShowString(2, 1, "        ");
		Delay_ms(100);
		
		RCC_ClearFlag();
	}
	else
	{
		OLED_ShowString(3, 1, "RST");
		Delay_ms(500);
		OLED_ShowString(3, 1, "   ");
		Delay_ms(100);
		
		RCC_ClearFlag();
	}
	
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_WWDG, ENABLE);
	
	WWDG_SetPrescaler(WWDG_Prescaler_8);
	WWDG_SetWindowValue(0x40 | 21);	//30ms
	WWDG_Enable(0x40 | 54);			//50ms
	
	while(1)
	{
		Key_GetNum();
		
		OLED_ShowString(4, 1, "Feed");
		Delay_ms(20);
		OLED_ShowString(4, 1, "    ");
		Delay_ms(20);
	
		WWDG_SetCounter(0x40 | 54);
	}
}

        初始化OLED和按键,调用RCC_GetFlagStatus函数来判断是不是由看门狗导致的复位,使能时钟,设置分频器,设置最大最小超时时间,在主循环中不断喂狗。当我们按下按键不松,在时间范围内没有按时喂狗,程序会复位,OLED上会显示WWDG_RST。结果如下:

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值