STM32系列第10篇--看门狗
扫描二维码
随时随地手机看文章
看门狗的作用:
在启动正常运行的时候,系统不能复位。
在系统跑飞(程序异常执行)的情况,系统复位,程序重新执行
独立看门狗(IWDG)由专用的低速时钟(LSI)驱动,即使主时钟发生故障它仍有效。独立看门狗适合应用于需要看门狗作为一个在主程序之外 能够完全独立工作,并且对时间精度要求低的场合。
窗口看门狗由从APB1时钟分频后得到时钟驱动。通过可配置的时间窗口来检测应用程序非正常的过迟或过早操作。 窗口看门狗最适合那些要求看门狗在精确计时窗口起作用的程序。
看门狗一般用法:
while(1){喂狗;if(定时标识){里面就是按键程序;}}12345678
计算一下,主循环执行一次的最大时间,看门狗定时是这个时间的一,二十倍,就可以了。不用再某个模块中喂狗,一个循环来一次。
窗口看门狗配置步骤:
取消寄存器写保护:IWDG_WriteAccessCmd();
设置独立看门狗的预分频系数,确定时钟:IWDG_SetPrescaler();
设置看门狗重装载值,确定溢出时间:IWDG_SetReload();
使能看门狗:IWDG_Enable();
应用程序喂狗:IWDG_ReloadCounter();
溢出时间计算:Tout=((4×2^prer) ×rlr) /40 (M3)
wdg.c
voidIWDG_Init(u8prer,u16rlr){IWDG_WriteAccessCmd(IWDG_WriteAccess_Enable);//使能对寄存器IWDG_PR和IWDG_RLR的写操作IWDG_SetPrescaler(prer);//设置IWDG预分频值:设置IWDG预分频值为64IWDG_SetReload(rlr);//设置IWDG重装载值IWDG_ReloadCounter();//按照IWDG重装载寄存器的值重装载IWDG计数器IWDG_Enable();//使能IWDG}12345678
main.c
intmain(void){delay_init();//延时函数初始化NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//设置NVIC中断分组2:2位抢占优先级,2位响应优先级uart_init(115200);//串口初始化为115200LED_Init();//初始化与LED连接的硬件接口KEY_Init();//按键初始化delay_ms(500);//让人看得到灭IWDG_Init(4,625);//与分频数为64,重载值为625,溢出时间为1sLED0=0;//点亮LED0while(1){if(KEY_Scan(0)==WKUP_PRES){IWDG_ReloadCounter();//如果WK_UP按下,则喂狗,LEDO亮,一直连按LED0一直亮}delay_ms(10);};}12345678910111213141516171819
窗口看门狗:
工作过程:
STM32F的窗口看门狗中有一个7位的递减计数器T[6:0],它会在出现下述2种情况之一时产生看门狗复位:
当喂狗的时候如果计数器的值大于某一设定数值W[6:0](上窗口值)时,此设定数值在WWDG_CFR寄存器定义。
当计数器的数值从0x40减到0x3F时【T6位跳变到0】。
如果启动了看门狗并且允许中断,当递减计数器等于0x40时产生早期唤醒中断(EWI),它可以用于喂狗以避免WWDG复位。
配置过程:
使能看门狗时钟:RCC_APB1PeriphClockCmd();
设置分频系数:WWDG_SetPrescaler();
设置上窗口值:WWDG_SetWindowValue();
开启提前唤醒中断并分组(可选):WWDG_EnableIT(); NVIC_Init();
使能看门狗:WWDG_Enable();
喂狗:WWDG_SetCounter();
编写中断服务函数:WWDG_IRQHandler();
wdg.c
voidWWDG_Init(u8tr,u8wr,u32fprer){RCC_APB1PeriphClockCmd(RCC_APB1Periph_WWDG,ENABLE);//WWDG时钟使能WWDG_CNT=tr&WWDG_CNT;//初始化WWDG_CNT,设置计数值WWDG_SetPrescaler(fprer);////设置IWDG预分频值WWDG_SetWindowValue(wr);//设置窗口值WWDG_Enable(WWDG_CNT);//使能看门狗WWDG_ClearFlag();//清除提前唤醒中断标志位WWDG_NVIC_Init();//初始化窗口看门狗NVICWWDG_EnableIT();//开启窗口看门狗中断}//重设置WWDG计数器的值,喂狗voidWWDG_Set_Counter(u8cnt){WWDG_Enable(cnt);//使能看门狗}//窗口看门狗中断服务程序voidWWDG_NVIC_Init(){NVIC_InitTypeDefNVIC_InitStructure;NVIC_InitStructure.NVIC_IRQChannel=WWDG_IRQn;//WWDG中断NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=2;NVIC_InitStructure.NVIC_IRQChannelSubPriority=3;NVIC_InitStructure.NVIC_IRQChannelCmd=ENABLE;NVIC_Init(&NVIC_InitStructure);//NVIC初始化}//中断服务函数voidWWDG_IRQHandler(void){WWDG_SetCounter(WWDG_CNT);//当禁掉此句后,窗口看门狗将产生复位WWDG_ClearFlag();//清除提前唤醒中断标志位LED1=!LED1;//LED状态翻转}12345678910111213141516171819202122232425262728293031323334353637
main.c
intmain(void){delay_init();//延时函数初始化NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//设置中断优先级分组为组2:2位抢占优先级,2位响应优先级uart_init(115200);//串口初始化为115200LED_Init();KEY_Init();//按键初始化LED0=0;delay_ms(300);WWDG_Init(0X7F,0X5F,WWDG_Prescaler_8);//计数器值为7f,窗口寄存器为5f,分频数为8while(1){LED0=1;}}