STM32入门教程(WDG看门狗篇)

重要的内容写在前面:

  1. 该系列是以up主江协科技的STM32视频教程为基础写下去的,大部分内容都参考了老师的课件,对于一些个人认为比较重要但是老师仅口述的部分,笔者都有用文字的方式记录并标出了重点。
  2. 文中的图片基本都来源于老师的课件以及开发板和芯片的手册,粘贴过来是为了方便阅读。
  3. 如果有条件的可以先学习一些相关课程再去看STM32的教程,学起来会更加轻松(不太建议零基础开始直接STM32,听起来可能会有点困难,可以先学51单片机),相关课程有数字电路(强烈推荐先学数电,不然可能会有很多地方理解起来很困难)、模拟电路、计算机组成原理(像寄存器、存储器、中断等在这门课里有很详细的介绍)、计算机网络等。
  4. 如有错漏欢迎指出。

视频链接:[14-1] WDG看门狗_哔哩哔哩_bilibili

一、概述

1、WDG(Watchdog)看门狗简介

(1)看门狗可以监控程序的运行状态,当程序因为设计漏洞、硬件故障、电磁干扰等原因,出现卡死或跑飞现象时,看门狗能及时复位程序,避免程序陷入长时间的罢工状态,保证系统的可靠性和安全性。

(2)看门狗本质上是一个定时器,当指定时间范围内,程序没有执行喂狗(重置计数器)操作时,看门狗硬件电路就自动产生复位信号

(3)STM32内置两个看门狗:

①独立看门狗(IWDG):独立工作,对时间精度要求较低。

②窗口看门狗(WWDG):要求看门狗在精确计时窗口起作用。

2、独立看门狗(IWDG)

(1)IWDG框图:

①在时钟产生电路有4个震荡源,其中一个是内部的40kHz低速RC振荡器(LSI RC 40kHz),它负责给独立看门狗提供时钟,这个时钟不需要用户手动开启。

②LSI时钟进入预分频器进行分频,分频系数由预分频寄存器进行配置。

LSI时钟经过预分频后驱动递减计数器进行自减计数(12位计数器最大值为4095),当计数器的值自减为0时会产生IWDG复位信号

如果不想让IWDG产生复位信号,那么在计数器的值自减为0之前及时给计数器重装载一个值(也就是“喂狗”)即可,这个值通过重装载寄存器写入递减计数器,什么时候给递减计数器重装载由键寄存器控制

(2)IWDG键寄存器:

①键寄存器本质上是控制寄存器,用于控制硬件电路的工作

②在可能存在干扰的情况下,一般通过在整个键寄存器写入特定值来代替控制寄存器写入一位的功能,以降低硬件电路受到干扰的概率

写入键寄存器的值

作用

0xCCCC

启用独立看门狗

0xAAAA

IWDG_RLR中的值重新加载到计数器(喂狗)

0x5555

解除IWDG_PR和IWDG_RLR的写保护

0x5555之外的其他值

启用IWDG_PR和IWDG_RLR的写保护

(3)IWDG超时时间:

3、窗口看门狗(WWDG)

(1)WWDG框图:

①窗口看门狗的时钟源是PCLK1(36MHz),时钟进入预分频器前会进行4096分频(图上未体现)。

WWDG_CR将递减计数器T0~T5是有效计数位,T6是溢出标志位,计数值自减过程中T6位为0代表溢出和控制寄存器(WDGA位置为1,窗口看门狗启动)合二为一需要同时满足T6位为0、WDGA位为1两个条件WWDG才会产生复位信号;窗口看门狗没有重装载寄存器,需要重装载时(喂狗)直接往递减计数器中写值即可

窗口看门狗的最早喂狗时间写在WWDG_CFR中,当喂狗时间过早时,窗口看门狗会产生复位信号。

当对递减计数器进行写操作(喂狗)时,比较器使能,这时比较器会比较递减计数器(喂狗前一刻)的值和配置寄存器的值,如果递减计数器的值较大,说明喂狗时间过早,比较器输出高电平,如果WDGA=1,就会产生复位信号

(2)WWDG工作特性:

①递减计数器T[6:0]的值小于0x40(也就是T6=0)时(没有及时喂狗),WWDG产生复位。

②递减计数器T[6:0]在窗口W[6:0]外被重新装载时(喂狗时间过早),WWDG产生复位。

③递减计数器T[6:0]等于0x40时可以产生早期唤醒中断(EWI,又称作“死前中断”),可以在中断函数中重装载计数器以避免WWDG复位(在喂狗的最晚时间使用中断喂狗)。

④定期写入WWDG_CR寄存器(喂狗)以避免WWDG复位。

(3)WWDG超时时间:

4、IWDG和WWDG对比

IWDG独立看门狗

WWDG窗口看门狗

复位

计数器减到0后

计数器T[5:0]减到0后、过早重装计数器

中断

早期唤醒中断

时钟源

LSI(40KHz)

PCLK1(36MHz)

预分频系数

4、8、32、64、128、256

1、2、4、8

计数器

12位

6位(有效计数)

超时时间

0.1ms~26214.4ms

113us~58.25ms

喂狗方式

写入键寄存器,重装固定值RLR

直接写入计数器,写多少重装多少

防误操作

键寄存器和写保护

用途

独立工作,对时间精度要求较低

要求看门狗在精确计时窗口起作用

二、看门狗使用示例

1、独立看门狗使用示例

(1)按照下图所示接好电路,并将OLED显示屏的项目文件夹复制一份作为模板使用。

(2)在stm32f10x_iwdg.h文件中有IWDG模块相关的函数。

[1]IWDG_WriteAccessCmd函数:写使能控制(键寄存器写入0x5555,解除或开启IWDG_PR和IWDG_RLR的写保护)。

[2]IWDG_SetPrescaler函数:设置预分频器的分频系数(写IWDG_PR)。

[3]IWDG_SetReload函数:设置重装值(写IWDG_RLR)。

[4]IWDG_ReloadCounter函数:重装载递减计数器(键寄存器写入0xAAAA,即喂狗)。

[5]IWDG_Enable函数:启动独立看门狗(键寄存器写入0xCCCC)。

[6]IWDG_GetFlagStatus函数:获取状态标志位。

(3)在main.c文件中粘贴以下代码,然后编译,将程序下载到开发板中进行调试。

①正常情况下,将程序下载到开发板后OLED屏会显示一次“RST”,然后会不断闪烁显示“FFED”,如果按下复位按键,OLED屏会再显示一次“RST”,然后接着不断闪烁显示“FFED”。

如果按住按键不放,程序会卡死在Key_GetNum函数的死循环中程序不能及时喂狗,于是看门狗会产生复位信号并置IWDGRST为1,程序从头开始运行,由于是IWDG导致的复位,OLED屏不显示“RST”而显示“IWDGRST”,然后接着不断闪烁显示“FFED”

#include "stm32f10x.h"                  // Device headerCmd
#include "OLED.h"
#include "Delay.h"
#include "Key.h"

int main()
{
	OLED_Init();
Key_Init();
	
	OLED_ShowString(1,1,"IWDG TEXT");
	
	if(RCC_GetFlagStatus(RCC_FLAG_IWDGRST) == SET)  //判断IWDG是否产生复位
	{
		OLED_ShowString(2,1,"IWDGRST");  //看门狗导致的复位
		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);
	}
	
	//解除IWDG的写保护
	IWDG_WriteAccessCmd(IWDG_WriteAccess_Enable);
	
	//配置分频系数(40MHz经过16分频为2.5MHz)
	IWDG_SetPrescaler(IWDG_Prescaler_16);
	
	//配置重装值
	IWDG_SetReload(2500 - 1);  //超时时间为1000ms
	
	//先喂一次狗(键寄存器写入0x5555以外的值,同时开启写保护)
	IWDG_ReloadCounter();
	
	//启动看门狗
	IWDG_Enable();
	
	while(1)
	{
		Key_GetNum();
		//按下按键不放,程序会卡死在Key_GetNum函数的死循环中
		
		IWDG_ReloadCounter();   //喂狗
		
		OLED_ShowString(4,1,"FFED");
		Delay_ms(400);
		OLED_ShowString(4,1,"FFED");
		Delay_ms(200);
	}
}

2、窗口看门狗使用示例

(1)按照下图所示接好电路,并将上例的项目文件夹复制一份作为模板使用。

(2)在stm32f10x_wwdg.h文件中有WWDG模块相关的函数。

[1]WWDG_DeInit函数:恢复缺省配置。

[2]WWDG_SetPrescaler函数:配置预分频器的分频系数。

[3]WWDG_SetWindowValue函数:配置窗口值,也就是设置最早喂狗时间(写WWDG_CFR)。

[4]WWDG_EnableIT函数:使能早期唤醒中断。

[5]WWDG_SetCounter函数:重装载递减计数器(写WWDG_CR,即喂狗)。

[6]WWDG_Enable函数:启动窗口看门狗(并给递减计数器一个初值)。

[7]WWDG_GetFlagStatus函数:获取标志位。

[8]WWDG_ClearFlag函数:清除标志位。

(3)在main.c文件中粘贴以下代码,然后编译,将程序下载到开发板中进行调试。

①正常情况下,将程序下载到开发板后OLED屏会显示一次“RST”,然后会不断闪烁显示“FFED”,如果按下复位按键,OLED屏会再显示一次“RST”,然后接着不断闪烁显示“FFED”。

如果按住按键不放,程序会卡死在Key_GetNum函数的死循环中程序不能及时喂狗,于是看门狗会产生复位信号并置WWDGRST为1,程序从头开始运行,由于是WWDG导致的复位,OLED屏不显示“RST”而显示“WWDGRST”,然后接着不断闪烁显示“FFED”

③修改while循环中的延时函数参数,使喂狗时间早于30ms,那么喂狗后一样会产生复位信号并置WWDGRST为1,程序从头开始运行,由于是WWDG导致的复位,OLED屏不显示“RST”而显示“WWDGRST”,然后接着不断闪烁显示“FFED”

#include "stm32f10x.h"                  // Device headerCmd
#include "OLED.h"
#include "Delay.h"
#include "Key.h"

int main()
{
	OLED_Init();
	Key_Init();
	
	OLED_ShowString(1,1,"WWDG TEXT");
	
	if(RCC_GetFlagStatus(RCC_FLAG_WWDGRST) == SET)  //判断WWDG是否产生复位
	{
		OLED_ShowString(2,1,"WWDGRST");  //看门狗导致的复位
		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);
	}
	
	//开启WWDG时钟
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_WWDG, ENABLE);
	
	//配置分频系数(36MHz经过8×4096分频为1098.63Hz)
	WWDG_SetPrescaler(WWDG_Prescaler_8);
	
	//配置窗口值(这个值多多少少会有误差,但不大)
	WWDG_SetWindowValue(21|0x40);  //最早喂狗时间为30ms,过早喂狗会复位(0x40的作用是置W6为1,21由公式计算而得)
	
	//启动看门狗(这个值多多少少会有误差,但不大)
	WWDG_Enable(54|0x40);          //最晚喂狗时间为50ms,过晚喂狗会复位(0x40的作用是置T6为1,54由公式计算而得)
	
	while(1)
	{
		Key_GetNum();
		//按下按键不放,程序会卡死在Key_GetNum函数的死循环中
		
		OLED_ShowString(4,1,"FFED");
		Delay_ms(20);
		OLED_ShowString(4,1,"    ");
		Delay_ms(20);
		
		WWDG_SetCounter(54|0x40);   //喂狗(0x40的作用是置T6为1)
	}
}
  • 21
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
优秀的处理器配合好的开发工具和工具链成就了单片机的辉煌,这是单片机开发者辛勤劳动的结果。也正因为此,ARM的工具链工程师和CPU工程师强强联手,日日夜夜不停耕耘为ARM7TDMI设计出了精练、优化和到位的内部结构,终于成就了ARM7TDMI的风光无限的辉煌。新的ARMCortex-MB处理器在破茧而出之后,就处处闪耀着ARM体系结构激动人心的新突破。它是基于最新最好的32为ARMv7架构,支持高度成功的Thumb-2指令集,并带来了很多前卫崭新的特性。在它优秀,强大的同时,编程模型也更清爽,因而无论你是新手还是骨灰级玩家都会对这样秀外慧中的小尤物爱不释手。根据ARM的统计,2010年全部Cortex-MMCU出货量为1.44亿片,2008年~2011年第一季度,STM32累计出货量占Cortex-MMCU出货量的45%。也就是说,两个Cortex-M微控制器中有一个就来自ST。”很多市场分析机构也ARM的强劲增长表示认可。2007年在3264bitMCU及MPU架构中,ARM所占市场份额为13.6%,而2010年已经占了23.5%击败了PowerArchitecture,成为市场占有率最多的架构。Cortex-n3内核是ARM公司整个Cortex内核系列中的微控制器系列(M)内核还是其他两个系列分别是应用处理器系列(A)与实时控制处理系列(R),这三个系列又分别简称为A、R、M系列。当然,这三个系列的内核分别有各自不同的应用场合。Cortex-MB内核是为满足存储器和处理器的尺寸对产品成本影响很大的广泛市场和应用领域的低成本需求而专门开发设计的。主要是应用于低成本、小管脚数和低功耗的场合,并且具有极高的运算能力和极强的中断响应能力。Cortex-M3处理器采用纯Thumb2指令的执行方式,这使得这个具有32位高性能的ARM内核能够实现8位和16位的代码存储密度。核心门数只有3K,在包含了必要的外设之后的门数也只有60K,使得封装更为小型,成本更加低廉。Cortex-n3采用了ARMV7哈佛架构,具有带分支预测的3级流水线,中断延退最大只有12个时钟周期,在末尾连锁的时候只需要6个时钟周期。同时具有1.25DMIPS/MHZ的性能和0.19MW/MHZ的功耗。     社会对基于ARM的嵌入式系统开发人员的高需求及给予的高回报,催生了很多的培训机构,这也说明嵌入式系统的门槛较高,其主要原因有以下几点。ARM本身复杂的体系结构和编程模型,使得我们必须了解详细的汇编指令,熟悉ARM与Thumb状态的合理切换,才能理解Bootloader并对操作系统进行移植,而理解Bootloader本身就比较困难,因而对于初学者来说Bootloader的编写与操作系统的移植成了入门的第一道难以逾越的门槛2、ARM芯片,开发板及仿真器的高成本,这样就直接影响了嵌入式开发的普及,使得这方面人才增长缓慢;3、高校及社会上高水平嵌入式开发人员的短缺,现实问题使得我们的大学生和公司职工在入门的道路上困难重重,很多人也因此放弃;培训机构的高费用,虽然有高水平的老师指导,但是高费用就是一道关口,进去的人也只是在短短的几天时间里匆匆了解了一下开发过程,消除了一些畏惧心理而己,修行还是得依靠自己;5、好的开发环境需要资金的支持,也直接影响了入门的进度。基于Cortex-m3内核的ARM处理器的出现,在优秀的Kei开发工具的支持下,可以自动生成启动代码,省去了复杂的Bootloader的编写。Thumb-2指令集的使用,使得开发人员不用再考虑ARM状态与Thumb状态的切换,节省了执行时间和指令空间,大大减轻了软件开发的管理工作。处理器与内存尺寸的减少,大大降低了成本,使得芯片及开发板的价格得以在很大程度降低。Cortex-M3内核通过把中断控制器、MPU及各种调试组件等基础设施的地址固定很大程度上方便了程序的移植。源代码是公开的库函数,使得我们可以摒弃晦涩难懂的汇编语言,在不需要了解底层寄存器的操作细节的情况下,用C语言就可以完成我们需要的功能。所有这些特点使得我们学习ARM处理器的门槛得以降低。同时建议大家尽量去用固件库。而不是避开固件库自己写代码。因为在实际的项目中,代码成百上千个,不可能都自己来写,调用固件库中的函数来完成,才是可行的方案。当然我们在深入的情况下,透彻理解寄存器的操作是必要的,也是值得的,高效编程也必须在这方面努力。
STM32F103C8T6是一款基于ARM Cortex-M3内核的微控制器,它具有看门狗(Watchdog)功能。看门狗是一种硬件定时器,用于监控系统的运行状态,当系统出现异常情况时,看门狗会自动重启系统,保证系统的稳定性和可靠性。 在STM32F103C8T6中,看门狗的配置需要以下步骤: 1. 使能看门狗时钟:通过RCC寄存器使能看门狗时钟。 2. 配置看门狗预分频器和重载值:看门狗预分频器和重载值用于确定看门狗计数器的计数周期,通过IWDG_PR和IWDG_RLR寄存器进行配置。 3. 启动看门狗:配置好看门狗后,通过IWDG_KR寄存器启动看门狗。 4. 定时喂狗:在系统运行正常时,需要定时喂狗,以避免看门狗超时,导致系统重启。通过IWDG_KR寄存器定时喂狗。 以下是一个简单的示例代码,演示如何配置和使用看门狗: ``` #include "stm32f10x.h" void WDG_Init(void) { RCC_APB1PeriphResetCmd(RCC_APB1Periph_IWDG, ENABLE); // 使能看门狗时钟 IWDG_WriteAccessCmd(IWDG_WriteAccess_Enable); // 允许写入IWDG_PR和IWDG_RLR寄存器 IWDG_SetPrescaler(IWDG_Prescaler_256); // 配置预分频器,分频系数为256 IWDG_SetReload(0xFFF); // 配置重载值,最大值为0xFFF IWDG_ReloadCounter(); // 重载看门狗计数器 IWDG_Enable(); // 启动看门狗 } int main(void) { WDG_Init(); // 初始化看门狗 while(1) { // 定时喂狗 IWDG_ReloadCounter(); // 喂狗 } } ``` 在上面的例子中,预分频器的分频系数为256,重载值为0xFFF,这意味着看门狗计数器的计数周期为256*4096/40M=26.2144ms,如果系统在这个周期内没有重载看门狗计数器,那么看门狗就会超时,导致系统重启。通过定时喂狗,可以避免这种情况的发生。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

Zevalin爱灰灰

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

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

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

打赏作者

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

抵扣说明:

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

余额充值