目录
看门狗
早期的MCU没有看门狗,就容易引起有些产品死机了不能重启工作。为了避免这个问题,后期的MCU在内部继承了看门狗的功能。看门狗功能由VDD电压域供电,在停止模式和待机模式下仍能工作。
现如今有两种看门狗,应用不同领域。两种看门狗:独立看门狗与窗口看门狗。
RLR 是重装载寄存器,用来设置独立看门狗的计数器的值。
TR 是窗口看门狗的计数器的值,由用户独立设置, WR 是窗口看门狗的上窗口值,由用户独立设置。
独立看门狗中,待计数器递减到0前不喂狗(刷新数值),就会产生复位。
窗口看门狗中,在TR与WR期间喂狗(刷新数值)会产生复位,在WR递减到0x40前不喂狗(刷新数值),就会产生复位。所以窗口看门狗喂狗时间不能过早也不能过晚。
独立看门狗
功能框图
IWDG的时钟由独立的RC振荡器LSI提供,即便主时钟发生故障时仍然保持工作状态。LSI频率一般在30~60kHz之间,根据温度和工作场合会有一定的漂移,一般取40kHz,所以IWDG的定时时间不一定非常准确,只适用于对时间精度要求比较低的场合。
递减计数器的时钟由LSI经过8-bit prescaler(8位预分频器)而来,可以通过IWDG_PR预分频器寄存器设置分频因子。
递减计数器是12位,最大值为0xfff,当减到0时产生一个复位信号:IWDG_RESET。
重装载寄存器是12位,里面存放着要刷新到计数器的值,这个值决定着IWDG的溢出时间。
IWDG_KR键值寄存器为只写寄存器,写入键值会起键值作用。
键值 键值作用 0xAAAA 把IWDG_PLR的值重装载到递减计数器 0x5555 IWDG_PR和IWDG_PLR这两个寄存器可写 0xCCCC 启动IWDG IWDG_PR 和 IWDG_RLR 寄存器具有写保护功能。要修改这两个寄存器的值,必须先向 IWDG_KR 寄存器中写入0x5555。 将其他值写入 IWDG_KR 寄存器将会打乱操作顺序,寄存器将重新被保护,必须先向 IWDG_KR 寄存器中写入0x5555后才能写0xAAAA。
IWDG 在一旦启用,就不能再被关闭!
IWDG配置
溢出时间:625/(40k/64) =1s。
IWDG_HandleTypeDef hiwdg;
void MX_IWDG_Init(void)
{
hiwdg.Instance = IWDG;
hiwdg.Init.Prescaler = IWDG_PRESCALER_64;
hiwdg.Init.Reload = 625;
if (HAL_IWDG_Init(&hiwdg) != HAL_OK)
{
Error_Handler();
}
}
测试环节
0.5s喂狗一次,时间不宜太晚。
/**
* @brief 守护任务循环入口
* @note None
* @param argument : NULL
* @retval None
*/
void StartGuardTask(void *argument)
{
for(;;)
{
HAL_IWDG_Refresh(&hiwdg);
osDelay(500);
}
}
窗口看门狗
之所以称为窗口,是因为其喂狗时间是一个有上下限的范围内,可以通过设定时间寄存器,设定其上限时间和下限时间:喂狗时间不能过早也不能过晚。
功能框图
WWDG时钟来自PCLK1,PCLK1最大是36M,由RCC时钟控制器开启。
递减计数器时钟由CK计时器时钟(PCLK1/4096,手册规定)经过预分频器分频得到(分频系数由WWDG_CFG:WDGTB0/1配置),所以计数器的时钟CNT_CK = PCLK1/4096/(2^WDGTB)。递减一个数为1/CNT_CK。
窗口看门狗的上限窗口就是配置寄存器WWDG_CFG:W[6:0],下限窗口是固定的0x40。当窗口看门狗的计数器在上限窗口之外,或是在下限窗口之外都会产生复位。
WWDG_CR控制寄存器
WWDG_CR:WDGA为第8位,是看门狗的激活位。该位由软件置1,以启动看门狗。注意该位一旦设置,就只能在硬件复位后才拿清零了。
WWDG_CR:T[6:0]:看门狗的计数器值。
WWDG_CFG配置寄存器
配置寄存器WWDG_CFG:EWI为提前唤醒中断位,也就是在快要产生复位的前一段时间(T[6:0]=0X40) 来提醒我们,需要进行喂狗了,否则将复位。因此,我们一般用该位来设置中断,当窗口看门狗的计数器值减到 0X40 的时候,如果该位设置,并开启了中断,则会产生中断,我们可以在中断里面向 WWDG_CR 重新写入计数器的值,来达到喂狗的目的。注意这里在进入中断后, 必须在不大于 1 个窗口看门狗计数周期的时间(在 PCLK1 频率为 36M 且 WDGTB 为 0 的条件下,该时间为 113us)内重新写 WWDG_CR,否则,看门狗将产生复位。
配置寄存器WWDG_CFG:WDGTB[1:0]为计数器设定时钟分频系数,确定这个计数器可以定时的时间范围,从而确定窗口的时间范围。
上限窗口由 WWDG_CFG:W[6:0] 设定,最大为0x7F,即127。最小为0x40,即64。所以取值范围为0x40~0x7F,即64~127。
WWDG_SR状态寄存器
只用到一个位,WWDG_SR:EWIF。用来记录当前是否有提前唤醒的标志。
当计数器值达到 40h 时,此位由硬件置 1。它必须通过软件写 0 来清除。对此位写 1 无效。 即使中断未被使能, 在计数器的值达到 0X40 的时候, 此位也会被置 1。
WWDG配置
WWDG_HandleTypeDef hwwdg;
void MX_WWDG_Init(void)
{
hwwdg.Instance = WWDG;
hwwdg.Init.Prescaler = WWDG_PRESCALER_8;
hwwdg.Init.Window = 80;
hwwdg.Init.Counter = 127;
hwwdg.Init.EWIMode = WWDG_EWI_ENABLE;
if (HAL_WWDG_Init(&hwwdg) != HAL_OK)
{
Error_Handler();
}
}
void HAL_WWDG_MspInit(WWDG_HandleTypeDef *wwdgHandle)
{
if (wwdgHandle->Instance == WWDG)
{
__HAL_RCC_WWDG_CLK_ENABLE();
HAL_NVIC_SetPriority(WWDG_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(WWDG_IRQn);
}
}
测试环节
// WWDG 中断服务程序,如果发生了此中断,表示程序已经出现了故障,
// 这是一个死前中断。在此中断服务程序中应该干最重要的事,
// 比如保存重要的数据等
void WWDG_IRQHandler(void)
{
//WWDG 中断服务处理函数,用户代码在提前唤醒中断回调函数中添加
HAL_WWDG_IRQHandler(&WWDG_Handle);
}
void HAL_WWDG_EarlyWakeupCallback(WWDG_HandleTypeDef* hwwdg)
{
//比如黄灯亮
//真正使用的时候,这里应该是做最重要的事情
}
void test(void)
{
uint8_t wwdg_tr, wwdg_wr;
初始化
//检查窗口看门狗复位标志位
if (__HAL_RCC_GET_FLAG(RCC_FLAG_WWDGRST) != RESET)
{
// 窗口看门狗复位了,可以做一些处理来判断
// 比如红灯亮
//清除复位标志位
__HAL_RCC_CLEAR_RESET_FLAGS();
}
else
{
// 正常启动
// 比如蓝灯亮
}
// 窗口值我们在初始化的时候设置成0X5F,这个值不会改变
wwdg_wr = WWDG->CFR & 0X7F;
while (1)
{
//-----------------------------------------------------
// 这部分应该写需要被WWDG监控的程序,这段程序运行的时间决定了窗口值应该设置成多大。
//-----------------------------------------------------
// 计时器值,初始化成最大0X7F,当开启WWDG时候,这个值会不断减小
// 当计数器的值大于窗口值时喂狗的话,会复位,当计数器减少到0X40
// 还没有喂狗的话就非常非常危险了,计数器再减一次到了0X3F时就复位
// 所以要当计数器的值在窗口值和0X40之间的时候喂狗,其中0X40是固定的。
wwdg_tr = WWDG->CR & 0X7F;
if (wwdg_tr == wwdg_wr)
{
// 喂狗,刷新递减计数器的值,设置成最大WDG_CNT=0X7F
HAL_WWDG_Refresh(&hwwdg);
}
}
}
IWDG和WWDG的区别
使用条件对比
特点对比
相同点
不同点
两者区别
独立看门狗没有中断,窗口看门狗有中断。
独立看门狗有硬件软件之分,窗口看门狗只能软件控制。
独立看门狗只有下限,窗口看门狗有下限和上限。
独立看门狗是12位递减的,窗口看门狗是7位递减的。
独立看门狗是用的内部大约40kHz的RC振荡器,窗口看门狗是用的系统时钟APB1。
独立看门狗没有中断功能,只要在计数器减到0(下限)之前,重新装载计数器的值,就不会产生复位。
要注意看门狗和外接复位IC同时存在的情况,外部电路可能会阻止看门狗复位。
窗口看门狗有中断,这个中断的作用是在计数器达到下限0x40的时候,产生中断,让你喂狗。如果不喂狗,计数器的值变为0x3f时,将会产生系统复位。即便是喂狗,也该在中断里快速喂狗,要不时间长了计数器减1也会变成0x3f产生复位。
窗口看门狗还有一个上限值,只有计数器值在上限值和下限值之间才能装载计数器,否则就会产生系统复位。当上限值小于下限值,没有意义。