简介:
“看门狗”如其名,即检测软硬件故障,当出现错误无法及时,响应时自动复位
种类:
1.独立看门狗 2.窗口看门狗
独立看门狗(IWDG):
IWDG由一个独立的低速时钟(LSI)驱动,主时钟发生故障时,其仍能正常工作
故IWDG 最适合应用于:能够完全独立工作,并且对时间精度要求较低的场合。
主要特性:
● 自由运行递减计数器
● 时钟由独立 RC 振荡器提供(可在待机和停止模式下运行)
● 当递减计数器值达到 0x000 时产生复位(如果看门狗已激活)
功能说明:
向关键字寄存器(IWDG_KR)写入 0x5555,关闭IWDG_PR 和 IWDG_RLR 寄存器写访问保护,而写入其他值则会破坏该序列,从而使寄存器访问保护再次生效。
向关键字寄存器(IWDG_KR)写入0XCCCC,独立看门狗启动,计数器从复位值(最大0XFFF)开始下降。当计数器值到达0,会产生一个复位信号(独立看门狗复位)
向关键字寄存器(IWDG_KR)写入0XAAAA,IWDG_RLR的数值会重载进计数器,避免看门狗复位
代码实现:
void IWDG_Init(u8 prer,u16 rlr) T=rlr*prer/f
{
IWDG_WriteAccessCmd(IWDG_WriteAccess_Enable); //使能IWDG->PR IWDG->RLR的写 0x5555
IWDG_SetPrescaler(prer); //设置IWDG分频系数
IWDG_SetReload(rlr); //设置IWDG装载值
IWDG_ReloadCounter(); //reload 0xAAAA
IWDG_Enable(); //使能看门狗 (0xCCCC)
}
//喂独立看门狗
void IWDG_Feed(void)
{
IWDG_ReloadCounter();//reload 0xAAAA
}
窗口看门狗 (WWDG):
窗口看门狗 (WWDG) 时钟由 APB1 时钟经预分频后提供,检测应用程序非正常的过迟或过早的操作。
故WWDG 最适合:要求看门狗在精确计时窗口起作用的应用程序.
简要地说,就是在中断中实现喂狗。
主要特性:
●可编程的自由运行递减计数器
● 复位条件
----- 当递减计数器值小于 0x40 时复位(如果看门狗已激活)
----- 在窗口之外重载递减计数器时复位(如果看门狗已激活)
●提前唤醒中断 (EWI):当递减计数器等于 0x40 时触发(如果已使能且看门狗已激活)
●WWDG 不同于 IWDG,IWDG 有自己独立的 LSI 时钟,所以不存在使能问题,而WWDG使用的是 APB1 时钟,需要先使能时钟。在库函数中实现函数如下:
功能说明:
向关键字寄存器(IWDG_KR)写入 0x5555,关闭IWDG_PR 和 IWDG_RLR 寄存器写访问保护,而写入其他值则会破坏该序列,从而使寄存器访问保护再次生效。
向关键字寄存器(IWDG_KR)写入0XCCCC,独立看门狗启动,计数器从复位值(最大0XFFF)开始下降。当计数器值到达0,会产生一个复位信号(独立看门狗复位)
向关键字寄存器(IWDG_KR)写入0XAAAA,IWDG_RLR的数值会重载进计数器,避免看门狗复位
代码实现:
u8 WWDG_CNT=0X7F;
//初始化窗口看门狗
//tr :T[6:0],计数器值
//wr :W[6:0],窗口值
//fprer:分频系数(WDGTB),仅最低2位有效
//Fwwdg=PCLK1/(4096*2^fprer). 一般PCLK1=42Mhz
int main(void)
{
........
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//设置系统中断优先级分组2
WWDG_Init(0x7F,0X5F,WWDG_Prescaler_8); //计数器值为7f(最大为 0X7F,最小不低于 0X40),窗口寄存器为5f,分频数8
........
}
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;
LED2=!LED2;
}