stm32独立看门狗和窗口看门狗的区别是啥
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了stm32独立看门狗和窗口看门狗的区别是啥相关的知识,希望对你有一定的参考价值。
stm32独立看门狗和窗口看门狗的区别为:时钟源不同、中断不同、使用条件不同。
一、时钟源不同
1、stm32独立看门狗:stm32独立看门狗使用的是内部专门的 40Khz低速时钟,不需要使能时钟操作。
2、窗口看门狗:窗口看门狗使用的是 PCLK1的时钟,使用前需要先使能时钟。
二、中断不同
1、stm32独立看门狗:stm32独立看门狗没有中断,超时直接复位。
2、窗口看门狗:窗口看门狗可以在中断中做复位前的函数操作。
三、使用条件不同
1、stm32独立看门狗:stm32独立看门狗一般用于避免程序跑飞或者死循环。
2、窗口看门狗:窗口看门狗避免程序不安预定逻辑执行,比如先于理想环境完成,或者后于极限时间超时。
参考技术A 1)独立看门狗没有中断,窗口看门狗有中断2)独立看门狗有硬件软件之分,窗口看门狗只能软件控制
3)独立看门狗只有下限,窗口看门狗又下限和上限
4)独立看门狗是12位递减的。窗口看门狗是7位递减的
5)独立看门狗是用的内部的大约40KHZ RC振荡器,窗口看门狗是用的系统时钟APB1ENR
独立看门狗没有中断功能,只要在计数器减到0(下限)之前,重新装载计数器的值,就不会产生复位。
窗口看门狗有中断,这个中断的作用是在计数器达到下限0x40的时候,产生中断,让你喂狗,如果你不喂狗,计数器的值变为0x3f的时候,将会产生系统复位,即使是喂狗,也应该在中断里快速喂狗,要不时间长了计数器减一也会变成0x3f产生复位。还有一个上限值,这个值如果大于计数器的初始值,那么就没有任何作用了,这个值小于计数器的初始值得时候,当计数器的值大于上限值时你对计数器进行装载,将会产生复位,只有在计数器减到小于上限值时,你才能重新装载计数器,意思就是说只有计数器的值在上限值和下限值之间你才能装载计数器,否则就会产生系统复位,当上限值小于下限值,也没有意义。本回答被提问者和网友采纳 参考技术B 窗口看门狗只是运行时的一个监控看门狗……但如果程序出错跑偏,但是还能回来喂狗是没法起作用的。
独立狗是利用外部或内部低速PLL32k频率运行的独立于程序的……如果死机等……是可以重新启动芯片的。
STM32的看门狗了解及代码演示
一、介绍:
STM32看门狗分为独立看门狗和窗口看门狗两种,其两者使用调条件如下所示,
IWDG和WWDG两者特点如下图所示:
独立看门狗的手册资料:
串口看门狗的手册资料:
应当注意:在窗口看门狗中,当递减计数器在窗口外被重新装载,(若看门狗被启动)则产生复位
由于窗口看门狗使用的APB1的PCLK1,时钟最高36MHZ,和RCC_APB2Periph_GPIOx不同,APB1最大就是36MHZ,APB2最大就是72MHZ。
所以串口看门狗需要配置APB1时钟使能,如下语句。
可以从图1-3 窗口看门狗编程说明红看到TWWDG=TPCLK1 x 4096 x 2^WDGTB x (T[5:0]+1) ; (ms)
WDGTB[1:0]: 时基 (Timer base),也就是设置WDGTB 的值是1/2/4还是8,这在配置寄存器(WWDG_CFR)寄存器的位8:7 中设置,
其预分频器的时基可以设置如下:
00: CK计时器时钟(PCLK1除以4096)除以1
01: CK计时器时钟(PCLK1除以4096)除以2
10: CK计时器时钟(PCLK1除以4096)除以4
11: CK计时器时钟(PCLK1除以4096)除以8
也可以直接用这个函数
1 WWDG_SetPrescaler(WWDG_Prescaler_8); //8预分频,则WWDG时钟频率=(PCK1(36M)/4096)/8=1099Hz(910us)
也可以直接用这个函数
其次是设置窗口值,用来与递减计数器进行比较用的窗口值。通过如下函数即可
1 WWDG_SetWindowValue(80);//设置窗口值为80则WWDG的计数值必须在64~80之间才能喂狗(64是0x40,当再次减1就会T6清零,从而导致复位了,即刷新窗口设置成了80-64,127-80也是不能更新值得否则也会复位)
应当注意:在窗口看门狗中,当递减计数器在窗口外被重新装载,(若看门狗被启动)则产生复位,也即是说在90-64外面使用这个重载函数,会有问题发生
最后我们设置 (T[5:0]+1)的值,这里我们设置最大127,代码如下,以后每次喂狗也可以用这个函数进行重载计数值(喂狗)。
1 WWDG_Enable(127)
因为这是会导致产生复位,所以重载的窗口一定要设置好。
总结就是我们使用串口看门狗应该先配置寄存器(WWDG_CFR),即配置窗口值是多少到x40(我们设置的80-0x40),这个配置会告诉单片机什么时候来与递减计数器进行值比较,如果值小于0x40就产生复位。
当然,如果你在减减计数值还在0x7E-0x50(127-80)之间就重载计数值(喂狗)同样会导致芯片复位。所以窗口的概念一定要理解好,在窗内才可以重载计数值(喂狗),这样才不会莫名被复位。
二、代码实现
最终的初始化窗口看门狗的配置函数(WWDG)如下:
/************************************************************* Function : WWDGReste_Init Description: 窗口看门狗定时器 Input : none return : none *************************************************************/ void WWDGReste_Init(void) { RCC_APB1PeriphClockCmd(RCC_APB1Periph_WWDG, ENABLE);//WWDG连接在PCLK1(36M)的时钟线上 WWDG_SetPrescaler(WWDG_Prescaler_8); //8预分频,则WWDG时钟频率=(PCK1(36M)/4096)/8=1099Hz(910us) WWDG_SetWindowValue(80);//设置窗口值为80则WWDG的计数值必须在64~80之间才能喂狗(64是0x40,当再次减1就会T6清零,从而导致复位了) //设置WWDG计数值为127,超时时间=910us*64=58.25ms,所以 WWDG_Enable(127);//(0x7F为设置的最小值,0x40为最大的复位值,取值应该在0x40~0x7F之间)刷新窗口为:910us*(127-80)=42.77ms < 刷新窗口 < 910us*64=58.25ms }
主函数如下:
void mian(void) { //初始化 while(1) { delay_ms(400) WWDG_Enable(127); //无需判断直接等待窗口看门狗中断触发 } }
或者这样的留参带使能中断形式:
#include "wdg.h" #include "stm32f10x_wwdg.h" static u8 WWDG_CNT=0x7f; /*保存WWDG计数器的设置值,默认为最大127. */ //======================================================================================== /** * 初始化窗口看门狗 * tr :T[6:0],计数器值 * wr :W[6:0],窗口值 * fprer:分频系数(WDGTB),仅最低2位有效 * Fwwdg=PCLK1/(4096*2^fprer). // 计数器值为7f,窗口寄存器为5f,分频数为8 WWDG_Init(0X7F,0X5F,WWDG_Prescaler_8); */ void WWDG_Init(u8 tr,u8 wr,u32 fprer) { RCC_APB1PeriphClockCmd(RCC_APB1Periph_WWDG, ENABLE); /*WWDG时钟使能*/ WWDG_SetPrescaler(fprer); /*设置IWDG预分频值*/ WWDG_SetWindowValue(wr); /*设置窗口值*/ WWDG_CNT=tr&WWDG_CNT; /* 初始化WWDG_CNT. */ WWDG_Enable(WWDG_CNT); /*使能看门狗 , 设置 counter . */ WWDG_ClearFlag(); /*清除提前唤醒中断标志位*/ WWDG_NVIC_Init();/* 初始化窗口看门狗 NVIC */ WWDG_EnableIT(); /* 开启窗口看门狗中断 */ } /** * 窗口看门狗中断服务程序 */ void WWDG_NVIC_Init(void) { NVIC_InitTypeDef NVIC_InitStructure; NVIC_InitStructure.NVIC_IRQChannel = WWDG_IRQn; /*WWDG中断*/ /* 抢占2,子优先级3 */ NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2; NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3; NVIC_Init(&NVIC_InitStructure);/* NVIC初始化*/ } /** * 重设置WWDG计数器的值,喂狗 */ void WWDG_Set_Counter(u8 cnt) { WWDG_Enable(cnt); /*使能看门狗 , 设置 counter . */ } /** * 看门狗中断服务程序 */ void WWDG_IRQHandler(void) { WWDG_Set_Counter(WWDG_CNT); WWDG_ClearFlag(); /*清除提前唤醒中断标志位*/ LED1 = ~LED1; /*LED状态翻转 */ } void mian(void) { //初始化 while(1) { } }
附录:
独立看门狗(IWDG)的代码:
/** * 初始化独立看门狗 * prer:分频数:0~7(只有低 3 位有效!) * 分频因子=4*2^prer.但最大值只能是 256! * rlr:重装载寄存器值:低 11 位有效. * 时间计算(大概):Tout=((4*2^prer)*rlr)/40 (ms). *IWDG_Init(4,625);//初始化独立看门狗,分频数为64,重装载值为625,溢出时间计算为:64*625/40=1000ms=1s */ void IWDG_Init(u8 prer,u16 rlr) { IWDG_WriteAccessCmd(IWDG_WriteAccess_Enable); /* 使能对寄存器IWDG_PR和IWDG_RLR的写操作*/ IWDG_SetPrescaler(prer); /*设置IWDG预分频值:设置IWDG预分频值*/ IWDG_SetReload(rlr); /*设置IWDG重装载值*/ IWDG_ReloadCounter(); /*按照IWDG重装载寄存器的值重装载IWDG计数器*/ IWDG_Enable(); /*使能IWDG*/ } /** * 喂独立看门狗 */ void IWDG_Feed(void) { IWDG_ReloadCounter(); /*reload*/ } /** *main函数 */ void main(void) { NVIC_Configuration();//优先级配置 IWDG_Init(4,625);//初始化独立看门狗,分频数为64,重装载值为625,溢出时间计算为:64*625/40=1000ms=1s while(1) { delay_ms(500);//0.5秒喂一次狗 IWDG_Feed();//喂狗 } }
以上是关于stm32独立看门狗和窗口看门狗的区别是啥的主要内容,如果未能解决你的问题,请参考以下文章