看门狗简介:

独立看门狗能独立工作是指,它有独立的时钟源LSI(内部低速时钟40KHZ),即使主时钟出现问题,独立看门狗也能正常运行,时间精度低就是只有一个最晚界限,只要不超过这个界限就不会产生复位信号。
窗口看门狗与独立看门狗不同,它多了一个最早界限,必须在这个窗口内喂狗,而且它使用的是APB1的时钟(36MHZ)
独立看门狗框图:

这个框图类比于时基单元,只不过这个是递减计数器,每来一个时钟递减一次(由图可以看出这个是12位计数器所以最大值是2^12-1=4095)
键寄存器作用:

由图可以看出只有输入键寄存器特定值,它才能正常运行工作,当程序可能跑飞,可能受到电磁干扰时,程序可能会做出任何操作,而设置一位则很有可能会被程序误操作设置成0或1,但0xAAAA,0xCCC就很小可能了,这就降低了电路受干扰的能力。
独立看门狗的超时时间:

例如选择四分频:TLSI=1/40KHZ=0.025毫秒,最短时间TIWDG=0.02541=0.1毫秒,最长时间TIWDG=0,02444096=409.6毫秒,以此类推。
窗口看门狗框图:

注意这里T6用作溢出标志位,当T6由1变为0时(即由0x40变成0x3F时),就会触发复位信号,WDGA则是控制看门狗的开关(置1打开,置0关上),可以看到上面还有一个看门狗配置,当T6:0大于W6:0时(就是当重置CNT值时,会先将CNT值拿出跟W6:0比较,发现比它大时就是喂早了),即超出看门狗最早界限,就会置1触发复位信号。
窗口看门狗工作特性:

第三点是指在产生复位前一刻,会有中断信号提醒一下你要不要干点啥,所以可以在这个早期唤醒中断里干一些紧急任务:保存重要数据,关闭危险设备等。
窗口看门狗超时时间:

这里要x4096是因为PLCK1时钟源到看门狗预分频器会有一个4096的固定分频。
这里WDGTB从上到下分别对应(0,2,4,8)
独立看门狗和窗口看门狗的对比:

独立看门狗初始化模板:
int main(void)
{
OLED_Init ();
Key_Init ();
OLED_ShowString (1,1,"IWDG TEST:");
if(RCC_GetFlagStatus(RCC_FLAG_IWDGRST)==SET) //获取看门狗复位标志位
{
OLED_ShowString (2,1,"IWDG RST");
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_WriteAccessCmd(IWDG_WriteAccess_Enable ); //解除写使能保护
//配置1秒,1000=0.025*16*(2499+1)
IWDG_SetPrescaler(IWDG_Prescaler_16); //配置预分频
IWDG_SetReload(2499); //配置重装值
IWDG_ReloadCounter(); //喂一次狗
IWDG_Enable(); //使能看门狗
while(1)
{
Key_GetNum ();
IWDG_ReloadCounter(); //每搁一秒喂一次狗
OLED_ShowString (4,1,"FEED");
Delay_ms (500);
OLED_ShowString (4,1," ");
Delay_ms (100);
}
}
注意这里调用IWDG_Enable()和IWDG_ReloadCounter(),就相当于启动写保护。
想要查看是否由独立看门狗引起的复位,可以调用RCC_GetFlagStatus(RCC_FLAG_IWDGRST)
不过下一次还想查看是否由它引起的复位,要在每次查看后手动清除标志位,RCC_ClearFlag()

如上图,调用看门狗函数,LSI时钟就会自动打开,所以不用手动开启时钟。
窗口看门狗初始化配置:
int main(void)
{
OLED_Init ();
Key_Init ();
OLED_ShowString (1,1,"WWDG TEST:");
if(RCC_GetFlagStatus(RCC_FLAG_WWDGRST)==SET) //获取看门狗复位标志位
{
OLED_ShowString (2,1,"WWDG RST");
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);
}
RCC_APB1PeriphClockCmd (RCC_APB1Periph_WWDG,ENABLE);
//配置窗口时间为30ms,超过时间为50ms,50=1/36000*4096*8*55
WWDG_SetPrescaler(WWDG_Prescaler_8); //配置预分频值
WWDG_SetWindowValue(0x40 |21); //30ms
WWDG_Enable(0x40 |54); //50ms,0x40是将T6位置1
while(1)
{
Key_GetNum ();
OLED_ShowString (4,1,"FEED");
Delay_ms (20);
OLED_ShowString (4,1," ");
Delay_ms (20);
WWDG_SetCounter(0x40 |54); //喂狗
}
}
这里WWDG_Enable(0x40 |54)函数与WWDG_SetCounter(0x40 |54)参数相同是因为:

可以从图中看出,为防止计数器数值随意跳动而复位,这里使能必须也要喂一次狗,这也是为什么WWDG_SetCounter(0x40 |54)要放在后面,因为使能函数和喂狗函数太近就会因为两次喂狗时间过早而导致复位。

806

被折叠的 条评论
为什么被折叠?



