STM32窗口看门狗和独立看门狗的区别,看门狗介绍及代码演示

简介: STM32窗口看门狗和独立看门狗的区别,看门狗介绍及代码演示

一、介绍:

STM32看门狗分为独立看门狗和窗口看门狗两种,其两者使用调条件如下所示,

 

 

 

IWDG和WWDG两者特点如下图所示:

 

   

独立看门狗的手册资料:

窗口看门狗的手册资料:

 

               应当注意:在窗口看门狗中,当递减计数器在窗口外被重新装载,(若看门狗被启动)则产生复位

【注】图中的WDGTB为3表示2^3=8,表示8分频,最小时间910us也等于每次计数器减一所需要经过的时间:T(LSB),每隔910us减1。最大值也等于,设置重载(喂狗)值127时(最大),一个复位周期的时间就是最大值58.25ms,也就是所能维持进入复位的最大时间。

 

由于窗口看门狗使用的APB1的PCLK1,时钟最高36MHZ,和RCC_APB2Periph_GPIOx不同,APB1最大就是36MHZ,APB2最大就是72MHZ。

所以串口看门狗需要配置APB1时钟使能,如下语句。

可以从图1-3 窗口看门狗编程说明红看到T(WWDG)=T(PCLK1) 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),即配置窗口值是多少到最小的0x40*T(LSB)(假定T(LSB)为每减一计数所需要的时间),这个配置会告诉单片机什么时候来与递减计数器进行值比较,如果计数值值小于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_InitStructure.NVIC_IRQChannelCmd = ENABLE;      //中断使能,

   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)

   {

   

   }

}

 

三、中断说明:

关于void WWDG_IRQHandler(void)里的中断进入是在减计数到0x40时,处罚中断进入这个中断函数,如果在中断函数中进行减计数的操作,可以避免复位的厄运,但是如果你不做喂狗操作,那减计数值将接着减,数值将为0x3F,此时bit7被置零,此时将会直接导致复位。总之,进入中断函数并非就复位了,只是此时的减计数值到了0x40,而下一次减计数器减一后值为0x3F将导致芯片复位了。

 

 

附录:

独立看门狗(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:ADC单通道(内含:1.实物图/接线图+2.代码部分如下+3.AD用到的库函数总结)
STM32:ADC单通道(内含:1.实物图/接线图+2.代码部分如下+3.AD用到的库函数总结)
303 0
STM32:ADC单通道(内含:1.实物图/接线图+2.代码部分如下+3.AD用到的库函数总结)
|
26天前
|
芯片
stm32f4外设学习篇(代码集合)(一)
stm32f4外设学习篇(代码集合)
|
1月前
STM32--WDG看门狗
STM32--WDG看门狗
|
1月前
STM32控制SG90舵机原理及代码
STM32控制SG90舵机原理及代码
28 1
STM32框架式管理代码第一篇LED代码的管理
STM32框架式管理代码第一篇LED代码的管理
64 0
|
内存技术
STM32Fxx位带操作还不会?哲学三问让你实现位带自由(含位带操作核心代码)以LED与键盘为例
STM32Fxx位带操作还不会?哲学三问让你实现位带自由(含位带操作核心代码)以LED与键盘为例
stm32单片机 代码实现歌曲——红尘情歌
stm32单片机 代码实现歌曲——红尘情歌
96 0
|
监控 程序员 芯片
STM32 你不知道的看门狗细节
你知道什么是看门狗吗?看门狗,实际上可以说就是一个简单的定时器功能,而这个定时器有一个输出端,可以输出复位信号。
STM32 你不知道的看门狗细节
|
搜索推荐 算法
STM32的HAL库开发系列 - 常用的用户库代码 - 快速排序
STM32的HAL库开发系列 - 常用的用户库代码 - 快速排序
160 0
|
算法 搜索推荐 中间件
STM32的HAL库开发系列 - 常用的用户库代码
STM32的HAL库开发系列 - 常用的用户库代码1
147 0