- void IWDG_Configuration(void)
- {
- /* 写入0x5555,用于允许狗狗寄存器写入功能 */
- IWDG_WriteAccessCmd(IWDG_WriteAccess_Enable);
- /* 狗狗时钟分频,40K/256=156HZ(6.4ms)*/
- IWDG_SetPrescaler(IWDG_Prescaler_256);
- /* 喂狗时间 5s/6.4MS=781 .注意不能大于0xfff*/
- IWDG_SetReload(781);
- /* 喂狗*/
- IWDG_ReloadCounter();
- /* 使能狗狗*/
- IWDG_Enable();
- }#include "STM32Libstm32f10x.h"
- #include "hal.h"
- int main(void)
- {
- ChipHalInit(); //片内硬件初始化
- ChipOutHalInit(); //片外硬件初始化if(RCC_GetFlagStatus(RCC_FLAG_IWDGRST)!=RESET){LED2_ON;RCC_ClearFlag();}/*如果上次的复位是看门复位的话LED2点亮*/
- LED1_ON;
- SysTickDelay(500);
- LED1_OFF;
- /*闪LED1 5秒后没喂狗将自动复位LED1又闪LED2亮*/
- IWDG_Enable(); //启动看门狗,自动就会使能内部的40K
- for(;;)
- {
- if(GET_LEFT())
- {
- IWDG_ReloadCounter(); //手动喂狗
- }
- }
- }
复制代码
WWDG简介
窗口看门狗通常被用来监测由外部干扰或不可预见的逻辑条件造成的应用程序背离正常的运行序列而产生的软件故障。除非递减计数器的值在T6位变成0前被刷新,看门狗电路在达到预置的时间周期时,会产生一个MCU复位。在递减计数器达到窗口寄存器数值之前,如果7位的递减计数器数值(在控制寄存器中)被刷新, 那么也将产生一个MCU复位。这表明递减计数器需要在一个有限的时间窗口中被刷新。
17.2
WWDG主要特性
●可编程的自由运行递减计数器
●条件复位
─当递减计数器的值小于0x40,(若看门狗被启动)则产生复位。
─当递减计数器在窗口外被重新装载,(若看门狗被启动)则产生复位。见图155。
●如果启动了看门狗并且允许中断,当递减计数器等于0x40时产生早期唤醒中断(EWI),它可以被用于重装载计数器以避免WWDG复位。
如果看门狗被启动(WWDG_CR寄存器中的WDGA位被置’1’), 并且当7位(T[6:0])递减计数器从0x40翻转到0x3F(T6位清零)时,则产生一个复位。如果软件在计数器值大于窗口寄存器中的数值时重新装载计数器,也将产生一个复位。应用程序在正常运行过程中必须定期地写入WWDG_CR寄存器以防止MCU发生复位。只有当计数器值小于窗口寄存器的值时,才能进行写操作。储存在WWDG_CR寄存器中的数值必须在0xFF和0xC0之间:
●启动看门狗 在系统复位后,看门狗总是处于关闭状态,设置WWDG_CR寄存器的WDGA位能够开启看门狗,随后它不能再被关闭,除非发生复位。
●控制递减计数器 递减计数器处于自由运行状态,即使看门狗被禁止,递减计数器仍继续递减计数。当看门狗被启用时,T6位必须被设置,以防止立即产生一个复位。 T[5:0]位包含了看门狗产生复位之前的计时数目;复位前的延时时间在一个最小值和一个最大值之间变化,这是因为写入WWDG_CR寄存器时,预分频值是未知的。 配置寄存器(WWDG_CFR) 中包含窗口的上限值:要避免产生复位,递减计数器必须在其值小于窗口寄存器的数值并且大于0x3F时被重新装载,图155描述了窗口寄存器的工作过程。 另一个重装载计数器的方法是利用早期唤醒中断(EWI)。设置WWDG_CFR寄存器中的WEI位开启该中断。当递减计数器到达0x40时,则产生此中断,相应的中断服务程序(ISR)可以用来加载计数器以防止WWDG复位。在WWDG_SR寄存器中写’0’可以清除该中断。
看这么多7788的肯定晕直接看代码:
这个就是窗口看门狗的例程了,窗口看门狗的特性:
喂狗太快—复位,喂狗太慢—复位.迟了喂狗,还可以有中断.WWDG_IRQHandler
- #include "STM32Libstm32f10x.h"
- void WWDG_Configuration(void)
- {
- /* 窗口看门狗时钟允许 */
- RCC_APB1PeriphClockCmd(RCC_APB1Periph_WWDG, ENABLE);
- /* 看门狗节拍 = (36M/4096)/8 = 1098 Hz就是说一秒钟计数器减1098下*/
- WWDG_SetPrescaler(WWDG_Prescaler_8);
- /* 窗口值用0x42就是说计数器满是0x7f在减到0x42之前喂狗了就算喂早了-复位*/
- WWDG_SetWindowValue(0x42);
- /*看门狗使能并初始化定时器为0x7f最大就是0x7f计数器减到到0x3F(T6位清零)时,则产生一个复位*/
- WWDG_Enable(0x7F);
- /* Clear EWI flag 清中断标记*/
- WWDG_ClearFlag();
- /* 使能 EW interrupt这个会在计数器减到0x40的时候产生一个"死前"中断 当然你也可以在这个中断里赶紧喂狗-省的狗咬你(复位)*/
- WWDG_EnableIT();
- }
- /*******************************************************************************
- * Function Name : WWDG_IRQHandler”死"前中断
- * Description : This function handles WWDG interrupt request.
- * Input : None
- * Output : None
- * Return : None
- *******************************************************************************/
- extern bool Feed_Dog;
- void WWDG_IRQHandler(void)
- {
- static u8 led2=0;
- /* 喂狗 */
- if(Feed_Dog==TRUE)
- {
- WWDG_SetCounter(0x7F);
- Feed_Dog=FALSE;
- }
- /* 清中断标志*/
- WWDG_ClearFlag();
- //每进入此中断,LED2翻转一次
- if(led2)
- {
- LED2_OFF;
- led2=0;
- }
- else
- {
- LED2_ON;
- led2=1;
- }
- }/**********由于喂狗太早也会复位所以 就在“死”前中断 喂狗了for(;;)
- {
- if(GET_LEFT()) //按左键,则系统长时间等待,也就是不喂狗!
- {
- SysTickDelay(1000);
- }
- Feed_Dog=TRUE;
- if(GET_RIGHT()) //按右键则频繁喂狗
- {
- WWDG_SetCounter(0x7F);
- }
- }//按键左右的后果都是复位,不按的话会在“死”前中断【WWDG_IRQHandler】中及时喂狗LED2不停的闪以一般的情况说,这个“死”前中断中断里面不应该
- 喂狗的,而是应该做系统临死前的一些工作,例如保存重要数据之类.***************************************************************************/
复制代码
电子白菜曰"是STM32 芯片内的BUG,至少是我手上那片CPU 的BUG.就是:初始
化窗口狗中断前,必须要有片内外设被允许,例如允许GPIO
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
只有允许了一个片内外设,再初始化窗口狗中断(NVIC_Configuration()),窗口狗中断才有
效.你可以试试在RCC 配置后就马上运行NVIC_Configuration(),之后再初始化GPIO,那么窗
口狗的中断WWDG_IRQHandler就不会进入了,对于我这个程序,就不会喂狗,结果系统就不停被复位.如果其他
CPU也有这个情况,那么这个可以肯定就是STM32 芯片的BUG.”
颠倒着两句话的顺序就可以了。
我的STM32 103VC T6也是,这个在勘误表中可以查到。