参考资料:
1、正点原子探索者STM32f407开发板-《STM32f407开发指南-库函数版本》-第12章;
2、STM32F4xx 官方参考资料《STM32F4xx中文参考手册》-第19章。
目录
WWDG时钟
产生RESET的原理:
超时值计算公式:
WWDG 寄存器
控制寄存器 (WWDG_CR)
配置寄存器 (WWDG_CFR)
状态寄存器 (WWDG_SR)
WWDG 寄存器映射
窗口看门狗配置过程
窗口看门狗:之所以称为窗口就是因为其喂狗时间是一个有上下限的范围内(窗口),你可以通过设定相关寄存器,设定其上限时间(下限固定)。喂狗的时间不能过早也不能过晚。
而独立看门狗限制喂狗时间在0-x内,x由相关寄存器决定。喂狗的时间只是不能过晚。
如图,这个窗口的上限就是W,下限就是0x3F,只有在计数器计到这些数之间才能喂狗。
如果到达0x3F还没有喂狗,那么就会产生一个复位信号。
上图中T6位就是0x3F=0011 1111的第六位,如果第六位跳变为0(原本是1),就会复位。
IWDG时钟是专用的低速时钟(LSI)。
WWDG时钟是PCLK1。
①如果看门狗被激活(WWDG_CR 寄存器中的 WDGA 位置 1),T6位大于W6位,比较器=1,与门1输出1。
②如果与门1输出1,T6位是0时,或门2输出1。
③如果或门2输出1,又WDGA是1,与门3输出1,至此,产生RESET信号。
注:写WWDG_CR就是喂狗,WDGA就是启动位。
STM32F的窗口看门狗中有一个7位的递减计数器T[6:0],它会在出现下述2种情况之一时产生看门狗复位:
Ⅰ、当喂狗的时候如果计数器的值大于某一设定数值W[6:0]时,此设定数值在WWDG_CFR寄存器定义。
Ⅱ、当计数器的数值从0x40减到0x3F时【T6位跳变到0】。
如果启动了看门狗并且允许中断,当递减计数器等于0x40时产生早期唤醒中断(EWI),它可以用于喂狗以避免WWDG复位。(就像定个闹钟叫程序去喂狗)
在上篇IWDG里面有详细的原理介绍,WWDG类似,不多赘述。
void WWDG_Enable(uint8_t Counter);//启动并设置初始值
void WWDG_SetCounter(uint8_t Counter);//喂狗
void WWDG_EnableIT(void);//使能提前唤醒中断
void WWDG_SetPrescaler(uint32_t WWDG_Prescaler);
void WWDG_SetWindowValue(uint8_t WindowValue);
FlagStatus WWDG_GetFlagStatus(void);
void WWDG_ClearFlag(void);
RCC_APB1PeriphClockCmd();
② 设置分频系数:
WWDG_SetPrescaler();
③ 设置上窗口值:
WWDG_SetWindowValue();
④ 开启提前唤醒中断并分组(可选):
WWDG_EnableIT();
NVIC_Init();
⑤ 使能看门狗:
WWDG_Enable();
⑥ 喂狗:
WWDG_SetCounter();
⑦编写中断服务函数
WWDG_IRQHandler();
函数分布在stm32f4xx_wwdg.h和stm32f4xx_wwdg.c中。
使用示例:
u8 WWDG_CNT=0X7F;
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_SetCounter(WWDG_CNT);//设置计数值
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;
}
WWDG_Init(0x7F,0X5F,WWDG_Prescaler_8);
计数器值为7f,意思就是初始值为7f,这个是写入CR的,实时更新的;
窗口寄存器为5f,意思就是窗口最大值是5f(最小值固定为3f);
分频数为8。
保存WWDG计数器的设置值,默认为最大。
注意,配置寄存器(WWDG_CFR)的EWI是提前唤醒中断,当窗口看门狗的计数器值减到 0X40的时候,如果该位设置,并开启了中断,则会产生中断,我们可以在中断里面向 WWDG_CR重新写入计数器的值,来达到喂狗的目的。
这里在进入中断后, 必须在不大于 1个 窗口看门狗计数周期的时间( 在 PCLK1频率 为 42M且 WDGTB为 0的 条件下,该时间为 97.52us)内重新写 WWDG_CR,否则,看门狗将产生复位!
Fin.