本帖最后由 gjianw217 于 2016-10-6 01:34 编辑
本实验, 程序一运行则开启WWDG,并使得DS0亮300ms后关闭,进入死循环。等待WWDG中断的到来,在中断里面,喂狗,并执行DS1的翻转操作。所以可以看到DS1不停的闪烁,而DS0只在刚启动的时候闪一下。
1 MM32F103窗口看门狗
窗口看门狗通常被用来监测由外部干扰或不可预见的逻辑条件造成的应用程序背离正常的运行序列而产生的软件故障。除非递减计数器的值在T6位变成0前被刷新,看门狗电路在达到预置的时间周期时,会产生一个MCU复位。在递减计数器达到窗口寄存器数值之前,如果7位的递减计数器数值(在控制寄存器中)被刷新,那么也将产生一个MCU复位。这表明递减计数器需要在一个有限的时间窗口中被刷新。
窗口看门狗的工作原理,如下图所示:
T 是WWDG_CR的低七位, W即是 WWDG ->CFR的低七位。 T就是窗口看门狗的计数器,而 W则是窗口看门狗的上窗口,下窗口值固定(0X40)。 当窗口看门狗的计数器在上窗口值之外被刷新,或者低于下窗口都会产生复位。上窗口值(W)是由用户自己设定的,根据实际要求来计窗口值,但一定要确保窗口值大 于 0X40,否则窗口就不存在了。
2 MM32F103寄存器
1)WWDG_CR寄存器,T存储看门狗的计数值,WDGA是看门狗的激活位
2)配置寄存器WWDG_CFR,其中的 EWI 是提前唤醒中断,也就在快要产生复位的一段时间(T=0X40)来提醒我们,需要进行喂狗了,否则将复位!因此,一般用该来设置中断,当窗口看门的计数器值减到0X40的时候,如果该位设置并开启了中断则会产生中断,可以在中断里面向WWDG_CR重新写入计数器的值,来达到喂狗目的。
3)状态寄存器WWDG_SR,该寄存器用来记录当前是否有提前唤醒的标志。该寄存器仅有位0有效。当计数器值达到40H时,此位由硬件置1,它必须通过软件写0来消除。
3 操作WWDG看门狗
1)使能 WWDG时钟
WWDG不同于IWDG ,IWDG有自己独立的32 Khz 时钟,不存在使能问题。而WWDG 使用的是PCLK1 的时钟,需要先使能。
2)设置 WWDG_CFR和 WWDG_CR 两个寄存器
在时钟使能完后,设置WWDG的CFR和CR 两个寄存器,对WWDG进行配置。包括使能窗口看门狗、开启中断,设置计数 器的初始值,设置窗口值,并设置分频数WDGTB等。
3)开启 WWDG WWDG 中断并分组
在设置完了WWDG 后,需要配置该中断的分组及使能。
4)编写中断服务函数
编写窗口看门狗的中断服务函数,通过该函数来实现喂狗
4 程序实现
1)WWDG初始化
void WWDG_Init(u8 tr,u8 wr,u8 fprer)
{
RCC->APB1ENR|=RCC_APB1ENR_WWDGEN; //使能WWDG时钟
WWDG_CNT=tr&WWDG_CNT; //初始化WWDG_CNT
WWDG->CFR|=fprer<<7; //分频
WWDG->CFR&=0XFF80;
WWDG->CFR|=wr; //设定窗口值
WWDG->CR|=WWDG_CNT; //设定计数器值
WWDG->CR|=WWDG_CR_WDGA; //开启看门狗
MY_NVIC_Init(2,3,WWDG_IRQn,2); //抢占2,子优先级3,组2
WWDG->SR=0X00; //消除提前唤醒中断标志位
WWDG->CFR|=WWDG_CFR_EWI; //使能提前唤醒中断
}
2)WWDG喂狗
void WWDG_Set_Counter(u8 cnt)
{
WWDG->CR =(cnt&0x7F);//重设计数器,喂狗
}
void WWDG_IRQHandler(void)
{
WWDG_Set_Counter(WWDG_CNT);//重设窗口看门狗的值
WWDG->SR=0X00; //消除提前唤醒中断标志位
LED1=!LED1;
}
3)主函数
int main(void)
{
delay_init(72);
uart_init(72,9600);
LED_Init();
LED0=0;
delay_ms(300);
WWDG_Init(0X7F,0X5F,3);// 计数器值为0x7F,窗口寄存器为0x5F,分频数为8
while(1)
{
LED0=1;
}
}
5 实验效果
本帖最后由 gjianw217 于 2016-10-6 01:34 编辑
本实验, 程序一运行则开启WWDG,并使得DS0亮300ms后关闭,进入死循环。等待WWDG中断的到来,在中断里面,喂狗,并执行DS1的翻转操作。所以可以看到DS1不停的闪烁,而DS0只在刚启动的时候闪一下。
1 MM32F103窗口看门狗
窗口看门狗通常被用来监测由外部干扰或不可预见的逻辑条件造成的应用程序背离正常的运行序列而产生的软件故障。除非递减计数器的值在T6位变成0前被刷新,看门狗电路在达到预置的时间周期时,会产生一个MCU复位。在递减计数器达到窗口寄存器数值之前,如果7位的递减计数器数值(在控制寄存器中)被刷新,那么也将产生一个MCU复位。这表明递减计数器需要在一个有限的时间窗口中被刷新。
窗口看门狗的工作原理,如下图所示:
T 是WWDG_CR的低七位, W即是 WWDG ->CFR的低七位。 T就是窗口看门狗的计数器,而 W则是窗口看门狗的上窗口,下窗口值固定(0X40)。 当窗口看门狗的计数器在上窗口值之外被刷新,或者低于下窗口都会产生复位。上窗口值(W)是由用户自己设定的,根据实际要求来计窗口值,但一定要确保窗口值大 于 0X40,否则窗口就不存在了。
2 MM32F103寄存器
1)WWDG_CR寄存器,T存储看门狗的计数值,WDGA是看门狗的激活位
2)配置寄存器WWDG_CFR,其中的 EWI 是提前唤醒中断,也就在快要产生复位的一段时间(T=0X40)来提醒我们,需要进行喂狗了,否则将复位!因此,一般用该来设置中断,当窗口看门的计数器值减到0X40的时候,如果该位设置并开启了中断则会产生中断,可以在中断里面向WWDG_CR重新写入计数器的值,来达到喂狗目的。
3)状态寄存器WWDG_SR,该寄存器用来记录当前是否有提前唤醒的标志。该寄存器仅有位0有效。当计数器值达到40H时,此位由硬件置1,它必须通过软件写0来消除。
3 操作WWDG看门狗
1)使能 WWDG时钟
WWDG不同于IWDG ,IWDG有自己独立的32 Khz 时钟,不存在使能问题。而WWDG 使用的是PCLK1 的时钟,需要先使能。
2)设置 WWDG_CFR和 WWDG_CR 两个寄存器
在时钟使能完后,设置WWDG的CFR和CR 两个寄存器,对WWDG进行配置。包括使能窗口看门狗、开启中断,设置计数 器的初始值,设置窗口值,并设置分频数WDGTB等。
3)开启 WWDG WWDG 中断并分组
在设置完了WWDG 后,需要配置该中断的分组及使能。
4)编写中断服务函数
编写窗口看门狗的中断服务函数,通过该函数来实现喂狗
4 程序实现
1)WWDG初始化
void WWDG_Init(u8 tr,u8 wr,u8 fprer)
{
RCC->APB1ENR|=RCC_APB1ENR_WWDGEN; //使能WWDG时钟
WWDG_CNT=tr&WWDG_CNT; //初始化WWDG_CNT
WWDG->CFR|=fprer<<7; //分频
WWDG->CFR&=0XFF80;
WWDG->CFR|=wr; //设定窗口值
WWDG->CR|=WWDG_CNT; //设定计数器值
WWDG->CR|=WWDG_CR_WDGA; //开启看门狗
MY_NVIC_Init(2,3,WWDG_IRQn,2); //抢占2,子优先级3,组2
WWDG->SR=0X00; //消除提前唤醒中断标志位
WWDG->CFR|=WWDG_CFR_EWI; //使能提前唤醒中断
}
2)WWDG喂狗
void WWDG_Set_Counter(u8 cnt)
{
WWDG->CR =(cnt&0x7F);//重设计数器,喂狗
}
void WWDG_IRQHandler(void)
{
WWDG_Set_Counter(WWDG_CNT);//重设窗口看门狗的值
WWDG->SR=0X00; //消除提前唤醒中断标志位
LED1=!LED1;
}
3)主函数
int main(void)
{
delay_init(72);
uart_init(72,9600);
LED_Init();
LED0=0;
delay_ms(300);
WWDG_Init(0X7F,0X5F,3);// 计数器值为0x7F,窗口寄存器为0x5F,分频数为8
while(1)
{
LED0=1;
}
}
5 实验效果