STM32内部自带了 2个看门狗:独立看门狗( IWDG)和窗口看门狗 WWDG)。
我们将通过按键 WK_UP来喂狗,然后通过 DS0提示复位状态。
10.1 STM32独立看门狗简介
40KHZ低速时钟驱动,是一个内部RC时钟,看门狗对时间要求不精确
键值寄存器IWDG_KR
0XCCCC,启用独立看门狗
0xFFF递减计数,末尾0x000产生复位信号IWDG_RESET
0xAAAA,IWDG_RLR的值重新加载
iwdg_pr iwdg_rlr写保护,先写0x5555
预分频寄存器IWDG-PR
设置看门狗时钟的分频系数
重装载寄存器
保存重装载到计数器中的值
库函数:stm32xxxx_hal_iwdg.c
库函数配置:
1.取消寄存器写保护:HAL_StatusTypeDef HAL_IWDG_Init( IWDG_HandleTypeDef *hiwdg );
HAL_IWDG_Init函数使用的一般方法为:
IWDG_HandleTypeDef IWDG_Handler; //独立看门狗句柄
IWDG_Handler.Instance=IWDG; //独立看门狗
IWDG_Handler.Init.Prescaler=IWDG_PRESCALER_64; //设置 IWDG分频系数
IWDG_Handler.Init.Reload=500; //重装载值
HAL_IWDG_Init(&IWDG_Handler);
看门狗的喂狗时间 (也就是看门狗溢出时间 ),该时间的计算方式为:
Tout=((4×2^prer) ×rlr) /32
Tout为看门狗溢出时间(单位为 ms prer为看门狗时钟预分频值( IWDG_PR值),
范围为 0~7 rlr为看门狗的重装载值( IWDG_RLR的值);
例:prer=4 (4-64) rlr=500,tout=64*500/32=1000ms=1s,
看门狗的溢出时间为1s
2.重载计数值喂狗(向 IWDG_KR写入 0XAAAA)
在HAL中 重载计数值的函数是 HAL_IWDG_Refresh,该函数声明为
HAL_StatusTypeDef HAL_IWDG_Refresh(IWDG_HandleTypeDef *hiwdg);
3.启动看门狗((向 IWDG_KR写入 0XCCCC)
HAL库函数里面启动独立看门狗的函数是 __HAL_IWDG_START
__HAL_IWDG_START(hiwdg);
实验验证思路:
将通过一个 LED灯来指示程序是否重启 ,来验证 STM32F1的独立看门狗
在配置看门狗后,DS0将常亮,如果 KEY_UP按键按下,就喂狗,只要 KEY_UP不停的按,看门狗就一直不会产生复位 ,保持 DS0的常亮,一旦 超过看门狗定 溢出 时间 Tout)还没按,那么将会导致程序重启,这将导致 DS0熄灭 一次 。
10..2硬件设计
本实验用到的硬件资源有:
1) 指示灯 DS0
2) WK_UP按键
3) 独立看门狗
10.3软件设计
打开工程,新建 wdg.c和 wdg.h两个文件,并保存在 WDG文件夹下,并将 WDG文件夹加入头文件包含路径。
在wdg.c里面输入如下代码:(两部分 :1.初始化看门狗 2.喂狗)
#include "wdg.h"IWDG_HandleTypeDef IWDG_Handler; //独立看门狗句柄
//初始化独立看门狗
//prer:分频数 :IWDG_PRESCALER_4~IWDG_PRESCALER_256//rlr:自动重装载值 ,0~0XFFF.
//时间计算 (大概 ):Tout=((4*2^prer)*rlr)/32 (ms).
void IWDG_Init(u8 prer,u16 rlr)
{
IWDG_Handler.Instance=IWDG;
IWDG_Handler.Init.Prescaler=prer; //设置 IWDG分频系数
IWDG_Handler.Init.Reload=rlr; //重装载值
HAL_IWDG_Init(&IWDG_Handler); //初始化 IWDG,默认会开启独立看门狗
}.....................
//喂独立看门狗
void IWDG_Feed(void){
HAL_IWDG_Refresh(&IWDG_Handler); //喂狗
}
主函数(main.c)
1.初始化系统代码
2.启动按键输入和启动看门狗
3.开启看门狗后立刻点亮DS0,进入死循环等待按键输入
4.按键则喂狗,否则IWDG复位
----------------------------------
int main(void)
{
HAL_Init(); //初始化 HAL库
Stm32_Clock_Init(RCC_PLL_MUL9); //设置时钟 ,72Mdelay_init(72); //初始化延时函数
uart_init(115200); //初始化串口
LED_Init(); //初始化 LEDKEY_Init(); //初始化按键
delay_ms(100); //延时 100ms再初始化看门狗 ,LED0的变化 "可见 "IWDG_Init(IWDG_PRESCALER_64,500);//分频数为 64,重载值为 500,溢出时间为 1s LED0=0;//点亮
while(1)
{
if(KEY_Scan(0)==WKUP_PRES) //如果 WK_UP按下,喂狗
{IWDG_Feed(); //喂狗
}delay_ms(10);
}
}
10.4下载验证
下载代码后, 可以 看到 DS0不停的闪烁,证明程序在不停的复位,否则只会 DS0常亮 。这时我们试试不停的按 WK_UP按键,可以看到 DS0就常亮了,不会 再 闪烁。说明我们
的实验是成功的。