IWDG独立看门狗

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

简介:
        看门狗可以监控程序的运行状态,当程序因为设计漏洞、硬件故障、电磁干扰等原因,出现卡死或跑飞现象时,看门狗能及时复位程序,避免程序陷入长时间的罢工状态,保证系统的可靠性和安全性。而STM32F10xxx内置两个看门狗,分别是IWDG独立看门狗和WWDG窗口看门狗,这节先来讲解独立看门狗。

        独立看门狗(IWDG)
由专用的低速时钟(LSI)驱动,即使主时钟发生故障它也仍然有效。(独立看门狗的复位也可以唤醒低功耗模式中的待机模式)

下面是独立看门狗的框图:




        原理:独立看门狗的核心是中间的12位递减计数器,当计数器计到0时产生IWDG复位,正常状况下,我们要在计数器减到0之前重新装载计数器(喂狗),这样就不会产生复位,当产生IWDG复位时,就说明我们的程序可能有问题。通过这样的方式来检测程序。

        键寄存器:在框图的右上角有一个键寄存器,它的本质是控制寄存器,用于控制硬件电路的工作。为了提高容错率,我们一般通过在为寄存器写入某个特定值来代替寄存器写入一位的功能,例如,当我们为键寄存器写入0xAAAA时才表示喂狗,而不是寄存器当中的某个位置1或置0,如果是某个位的操作,那么程序出问题是偶然的将那个位进行置1或置0,看门狗将起不到作用,所以我们为了降低这种可能性,采用为寄存器写入特定值的方式来实现功能。

        知道了大致原理,下面来写代码:


        首先我们不需要使能LSI的时钟,因为如果独立看门狗已经由硬件选项或软件启动,LSI振荡器将被强制在打开状态,并且不能被关闭。在LSI振荡器稳定后,时钟供应给IWDG。
        
        所以我们可以直接调用IWDG_WriteAccessCmd函数来使能对寄存器IWDG_PR和IWDG_RLR的写操作

IWDG_WriteAccessCmd(IWDG_WriteAccess_Enable);

        可以进行写操作了,我们就可以设置预分频器和计数器的值了。可参考下表以及计算公式



        计算公式:TIWDG = TLSI × PR预分频系数 × (RL + 1)

        这里我们选用1000ms来做实验,参考表可以发现,我们可选的预分频系数的范围是16分频至256分频。这里我们选择16分频。那么我们可以代入公式,TIWDG == 1000,LSI的输入时钟是40KHZ,所以TLSI == 1/40,PR预分频系数 == 16。最终算出RL + 1 = 2500。代码如下:

IWDG_SetPrescaler(IWDG_Prescaler_16);
IWDG_SetReload(2499);

        最后调用IWDG_Enable使能IWDG即可,我们也可以在调用之前先重装载一下计数器,也就是喂狗,调用函数IWDG_ReloadCounter 即可,代码如下:

IWDG_ReloadCounter();
IWDG_Enable();

        这样,独立看门狗的核心代码就写完了,我们只需要按时调用IWDG_ReloadCounter函数进行喂狗操作防止复位就可以了。最后看一下整体的代码。

int main(void)
{
	OLED_Init();
	Key_Init();
	
	OLED_ShowString(1, 1, "IWDG_TEST");
	
	if(RCC_GetFlagStatus(RCC_FLAG_IWDGRST) == SET )
	{
		OLED_ShowString(2, 1, "IWDG_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();
	}
	
	IWDG_WriteAccessCmd(IWDG_WriteAccess_Enable);
	
	//1000ms
	IWDG_SetPrescaler(IWDG_Prescaler_16);
	IWDG_SetReload(2499);
	
	IWDG_ReloadCounter();
	IWDG_Enable();
	
	while(1)
	{
		Key_GetNum();
		
		IWDG_ReloadCounter();
		
		OLED_ShowString(4, 1, "Feed");
		Delay_ms(200);
		OLED_ShowString(4, 1, "    ");
		Delay_ms(600);
	}
}

        首先,对OLED和按键进行初始化,RCC_GetFlagStatus这个函数可以获取复位标志位状态,可以通过这个函数来判断是我们手动按下复位键还是由IWDG导致的复位。再下面就是使能写操作,写寄存器,喂狗,开启看门狗。然后进入while循环。

        while循环中可以获取按键的键码,在Key_GetNum函数内部有一个死循环,只有松开按键才能跳出循环,做看门狗实验测试时,我们可以不松开按键,这样超过1000ms还没有喂狗,就会导致复位。当松开按键时,我们就会按时喂狗,并且在OLED上显示Feed。

结果如图:

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值