STM32学习和实践笔记(29):独立看门狗(IWDG)实验

1.IWDG介绍

1.1 IWDG简介

  STM32F1芯片内部含有两个看门狗外设,一个是独立看门狗IWDG,另一个是窗口看门狗WWDG。

两个看门狗外设(独立和窗口)均可用于检测并解决由软件错误导致的故障。

独立看门狗简单理解其实就是一个12位递减计数器,当计数器从某一个值递减到0时(如果看门狗已激活),系统就会产生一次复位,系统重新开始运行。

如果在计数器递减到0之前,程序重新给这个计数器装载了计数器值,那么系统就不会产生复位。这个程序在正常运行时,不断重载计数器值过程我们称之为“喂狗”。能够重载计数器值,表明程序在正常运行。反之,就表示程序跑飞了或者卡死了,那么看门狗计数器递减到0后,程序就会复位重新启动,这样就解决了程序运行中出现的跑飞或者卡死的故障。

看门狗功能由 VDD 电压域供电,在停止模式和待机模式下仍能工作。          

LSI:独立的低速内部时钟提供时钟源。

根据分频后的计数频率以及重载数值,就能决定独立开门狗的计数到0(溢出)复位的时间。

键寄存器可以写三个关键字,分别对应决定独立看门狗的三种工作模式。

2.IWDG配置步骤

  接下来我们介绍下如何使用库函数对IWDG进行配置。这个也是在编写程序中必须要了解的。具体步骤如下:(IWDG相关库函数在stm32f10x_iwdg.c和stm32f10x_iwdg.h文件中)。

1)开启看门狗各寄存器的访问(给IWDG_KR寄存器写入0X5555

IWDG_WriteAccessCmd(IWDG_WriteAccess_Enable);

2)设置IWDG预分频系数和重装载值

void IWDG_SetPrescaler(uint8_t IWDG_Prescaler);//预分频系数

void IWDG_SetReload(uint16_t Reload);//装入重载值

Tout = (4*2^pre) / 40 * rlr  //计数看门狗复位的时钟

其中Tout为独立看门狗溢出时间,单位是ms(因为计数频率是KHZ)。pre是预分频器系数(0-6),rlr 是重装载寄存器的值,公式内的40是独立看门狗的时钟源,也就是LSI,即40KHZ。

3)重载计数器值(喂狗)(给IWDG_KR寄存器写入0XAAAA)                               

IWDG_ReloadCounter();//写入0XAAAA就会自动重载计数器值。

4)开启IWDG(给IWDG_KR寄存器写入0XCCCC)                               

IWDG_Enable();

3.硬件电路

  由于IWDG是STM32F1内部资源,因此本实验的硬件电路非常简单,只有LED指示灯、K_UP按键连接,其对应的电路图在前面章节中都有介绍,这里就不多说。

D1指示灯用来提示系统运行,D2指示灯用来作为喂狗和系统重启时的提示,K_UP按键用来喂狗操作,喂狗时D2指示灯亮,喂狗失败系统重启,D2指示灯灭。

4.写独立看门狗控制实验程序

  本实验所要实现的功能是:通过K_UP按键进行喂狗,喂狗的时候D2指示灯亮,同时串口输出“喂狗”提示信息,超过喂狗时间系统重启D2指示灯灭,同时串口输出“复位系统”提示信息,同时使用D1指示灯闪烁表示系统运行。

程序框架如下:

(1)初始化IWDG(开启IWDG,设置溢出时间)

(2)编写主函数

main.c

#include "system.h"
#include "led.h"
#include "SysTick.h"
#include "usart.h"
#include "key.h"
#include "iwdg.h"



int main()
{
	u8 i;

	
	
	SysTick_Init(72);
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//中断优先级分组
	LED_Init();
	USART1_Init(9600);
	key_Init();
	IWDG_Init(4, 800);//1280 ms内必须喂狗
	led2=1;
	printf("复位系统\r\n");
	
	
	while(1)
	{
		if(KEY_Scan(0) ==KEY_UP) //按下key_up键喂狗
		{
			IWDG_FeedDog();
			led2=0;
			printf("喂狗\r\n");
		}
		i++;
		if(i%20 ==0)
		{
			led1=!led1;//LED1闪,用来指示主程序循环是否运行
			
		}
		delay_ms(10);
		
	}
}


iwdg.c

#include "iwdg.h"

void IWDG_Init(u8 pre, u16 rlr)
{
	IWDG_WriteAccessCmd(IWDG_WriteAccess_Enable); //开启寄存器访问(给IWDG_KR寄存器写入0X5555)
	IWDG_SetPrescaler(pre); //设置预分频系数
	IWDG_SetReload(rlr);//设置重装载值
	IWDG_ReloadCounter();//重载计数器值(喂狗)(给IWDG_KR寄存器写入0XAAAA) 
	IWDG_Enable();//开启IWDG(给IWDG_KR寄存器写入0XCCCC)                                
}

void IWDG_FeedDog(void)
{
		IWDG_ReloadCounter();
}

在开发板上实验是成功的!结果显示如下:

                    

  • 20
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

复业思维20240108

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值