赞
踩
1、WWDG初始化流程
<1>使能窗口看门狗的时钟
RCC_APB1PeriphClockCmd(RCC_APB1Periph_WWDG, ENABLE);
<2>设置窗口看门狗时钟分频系数
WWDG_SetPrescaler(WWDG_Prescaler_8);
<3>设置窗口的上限值
WWDG_SetWindowValue(80);
<4>设置计数值的初值
WWDG_Enable(127);
<5>配置WWDG的NVIC
//略
<6>清空提前唤醒中断标志位,使能提前唤醒中断标志位
//清空提前唤醒中断标志位
WWDG_ClearFlag();
//使能提前唤醒中断
WWDG_EnableIT();
<7>编写看门狗中断函数
void WWDG_IRQHandler(void)
{
if(WWDG_GetFlagStatus()==SET)
{
//进行喂狗
WWDG_SetCounter(127);
//清空提前唤醒中断标志位
WWDG_ClearFlag();
}
}
2、WWDG初始化例程
/* WWDG configuration ,窗口看门狗的配置*/ /* Enable WWDG clock ,使能看门狗的时钟*/ RCC_APB1PeriphClockCmd(RCC_APB1Periph_WWDG, ENABLE); /* 窗口看门狗的时钟 = (PCLK1 (42MHz)/4096)/8 = 1281 Hz (~780 us) */ WWDG_SetPrescaler(WWDG_Prescaler_8); /* Set Window value to 80; WWDG counter should be refreshed only when the counter is below 80 (and greater than 0x40) otherwise a reset will be generated 设置窗口的上限值为 80 */ WWDG_SetWindowValue(80); /* 设置计数值的初值为 127,则窗口看门狗的最大超时时间 = 780 us * 64 = 49.92 ms 这个时候窗口刷新时间如下 ~780 * (127-80) = 36.6ms < refresh window < ~780 * 64 = 49.9ms */ WWDG_Enable(127); //WWDG NVIC 配置 NVIC_InitStructure.NVIC_IRQChannel = WWDG_IRQn; //窗口看门狗中断通道 NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=0; //抢占优先级 0 NVIC_InitStructure.NVIC_IRQChannelSubPriority =0; //子优先级 0 NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ 通道使能 NVIC_Init(&NVIC_InitStructure); //根据指定的参数初始化 VIC 寄 存器 //清空提前唤醒中断标志位 WWDG_ClearFlag(); //使能提前唤醒中断 WWDG_EnableIT(); // 看门狗中断服务函数 void WWDG_IRQHandler(void) { if(WWDG_GetFlagStatus()==SET) { //进行喂狗 WWDG_SetCounter(127); //清空提前唤醒中断标志位 WWDG_ClearFlag(); } } /* 检查是否窗口看门狗导致的复位,如果发现由窗口看门 狗导致的复位,输出打印信息*/ if (RCC_GetFlagStatus(RCC_FLAG_WWDGRST) != RESET) { /* WWDGRST flag set */ printf("wwdg reset cpu\r\n"); /* Clear reset flags */ RCC_ClearFlag(); } else { /* WWDGRST flag is not set */ printf("normal reset cpu\r\n"); }
3、WWDG应用例程
static volatile uint32_t g_wwdg_cnt=0; int main(void) { int32_t rt = 0; /* GPIOA GPIOE GPIOF硬件时钟使能,就是让GPIOA GPIOE GPIOF工作 */ RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE); RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOE, ENABLE); RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOF, ENABLE); /* 配置PE13 PE14为输出模式,让这根引脚具有输出高低电平的功能 */ GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13|GPIO_Pin_14; //第13 14号引脚 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT; //输出模式 GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; //推挽输出,增强驱动能力,引脚的输出电流更大 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz; //引脚的速度最大为100MHz GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL; //没有使用内部上拉电阻 GPIO_Init(GPIOE, &GPIO_InitStructure); /* 配置PF9 PF10为输出模式,让这根引脚具有输出高低电平的功能 */ GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9|GPIO_Pin_10; //第9 10号引脚 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT; //输出模式 GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; //推挽输出,增强驱动能力,引脚的输出电流更大 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz; //引脚的速度最大为100MHz GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL; //没有使用内部上拉电阻 GPIO_Init(GPIOF, &GPIO_InitStructure); GPIO_SetBits(GPIOF,GPIO_Pin_9|GPIO_Pin_10); GPIO_SetBits(GPIOE,GPIO_Pin_13|GPIO_Pin_14); //配置中断优先级分组选择第二组 NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //串口1初始化波特率为115200bps usart1_init(115200); delay_ms(500); /* Check if the system has resumed from IWDG reset ,检查当前系统复位是否有看门狗复位导致*/ if (RCC_GetFlagStatus(RCC_FLAG_IWDGRST) != RESET) { /* IWDGRST flag set */ printf("iwdg reset cpu\r\n"); } else if (RCC_GetFlagStatus(RCC_FLAG_WWDGRST) != RESET) { /* WWDGRST flag set */ printf("wwdg reset cpu\r\n"); } else { /* IWDGRST flag is not set */ printf("normal reset cpu\r\n"); } /* Clear reset flags,清空所有复位标记 */ RCC_ClearFlag(); /* WWDG configuration */ /* Enable WWDG clock ,使能窗口看门狗的时钟*/ RCC_APB1PeriphClockCmd(RCC_APB1Periph_WWDG, ENABLE); /* WWDG clock counter = (PCLK1 (42MHz)/4096)/8 = 1281 Hz (~780 us) 窗口看门狗的时钟频率= (PCLK1 (42MHz)/4096)/8 = 1281 Hz (-1,780 us T=1/f) */ WWDG_SetPrescaler(WWDG_Prescaler_8); /* Set Window value to 80; WWDG counter should be refreshed only when the counter is below 80 (and greater than 64) otherwise a reset will be generated */ WWDG_SetWindowValue(80); /* Enable WWDG and set counter value to 127, WWDG timeout = ~780 us * 64 = 49.92 ms In this case the refresh window is: ~780 * (127-80) = 36.6ms < refresh window < ~780 * 64 = 49.9ms 设置看门狗的初始值为127 */ WWDG_Enable(127); WWDG_ClearFlag(); //使能窗口看门狗唤醒中断 WWDG_EnableIT(); //配置窗口看门狗的中断优先级 NVIC_InitStructure.NVIC_IRQChannel = WWDG_IRQn; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure); while(1) { //末尾添加一行代码 g_wwdg_cnt=0; } } void WWDG_IRQHandler(void) { if(WWDG_GetFlagStatus()==SET) { g_wwdg_cnt++; //约10秒时间 if(g_wwdg_cnt >= 200) { while(1); } //喂狗 WWDG_SetCounter(127); //清空标志位 WWDG_ClearFlag(); } }
窗口看门狗(WWDG):Window Watch Dog
窗口看门狗常被用来监测,由外部干扰或不可预见的逻辑条件造成的应用程序背离正常的运行序列而造成的软件故障,必须在限定的时间窗口内刷新计数器,否则导致MCU复位。
窗口看门狗需要在实时操作系统下运行,可以监测系统错误
WWDG的主要特性:
1、可编程的自由运行计递减数器,
2、复位条件:
当递减计数器值小于0x40时复位,在窗口外重载递减计数器时复位
3、提前唤醒中断(EWI):当递减计数器等于0x40时被触发
喂狗注意事项:必须在窗口范围内喂狗。 提前喂狗,cpu复位;超时喂狗,cpu复位
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。