// 这个实验,如果没有喂狗时,系统就会产生复位,导致系统断电一下,所有LED灯会灭一下;
//这里用到了外部中断(也可以不用),外部中断可以自己加
看门狗的原理:单片机系统在外界的干扰下会出现程序跑飞的现象导致出现死循环,看门狗电路就是为了避免这种情况的发生。看门狗的作用就是在一定时间内(通过定时计数器实现)没有接收喂狗信号(表示 MCU 已经挂了),便实现处理器的自动复位重启(发送复位信号) 。
在键值寄存器(IWDG_KR)中写入 0xCCCC,开始启用独立看门狗;此时计数器开始从其复位值 0xFFF 递减计数。当计数器计数到末尾 0x000 时,会产生一个复位信号(IWDG_RESET)。无论何时,只要键寄存器 IWDG_KR 中被写入 0xAAAA, IWDG_RLR 中的值就会被重新加载到计数器中从而避免产生看门狗复位 。
IWDG_PR 和 IWDG_RLR 寄存器具有写保护功能。要修改这两个寄存器的值,必须先向IWDG_KR 寄存器中写入 0x5555。将其他值写入这个寄存器将会打乱操作顺序,寄存器将重新被保护。重装载操作(即写入 0xAAAA)也会启动写保护功能。
#include "stm32f4xx.h"
void led_init(void);
void key_init(void);
void delay(void);
void iwdg_init(u8 pre,u16 rlr);
void EXTI0_IRQHandler(void);
void feed_iwdg(void);
int main(){
NVIC_PriorityGroupConfig( NVIC_PriorityGroup_2);
delay();
led_init();
key_init();
iwdg_init(4,500);
while(1){
delay();
delay();
delay();
delay();
delay();
delay();
delay();
delay();
feed_iwdg();
}
}
void delay(void){
int i,j;
for(i=0;i<1000;i++)
for(j=0;j<1000;j++)
{}
}
void led_init(void){ //LED0 DS0 PF9
GPIO_InitTypeDef GPIO_InitStruct;
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOF,ENABLE);
GPIO_InitStruct.GPIO_Mode=GPIO_Mode_OUT;
GPIO_InitStruct.GPIO_OType=GPIO_OType_PP;
GPIO_InitStruct.GPIO_Pin=GPIO_Pin_9;
GPIO_InitStruct.GPIO_PuPd=GPIO_PuPd_DOWN;
GPIO_InitStruct.GPIO_Speed=GPIO_Fast_Speed;
GPIO_Init(GPIOF, &GPIO_InitStruct);
}
void key_init(void){// WAKE_UP PA0
GPIO_InitTypeDef GPIO_InitStruct;
EXTI_InitTypeDef EXTI_InitStruct;
NVIC_InitTypeDef NVIC_InitStruct;
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA,ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG,ENABLE);
SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOA,EXTI_PinSource0);//
GPIO_InitStruct.GPIO_Mode=GPIO_Mode_IN;
GPIO_InitStruct.GPIO_OType=GPIO_OType_PP;
GPIO_InitStruct.GPIO_Pin=GPIO_Pin_9;
GPIO_InitStruct.GPIO_PuPd=GPIO_PuPd_DOWN;
GPIO_InitStruct.GPIO_Speed=GPIO_Fast_Speed;
GPIO_Init(GPIOA, &GPIO_InitStruct);
EXTI_InitStruct.EXTI_Line=EXTI_Line0;
EXTI_InitStruct.EXTI_LineCmd=ENABLE;
EXTI_InitStruct.EXTI_Mode=EXTI_Mode_Interrupt;
EXTI_InitStruct.EXTI_Trigger=EXTI_Trigger_Falling;
EXTI_Init(& EXTI_InitStruct);
NVIC_InitStruct.NVIC_IRQChannel=EXTI0_IRQn;
NVIC_InitStruct.NVIC_IRQChannelCmd=ENABLE;
NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority=0X02;
NVIC_InitStruct.NVIC_IRQChannelSubPriority=0X02;
NVIC_Init(& NVIC_InitStruct);
}
void EXTI0_IRQHandler(void){
delay();
if((EXTI_GetITStatus(EXTI_Line0))!=RESET)
GPIO_SetBits(GPIOF, GPIO_Pin_9 );
EXTI_ClearITPendingBit(GPIO_Pin_9);
}
void iwdg_init(u8 pre,u16 rlr){
IWDG_WriteAccessCmd(IWDG_WriteAccess_Enable);
IWDG_SetPrescaler(pre);
IWDG_SetReload(rlr);
IWDG_ReloadCounter();
IWDG_Enable();
}
void feed_iwdg(void){
IWDG_ReloadCounter();
}