从下往上看:
1. 时钟设置
RCC_APB1PeriphClockCmd(RCC_APB1Periph_WWDG,ENABLE);//使能独立看门狗时钟
WWDG_SetPrescaler(WWDG_Prescaler_8);//看门狗预分频器WWDG counter clock = (PCLK1/4096)/8
2.设置窗口值
实际就是设置WWDG_CR的低七位值, 但是这个值要大于0x40(也就是bit T6必须为1, 如果小于的话, 直接就复位, 因此窗口的上限值的取值范围: 0x40~ 0x7F)
看门狗使能的话, 则WWDG_CR的位WDGA置1
WWDG_SetWindowValue(wr);
WWDG_Enable(WWDG_CNT);
3. 是不是没看到关于WWDG的中断开启?
实际在时钟设置的时候以及被设置了.
void WWDG_SetWindowValue(uint8_t WindowValue)
{
__IO uint32_t tmpreg = 0;
/* Check the parameters */
assert_param(IS_WWDG_WINDOW_VALUE(WindowValue));
/* Clear W[6:0] bits */
tmpreg = WWDG->CFR & CFR_W_MASK;//#define CFR_W_MASK ((uint32_t)0xFFFFFF80)
/* Set W[6:0] bits according to WindowValue value */
tmpreg |= WindowValue & (uint32_t) BIT_MASK;
/* Store the new value */
WWDG->CFR = tmpreg;
}
WWDG_CFR:
bit6:0 : 设置窗口值
bit7:8 : 设置分配
bit9 : 提前唤醒中断, 此位若置’1’,则当计数器值达到40h,即产生中断。此中断只能由硬件在复位后清除。
4.开启了中断,那么当然要设置中断优先级
NVIC_InitStructure.NVIC_IRQChannel=WWDG_IRQn; //窗口看门狗中断
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=0x02; //抢占优先级为2
NVIC_InitStructure.NVIC_IRQChannelSubPriority=0x03; //子优先级为3
NVIC_InitStructure.NVIC_IRQChannelCmd=ENABLE; //使能窗口看门狗
NVIC_Init(&NVIC_InitStructure);
5.运行原理
实际他就是一个倒计数定时器, 当我们设置的初始值减到0x3F的时候,会产生复位, 如果我们开启了复位前中断,那么会先运行中断, 然后复位.我们可以在复位中断保存一些数据,.
目前在实际项目还没用过, 没有对时序要求这么严格的项目.
正点原子例程代码
void WWDG_Init(u8 tr,u8 wr,u32 fprer)
{
NVIC_InitTypeDef NVIC_InitStructure;
RCC_APB1PeriphClockCmd(RCC_APB1Periph_WWDG,ENABLE); //使能窗口看门狗时钟
WWDG_CNT=tr&WWDG_CNT; //初始化WWDG_CNT.
WWDG_SetPrescaler(fprer); //设置分频值
WWDG_SetWindowValue(wr); //设置窗口值
WWDG_Enable(WWDG_CNT); //开启看门狗
NVIC_InitStructure.NVIC_IRQChannel=WWDG_IRQn; //窗口看门狗中断
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=0x02; //抢占优先级为2
NVIC_InitStructure.NVIC_IRQChannelSubPriority=0x03; //子优先级为3
NVIC_InitStructure.NVIC_IRQChannelCmd=ENABLE; //使能窗口看门狗
NVIC_Init(&NVIC_InitStructure);
WWDG_ClearFlag();//清除提前唤醒中断标志位
WWDG_EnableIT();//开启提前唤醒中断
}
//窗口看门狗中断服务程序
void WWDG_IRQHandler(void)
{
WWDG_SetCounter(WWDG_CNT); //重设窗口看门狗值
WWDG_ClearFlag();//清除提前唤醒中断标志位
LED1=!LED1;
}