1 WDG
1.1 简介
WDG是看门狗定时器(Watchdog Timer)的缩写,它是一种用于计算机和嵌入式系统中的定时器,用来检测和恢复系统故障。
看门狗就像是一个忠诚的宠物狗,它时刻盯着你的程序,确保它们正常运行。如果程序因为设计上的小错误、硬件出了问题,或者受到了外界的干扰,导致程序卡住不动或者乱跑,看门狗就会立刻采取行动,让程序重新启动,防止它长时间处于无响应状态,这样就能保障系统的稳定和安全。
简单来说,看门狗就是一个特殊的计时器。它一旦开始计时,就需要程序在规定的时间内给它一个信号,告诉它一切都好。如果程序太忙了或者出了问题,没能在规定时间内给看门狗这个信号,看门狗就会自动启动一个重启程序,让系统回到正常状态。这个过程就像是给看门狗“喂骨头”,让它知道一切都在控制之中。如果没有按时“喂狗”,看门狗就会认为出了问题,然后采取行动。
1.2 主要功能与应用
-
1.系统监控:监控系统运行状态,确保系统不会因软件故障而停止响应。
-
2.防止死锁:如果程序进入无限循环,看门狗定时器可以检测到并重置系统。
-
3.安全机制:在某些关键系统中,看门狗定时器可以作为一个安全机制,确保系统在异常情况下能够安全地重启。
1.3 分类
WDG(Watchdog Timer)看门狗通常分为以下几种类型:
-
1.独立看门狗(Independent Watchdog, IWDG):独立于系统的其他部分运行,具有自己的时钟源,通常用于监视硬件错误。
-
2.窗口看门狗(Window Watchdog, WWDG):与系统时钟相关联,具有一个时间窗口,在该窗口内必须重置计数器,否则会产生系统复位。主要用于监视软件错误。
-
3.软件看门狗:由软件实现,依赖于操作系统的调度和运行环境,如果主程序卡死,软件看门狗可能无法触发重置。
-
4.硬件看门狗:具有独立的硬件结构,即使主程序卡死,也能独立于软件运行并触发系统重置。
-
5.周期性看门狗(AliveSupervision):监控周期性程序是否能正常执行,保证程序处于活跃状态。
-
6.截止期限看门狗(DeadlineSupervision):监督软件在两个状态之间的转换时间,确保在预定时间内完成特定任务。
-
7.逻辑看门狗(LogicalSupervision):监督软件执行顺序的正确性,确保程序按照预定逻辑运行。
这些看门狗类型可以根据不同的需求和应用场景进行选择和配置,以确保系统的稳定性和可靠性。
STM32中内置了两个看门狗:
-
独立看门狗(Independent Watchdog, IWDG)
-
窗口看门狗(Window Watchdog, WWDG)
2 IWDG
2.1 IWDG框图
-
1.输入时钟LSI(40KHz),进入预分频器进行分频(8位,最多256分频,由预分频寄存器IWDG_PR控制分频系数)。
-
2.时钟驱动递减计数器(每来一个时钟自减一个数,12位,最大值为4095),自减到0后产生IWDG复位信号。
-
3.提前在重装载寄存器(IWDG_RLR)写一个值,在键寄存器(IWDG_KR)中写一个特定数据控制电路,进行喂狗,这时重装值就会复制到当前的计数器中。
-
4.计数器回到重装值,重新自减运行。
预分频寄存器IWDG_PR、状态寄存器IWDG_SR(只读)、重装载寄存器IWDG_RLR、键寄存器IWDG_KR位于1.8V供电区;主要工作电路位于VDD供电区。
2.2 键寄存器IWDG_KR
键寄存器是IWDG系统中的核心控制组件,它的作用类似于一把精密的钥匙,用于精细调控看门狗的启动、寄存器的访问权限以及计数器的重载操作。
在嵌入式系统设计中,硬件电路可能会受到各种电磁干扰的影响,这些干扰有时会导致控制信号的误触发。为了避免这种情况,键寄存器采用了一种特殊的工作机制:通过在整个寄存器中写入一系列特定的值,而不是仅仅修改单个位,从而大大降低了因干扰而错误操作硬件电路的风险。
写入键寄存器的值 | 作用 |
---|---|
0xCCCC | 启动独立看门狗 |
0xAAAA | 将IWDG_RLR中的值重新加载到计数器(喂狗) |
0x5555 | 解除IWDG_RP与IWDG_RLR的写保护 |
0x5555之外的值 | 启动IWDG_RP与IWDG_RLR的写保护 |
2.3 IWDG超时时间
超时时间 == TIWDG = TLSI × PR预分频系数 × (RL + 1)==
TLSI = 1/FLSI ,FLSI = 40KHz
例如:当预分频系数为4时,最短超时时间 = 1/40000 * 4 * 1 = 0.0001s = 0.1ms;最长超时时间 = 1/40000 * 4 * 4096 = 0.4096s = 409.6ms
在多个可选择的预分频系数中,应该优先选择预分频系数小的,这样可以最大化利用计数器的值来减小时间误差。
原因:有的时候,带入上面公式计算,得到的RL值是一个小数,但RL只能给整数,所以四舍五入取整就会造成误差,这时,如果预分频系数小,时钟快,那么取整后造成的误差就比较小。
3 WWDG
3.1 WWDG框图
-
1.PCLK1时钟(默认36KHz)进入看门狗分频器WDGTB。
PCLK1时钟进入到WDGTB之前会先进行了4096分频。
-
2.分频之后的时钟驱动计数器(6位递减计数器)进行计数。
-
3.当T6位等于0时,产生复位信号。
T5~T0为有效计数值,T6用来当作溢出标志位,T6等于1时表示计数器没溢出,为0时表示计数器溢出。
-
把T6当作计数器的一部分,整个计数器的值减到0x40(二进制:10 0000)之后溢出;
-
把T6当作溢出标志位,低6位的计数值减到0后溢出。
-
WDGA:窗口看门狗的激活位(使能),为1启用窗口看门狗。
窗口看门狗的最晚界限由看门狗控制寄存器(WWDG_CR)控制;最早界限由看门狗配置寄存器(WWDG_CFR)控制。
3.2 WWDG工作特性
-
一. 递减计数器T[6:0]的监控机制:
- 当WWDG的递减计数器T[6:0]的值降至0x40以下时,系统将触发一个复位,以确保在预定的监控时间内系统能够正常响应。
-
二.窗口值W[6:0]的作用:
- 如果递减计数器T[6:0]在窗口值W[6:0]设定的范围之外被重新装载,WWDG将立即产生复位。这个特性确保了系统在预设的监控窗口内必须进行重置,以防止潜在的系统故障。
喂狗时把当前计数值与预设的窗口值进行比较,如果T[6:0] > W[6:0] 就产生复位信号。
-
三.早期唤醒中断(Early Wakeup Interrupt, EWI):
- 当递减计数器T[6:0]的值达到0x40时,WWDG可以发出早期唤醒中断信号。这个中断允许系统及时重装载计数器,从而避免因计数器归零而触发的WWDG复位。
1、早期唤醒中断中可以用来执行一些紧急操作,比如保持重要数据、关闭危险设备等。
2、当超时喂狗时,我们可以在中断里执行一些代码进行解决,或者任务不是很危险,超时了只想做一些提示,可以在早期唤醒中断中直接执行喂狗,阻止系统复位,提示信息。
-
四.维护WWDG的正常运行:
- 为了防止WWDG因计数器归零而引发复位,系统必须定期向WWDG控制寄存器(WWDG_CR)写入新的值,这一操作通常被称为“喂狗”。这是确保系统稳定运行的重要维护步骤。
总结:喂狗太晚,6位计数器减到0了复位;喂狗太早,计数器的值超过窗口值了,复位。
3.3 超时时间
-
超时时间:TWWDG = TPCLK1 × 4096 × WDGTB预分频系数 × (T[5:0] + 1)
要乘一个4096是因为PCLK1时钟进入到WDGTB之前先进行了4096分频。
-
窗口时间:TWIN = = TPCLK1 × 4096 × WDGTB预分频系数 × (T[5:0] - W[5:0])
-
TPCLK1 = 1 / FPCLK1
例如:超时时间为50ms,窗口时间为30ms,WDGTB预分频系数为8:
-
超时时间:TWWDG = 50 * 10-3 = 1 / 36000 * 4096 * 8 * (T[5:0] + 1) -> T[5:0] = 54
-
窗口时间:Twin = 30 * 10-3 = 1 / 36000 * 4096 * 8 * (T[5:0] - W[5:0]) -> W[5:0] = 21
4 软件设计
4.1 IWDG
4.1.1 配置流程:
-
1.开启LSI时钟
-
2.解除预分频器和重装寄存器写保护
-
3.写入预分频和重装值
-
4.启动看门狗
-
5.喂狗
在喂狗或使能的时候,会在键寄存器写入5555之外的值,就顺便给寄存器写保护了,不需要再手动执行写保护。
4.1.2 IDWG软件设计
// main.c
/***** 1000ms ******/
void IWDG_Init(void)
{IWDG_WriteAccessCmd(IWDG_WriteAccess_Enable);IWDG_SetPrescaler(IWDG_Prescaler_16);IWDG_SetReload(2499);IWDG_ReloadCounter();IWDG_Enable();
}int main(void)
{USART_Config();if(RCC_GetFlagStatus(RCC_FLAG_IWDGRST) == SET) {printf("\r\n -----------看门狗复位\r\n");Delay_ms(100);RCC_ClearFlag();}else{printf("\r\n -----------程序复位\r\n");}IWDG_Init();while(1){IWDG_ReloadCounter();printf("\r\n -----------IWDG_ReloadCounter\r\n");Delay_ms(900);}}
- 如果看门狗不会自动复位,拔掉DAP之后再按复位键。
4.2 WWDG
4.2.1 配置流程
-
1.开启窗口看门狗APB1的时钟
-
2.配置各寄存器(预分频、窗口值)
窗口看门狗没有写保护,所以可以在这一步直接写这些寄存器
-
3.写入控制寄存器CR
包含看门狗使能位、计数器溢出标志位和计数器有效位
- 4.在运行过程中,不断向计数器写入想要的重装值喂狗
4.2.2 WWDG软件设计
// main.c
void WWDG_Init()
{RCC_APB1PeriphClockCmd(RCC_APB1Periph_WWDG, ENABLE);WWDG_SetPrescaler(WWDG_Prescaler_8);/*** 设置窗口时间 ***/WWDG_SetWindowValue(0x40 | 21); // 低6位有效,第7位置1 30ms/*** 设置超时时间 ***/WWDG_Enable(0x40 | 54); // 0x40 WWDG_CR T6为1 50ms
}int main(void)
{USART_Config();if(RCC_GetFlagStatus(RCC_FLAG_WWDGRST) == SET) {printf("\r\n -----------窗口看门狗复位\r\n");Delay_ms(100);RCC_ClearFlag();}else{printf("\r\n -----------程序复位\r\n");}WWDG_Init();while(1){Delay_ms(40);WWDG_SetCounter(0x40 | 54);printf("\r\n -----------WWDG_SetCounter\r\n");}}
注意:
-
1.在WWDG_ENABLE后注意不要喂狗,会导致复位。
-
2.在开启窗口看门狗时,一定要给个重装值,并且T6位置1,以防止开的时候立刻就复位了。
即使窗口看门狗被禁止,递减计数器仍继续递减计数。
5 IWDG与WWDG对比
IWDG | WWDG | |
---|---|---|
复位 | 计数器减到0后 | 计数器T[5:0]减到0后、在窗口时间外重装计数器 |
中断 | 无 | 早期中断唤醒 |
时钟源 | LSI(40KHz) | PCLK1(默认36KHz) |
预分频系数 | 4、8、16、32、64、128、256 | 1、2、4、8 |
计数器 | 12位 | (有效计数)6位 |
超时时间 | 0.1ms~26214.4ms | 113us~58.25ms |
喂狗方式 | 写入键寄存器,重装固定值RLR | 直接写入计数器,写入多少重装值为多少 |
防误操作 | 键寄存器和写保护 | 无 |
应用场合 | 独立工作,对时间精度要求较低 | 要求看门狗在精确计时窗口起作用 |
无论是独立看门狗还是窗口看门狗,一旦启动就无法关闭。