1.窗口看门狗( WWDG):通常被用来监测由外部干扰或不可预见的逻辑条件造成的应用程序背离正常的运行序列而产生的软件故障。
2.窗口看门狗工作示意图:
T[6:0]就是 WWDG_CR 的低七位, W[6:0]即是 WWDG-》CFR 的低七位。T[6:0]
就是窗口看门狗的计数器,而 W[6:0]则是窗口看门狗的上窗口,下窗口值是固定的( 0X40)。当窗口看门狗的计数器在上窗口值之外被刷新,或者低于下窗口值都会产生复位。上窗口值( W[6:0]) 是由用户自己设定的,根据实际要求来设计窗口值,但是一定要确保窗口值大于 0X40,否则窗口就不存在了。
3.相关寄存器
a.控制寄存器( WWDG_CR):各位描述如下图
WWDG_CR 只有低八位有效, T[6:0]用来存储看门狗的计数器值,随时更新,每个窗口看门狗计数周期( 4096×2^ WDGTB)减 1。当该计数器的值从 0X40 变为 0X3F 的时候,将产生看门狗复位。
WDGA 位则是看门狗的激活位,该位由软件置 1,以启动看门狗,并且一定要注意的是该位一旦设置,就只能在硬件复位后才能清零了。
b.配置寄存器( WWDG_CFR)L
EWI 是提前唤醒中断,也就是在快要产生复位的前一段时间(T[6:0]=0X40) 来提醒我们,需要进行喂狗了,否则将复位!
c.状态寄存器( WWDG_SR)
该寄存器用来记录当前是否有提前唤醒的标志。该寄存器仅有位 0 有效,其他都是保留位。当计数器值达到 40h 时,此位由硬件置 1。它必须通过软件写 0 来清除。对此位写 1 无效。 即使中断未被使能, 在计数器的值达到 0X40的时候, 此位也会被置 1。
4.WWDG库函数配置步骤:
1)使能 WWDG 时钟:WWDG 不同于 IWDG, IWDG 有自己独立的 40Khz 时钟,而 WWDG使用的是 PCLK1 的时钟,需要先使能时钟。
操作:
RCC_APB1PeriphClockCmd(RCC_APB1Periph_WWDG, ENABLE); // WWDG 时钟使能
2)设置窗口值和分频数
设置窗口值的函数:void WWDG_SetWindowValue(uint8_t WindowValue);//入口参数为窗口值
设置分频数的函数是:void WWDG_SetPrescaler(uint32_t WWDG_Prescaler);//入口参数是分频值
3)开启 WWDG 中断并分组
开启 WWDG 中断的函数为:WWDG_EnableIT(); //开启窗口看门狗中断
中断优先级配置,使用 NVIC_Init()函数。
4) 设置计数器初始值并使能看门狗
void WWDG_Enable(uint8_t Counter);//该函数既设置了计数器初始值,同时使能了窗口看门狗。
5) 编写中断服务函数
在最后,编写窗口看门狗的中断服务函数,通过该函数来喂狗,喂狗要快,否则当窗口看门狗计数器值减到 0X3F 的时候,就会引起软复位了。在中断服务函数里面也要将状态寄存器的 EWIF 位清空。
5.库函数实现
/*窗口看门狗初始化*/
void WWDG_Init(u8 tr,u8 wr,u32 fprer)
{
RCC_APB1PeriphClockCmd(RCC_APB1Periph_WWDG, ENABLE); // WWDG时钟使能
WWDG_SetPrescaler(fprer);设置IWDG预分频值
WWDG_SetWindowValue(wr);//设置窗口值
WWDG_Enable(tr); //使能看门狗 ,设置 counter.
WWDG_ClearFlag();
WWDG_NVIC_Init();//初始化窗口看门狗 NVIC
WWDG_EnableIT(); //开启窗口看门狗中断
}
//重设置WWDG计数器的值
void WWDG_Set_Counter(u8 cnt)
{
WWDG_Enable(cnt);
}
//窗口看门狗中断服务程序
void WWDG_NVIC_Init()
{
NVIC_InitTypeDef NVIC_InitStructure;
NVIC_InitStructure.NVIC_IRQChannel = WWDG_IRQn; //WWDG中断
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2; //抢占2,子优先级3,组2
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3; //抢占2,子优先级3,组2
NVIC_InitStructure.NVIC_IRQChannelCmd=ENABLE;
NVIC_Init(&NVIC_InitStructure);//NVIC初始化
}
void WWDG_IRQHandler(void)
{
// Update WWDG counter
WWDG_SetCounter(0x7F); //当禁掉此句后,窗口看门狗将产生复位
// Clear EWI flag */
WWDG_ClearFlag(); //清除提前唤醒中断标志位
// Toggle GPIO_Led pin 7 */
LED1=!LED1;
}
1.窗口看门狗( WWDG):通常被用来监测由外部干扰或不可预见的逻辑条件造成的应用程序背离正常的运行序列而产生的软件故障。
2.窗口看门狗工作示意图:
T[6:0]就是 WWDG_CR 的低七位, W[6:0]即是 WWDG-》CFR 的低七位。T[6:0]
就是窗口看门狗的计数器,而 W[6:0]则是窗口看门狗的上窗口,下窗口值是固定的( 0X40)。当窗口看门狗的计数器在上窗口值之外被刷新,或者低于下窗口值都会产生复位。上窗口值( W[6:0]) 是由用户自己设定的,根据实际要求来设计窗口值,但是一定要确保窗口值大于 0X40,否则窗口就不存在了。
3.相关寄存器
a.控制寄存器( WWDG_CR):各位描述如下图
WWDG_CR 只有低八位有效, T[6:0]用来存储看门狗的计数器值,随时更新,每个窗口看门狗计数周期( 4096×2^ WDGTB)减 1。当该计数器的值从 0X40 变为 0X3F 的时候,将产生看门狗复位。
WDGA 位则是看门狗的激活位,该位由软件置 1,以启动看门狗,并且一定要注意的是该位一旦设置,就只能在硬件复位后才能清零了。
b.配置寄存器( WWDG_CFR)L
EWI 是提前唤醒中断,也就是在快要产生复位的前一段时间(T[6:0]=0X40) 来提醒我们,需要进行喂狗了,否则将复位!
c.状态寄存器( WWDG_SR)
该寄存器用来记录当前是否有提前唤醒的标志。该寄存器仅有位 0 有效,其他都是保留位。当计数器值达到 40h 时,此位由硬件置 1。它必须通过软件写 0 来清除。对此位写 1 无效。 即使中断未被使能, 在计数器的值达到 0X40的时候, 此位也会被置 1。
4.WWDG库函数配置步骤:
1)使能 WWDG 时钟:WWDG 不同于 IWDG, IWDG 有自己独立的 40Khz 时钟,而 WWDG使用的是 PCLK1 的时钟,需要先使能时钟。
操作:
RCC_APB1PeriphClockCmd(RCC_APB1Periph_WWDG, ENABLE); // WWDG 时钟使能
2)设置窗口值和分频数
设置窗口值的函数:void WWDG_SetWindowValue(uint8_t WindowValue);//入口参数为窗口值
设置分频数的函数是:void WWDG_SetPrescaler(uint32_t WWDG_Prescaler);//入口参数是分频值
3)开启 WWDG 中断并分组
开启 WWDG 中断的函数为:WWDG_EnableIT(); //开启窗口看门狗中断
中断优先级配置,使用 NVIC_Init()函数。
4) 设置计数器初始值并使能看门狗
void WWDG_Enable(uint8_t Counter);//该函数既设置了计数器初始值,同时使能了窗口看门狗。
5) 编写中断服务函数
在最后,编写窗口看门狗的中断服务函数,通过该函数来喂狗,喂狗要快,否则当窗口看门狗计数器值减到 0X3F 的时候,就会引起软复位了。在中断服务函数里面也要将状态寄存器的 EWIF 位清空。
5.库函数实现
/*窗口看门狗初始化*/
void WWDG_Init(u8 tr,u8 wr,u32 fprer)
{
RCC_APB1PeriphClockCmd(RCC_APB1Periph_WWDG, ENABLE); // WWDG时钟使能
WWDG_SetPrescaler(fprer);设置IWDG预分频值
WWDG_SetWindowValue(wr);//设置窗口值
WWDG_Enable(tr); //使能看门狗 ,设置 counter.
WWDG_ClearFlag();
WWDG_NVIC_Init();//初始化窗口看门狗 NVIC
WWDG_EnableIT(); //开启窗口看门狗中断
}
//重设置WWDG计数器的值
void WWDG_Set_Counter(u8 cnt)
{
WWDG_Enable(cnt);
}
//窗口看门狗中断服务程序
void WWDG_NVIC_Init()
{
NVIC_InitTypeDef NVIC_InitStructure;
NVIC_InitStructure.NVIC_IRQChannel = WWDG_IRQn; //WWDG中断
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2; //抢占2,子优先级3,组2
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3; //抢占2,子优先级3,组2
NVIC_InitStructure.NVIC_IRQChannelCmd=ENABLE;
NVIC_Init(&NVIC_InitStructure);//NVIC初始化
}
void WWDG_IRQHandler(void)
{
// Update WWDG counter
WWDG_SetCounter(0x7F); //当禁掉此句后,窗口看门狗将产生复位
// Clear EWI flag */
WWDG_ClearFlag(); //清除提前唤醒中断标志位
// Toggle GPIO_Led pin 7 */
LED1=!LED1;
}
举报