【STM32独立看门狗(IWDG) 】

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档

文章目录

  • 前言
  • 一、看门狗是什么?
    • 1.简介
    • 2. 主要功能
    • 3.独立看门狗如何工作
    • 4.寄存器写保护
    • 5.看门狗 看门时间
  • 二、使用步骤
    • 1.开启时钟
    • 2.初始化看门狗
      • 2.1 打开保护 IWDG_KR 写入 0x5555
      • 2.2 预分频系数 IWDG_RR 写入
      • 2.3 计数值 IWDG_RLR 写入 0X000- 0XFFF
    • 3. 将数据加载到计数器上,也就是喂一次狗IWDG_KR 写入 0xAAAA
    • 4.开启看门狗
    • 5.等待喂狗,超过时间就复位
  • 三、实际操作
    • 3.1.程序框架
      • 3.1.1 **这是一种测试的方法**
      • 3.3.2 实际应用的方法:定时器
    • 2.初始化参考
    • 3.测试结果
    • 3.1 按键的结果
    • 4.定时器喂狗
      • 4.1 定时器的结果
  • 总结


前言

提示:这里可以添加本文要记录的大概内容:

已经写了不少32程序了,程序都是直接运行,出了问题然后人工复位。有没有一种代替人工复位的方法呢?32里面是有的,而且很简单。


提示:以下是本篇文章正文内容,下面案例可供参考

一、看门狗是什么?

STM32的看门狗(Watchdog)是一种硬件定时器,用于监控系统的运行状态。它的主要功能是定期检查系统是否正常运行,并在系统出现问题时采取措施以恢复正常操作。STM32系列单片机通常配备了内置的看门狗定时器(独立看门狗,IWDG)和窗口看门狗定时器(WWDG),以提供更可靠的系统保护。

独立看门狗(IWDG)是STM32中常用的看门狗,它是一个独立的硬件模块,可以在系统内部独立运行。通过配置IWDG定时器的计数器和预分频器,可以设置看门狗的定时时间。当看门狗定时器计数器达到预设的值时,会产生看门狗超时事件,触发系统复位。

【STM32独立看门狗(IWDG) 】_第1张图片
【STM32独立看门狗(IWDG) 】_第2张图片

1.简介

【STM32独立看门狗(IWDG) 】_第3张图片

2. 主要功能

【STM32独立看门狗(IWDG) 】_第4张图片

3.独立看门狗如何工作

在这里插入图片描述

4.寄存器写保护

【STM32独立看门狗(IWDG) 】_第5张图片

5.看门狗 看门时间

【STM32独立看门狗(IWDG) 】_第6张图片
【STM32独立看门狗(IWDG) 】_第7张图片

二、使用步骤

1.开启时钟

【STM32独立看门狗(IWDG) 】_第8张图片
独立时钟LSI时钟不需要开启

2.初始化看门狗

2.1 打开保护 IWDG_KR 写入 0x5555

在这里插入图片描述

【STM32独立看门狗(IWDG) 】_第9张图片

IWDG_WriteAccessCmd(IWDG_WriteAccess_Enable);

2.2 预分频系数 IWDG_RR 写入

【STM32独立看门狗(IWDG) 】_第10张图片

IWDG_SetPrescaler(IWDG_Prescaler_8);

2.3 计数值 IWDG_RLR 写入 0X000- 0XFFF

【STM32独立看门狗(IWDG) 】_第11张图片

IWDG_SetReload(0x0FFF);   //1638.4 OVER

3. 将数据加载到计数器上,也就是喂一次狗IWDG_KR 写入 0xAAAA

【STM32独立看门狗(IWDG) 】_第12张图片

IWDG_ReloadCounter();

4.开启看门狗

【STM32独立看门狗(IWDG) 】_第13张图片

IWDG_Enable();

5.等待喂狗,超过时间就复位

【STM32独立看门狗(IWDG) 】_第14张图片

IWDG_ReloadCounter();

三、实际操作

3.1.程序框架

3.1.1 这是一种测试的方法

...

void main()
{
	//独立看门狗初始化
	// 亮灯        //这段程序复位之后只运行一遍
	while(1){
			//灭灯
			if(key0==0)
			{	
				//喂狗
			}
	}

}

3.3.2 实际应用的方法:定时器

根据自己的设定,确定看门狗溢出时间,再配置一个定时器,在溢出时间之前喂狗

...

void main()
{
	//独立看门狗初始化   200ms 溢出
	// 亮灯        //这段程序复位之后只运行一遍
	// 初始定时器   小于200ms溢出定时器中断
	while(1){
			//灭灯
	
	}

}


void timer()  //定时器溢出中断
{
//喂狗

}

2.初始化参考



void LED_Init()
{
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_GPIOD, ENABLE);
	GPIO_InitStruct.GPIO_Pin=  GPIO_Pin_8;
	GPIO_InitStruct.GPIO_Speed= GPIO_Speed_50MHz;
	GPIO_InitStruct.GPIO_Mode = GPIO_Mode_Out_PP;
		
	GPIO_Init(GPIOA, &GPIO_InitStruct);   //&x
	
	GPIO_InitStruct.GPIO_Pin=  GPIO_Pin_2;
	GPIO_InitStruct.GPIO_Speed= GPIO_Speed_50MHz;
	GPIO_InitStruct.GPIO_Mode = GPIO_Mode_Out_PP;
		
	GPIO_Init(GPIOD, &GPIO_InitStruct);   //&x
	
	
}

void KEY_Init()
{
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE);
	GPIO_InitStruct.GPIO_Pin=  GPIO_Pin_5;
	GPIO_InitStruct.GPIO_Speed= GPIO_Speed_50MHz;
	GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IPU;
		
	GPIO_Init(GPIOC, &GPIO_InitStruct);   //&x
	
	
	
}

void iwdg_init()
{
	IWDG_WriteAccessCmd(IWDG_WriteAccess_Enable);//使能
	IWDG_SetPrescaler(IWDG_Prescaler_8);//  
	IWDG_SetReload(0x0FFF);   //1638.4 ms OVER
	IWDG_ReloadCounter();
	IWDG_Enable();

}
void iwdg_init()
{
	IWDG_WriteAccessCmd(IWDG_WriteAccess_Enable);//使能
	IWDG_SetPrescaler(IWDG_Prescaler_8);//  
	IWDG_SetReload(0x0FFF);   //1638.4 OVER
	IWDG_ReloadCounter();
	IWDG_Enable();

}

void main()
{
   	
   	LED_Init();	
    iwdg_init();
	KEY_Init();
	GPIO_SetBits(GPIOD, GPIO_Pin_2);
	delay(1000);
	GPIO_ResetBits(GPIOD, GPIO_Pin_2);
    delay(1000);
	GPIO_SetBits(GPIOD, GPIO_Pin_2);
	while(1)
	{
		if(GPIO_ReadInputDataBit(GPIOC, GPIO_Pin_5)==0)
		{
		        IWDG_ReloadCounter();
		
		}


	}
}


3.测试结果

3.1 按键的结果

【STM32独立看门狗(IWDG) 】_第15张图片

4.定时器喂狗

定时器初始化 50ms溢出一次 20次则为1s =1000ms
独立看门狗溢出时间为 1638.4 ms
1s 1000ms 比1638.4 ms 小,1s喂狗一次,就不会复位
反正大于 就会复位

void timer6()
{

	/*
	
	1.开启APB1时钟   72MHz
	2.配置定时器6    TimeInit()  72预分配,0-65535     1000000us/50000us =CNT=20         定时时间/中断溢出时间=计数值
	3.中断配置       分组,优先级 。开启中断源
	4.中断服务函数   计数值, 1us  ,计数20次后让一个LED取反
	*/
	TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStruct;
	
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM6, ENABLE);
	
	//TIM_TimeBaseInitStruct.TIM_ClockDivision=
	TIM_TimeBaseInitStruct.TIM_CounterMode=TIM_CounterMode_Up;
	TIM_TimeBaseInitStruct.TIM_Period=50000-1;
	TIM_TimeBaseInitStruct.TIM_Prescaler= 72-1;
	//TIM_TimeBaseInitStruct.TIM_RepetitionCounter=
	
	TIM_TimeBaseInit(TIM6, &TIM_TimeBaseInitStruct);
	//开启中断:
	TIM_ITConfig( TIM6, TIM_IT_Update, ENABLE);
	
	TIM_Cmd( TIM6, ENABLE);      //使能
	
	NVIC_InitStruct.NVIC_IRQChannel=TIM6_IRQn;
	NVIC_InitStruct.NVIC_IRQChannelCmd= ENABLE;
	NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority=0;   //0-3
	NVIC_InitStruct.NVIC_IRQChannelSubPriority=  1;        //0-3
	NVIC_Init(&NVIC_InitStruct);
	
	
}


void TIM6_IRQHandler()
{

	if(TIM_GetITStatus( TIM6, TIM_IT_Update))
		
	{
	
	    TIM_ClearITPendingBit(TIM6, TIM_IT_Update);
	    
		num++;
		if(num==20)   // 1s  1000ms  比1638.4 ms 小,1s喂狗一次
		{
		   num=0;
		     IWDG_ReloadCounter();
			//led取反
			GPIOA->ODR^=0x0100;         //   1111 1110 1111 1111
			
			//   异或,相同为0,不同为1 
			//拿0 去异或,原来是0,还是0;原来是1,还是1。既可以保持不变
			//拿1 去异或,原来是0,变成1;原来是0,变成1。起到取反的作用
			second++;
			one_second_flag=1;
			if(second==60)
			{
				second=0;
				minute++;
				if(minute==60)
				{
					minute=0;
					hour++;
					if(hour==24)
					{
						hour=0;
					}
				}
			}
		
		}
	}
}

4.1 定时器的结果

1s定时喂狗竟然溢出,看来误差真的很大

50ms喂狗成功

总结

提示:这里对文章进行总结:
例如:以上就是今天要讲的内容,本文仅仅简单介绍了STM32独立看门狗的功能,后续将代码测试。

你可能感兴趣的:(STM32,学习教程,stm32,嵌入式硬件,单片机)