STM32学习心得十六:独立看门狗实验
记录一下,方便以后翻阅~
主要内容:
1) 独立看门狗概述;
2) 常用寄存器和库函数配置;
3) 独立看门狗实验代码解读。
官方资料:《STM32中文参考手册V10》第17章——独立看门狗
1. 看门狗的作用
在由单片机构成的微型计算机系统中,由于单片机的工作常常会受到来自外界电磁场的干扰,造成程序的跑飞,而陷入死循环,程序的正常运行被打断,由单片机控制的系统无法继续工作,会造成整个系统的陷入停滞状态,发生不可预料的后果,所以出于对单片机运行状态进行实时监测的考虑,便产生了一种专门用于监测单片机程序运行状态的模块或者芯片,俗称“看门狗”(watchdog)。其主要作用为:
1.1 在启动正常运行的时候,系统不能复位;
1.2 在系统跑飞(程序异常执行)的情况,系统复位,程序重新执行。
2. STM32的看门狗相关知识
2.1 STM32内置两个看门狗,提供了更高的安全性,时间的精确性和使用的灵活性。两个看门狗设备(独立看门狗和窗口看门狗)可以用来检测和解决由软件错误引起的故障。当计数器达到给定的超时值时,触发一个中断(仅适用窗口看门狗)或者产生系统复位;
2.2 独立看门狗(IWDG)由专用的低速时钟(LSI)驱动,即使主时钟发生故障它仍有效。独立看门狗适合应用于需要看门狗作为一个在主程序之外能够完全独立工作,并且对时间精度要求低的场合;
2.3 窗口看门狗由从APB1时钟分频后得到时钟驱动。通过可配置的时间窗口来检测应用程序非正常的过迟或过早操作。窗口看门狗最适合那些要求看门狗在精确计时窗口起作用的程序。
3. 独立看门狗功能描述
3.1 在键值寄存器(IWDG_KR)中写入0xCCCC,开始启用独立看门狗。此时计数器开始从其复位值0xFFF递减,当计数器值计数到尾值0x000时会产生一个复位信号(IWDG_RESET);
3.2 无论何时,只要在键值寄存器IWDG_KR中写入0xAAAA(通常说的喂狗), 自动重装载寄存器IWDG_RLR的值就会重新加载到计数器,从而避免看门狗复位;
3.3 如果程序异常,就无法正常喂狗,从而系统复位。
4. 独立看门狗框图
4.1 键值寄存器IWDG_KR: 0~15位有效;
4.2 预分频寄存器IWDG_PR:0~2位有效。具有写保护功能,要操作先取消写保护(即在IWDG_KR输入0x5555);
4.3 重装载寄存器IWDG_RLR:0~11位有效。具有写保护功能,要操作先取消写保护(即在IWDG_KR输入0x5555);
4.4 状态寄存器IWDG_SR:0~1位有效。
5. 看门狗相关寄存器解读
5.1 键寄存器IWDG_KR
5.2 预分频寄存器IWDG_PR
5.3 重装载寄存器IWDG_RLR
5.4 状态寄存器IWDG_SR
6. 独立看门狗超时时间
溢出时间计算:
Timeout=((4×2^prer) ×RLR) /40 (针对M3内核)
时钟频率LSI=40K, 一个看门狗时钟周期就是最短超时时间;
最长超时时间= (IWDG_RLR寄存器最大值)×看门狗时钟周期。
7. IWDG独立看门狗操作库函数
7.1 往IWDG_KR寄存器中写0x5555,取消写保护:
void IWDG_WriteAccessCmd(uint16_t IWDG_WriteAccess);
7.2 往IWDG_PR寄存器中写入值,设置预分频系数:
void IWDG_SetPrescaler(uint8_t IWDG_Prescaler);
7.3 往IWDG_RLR寄存器中写入值,设置重装载值:
void IWDG_SetReload(uint16_t Reload);
7.4 往IWDG_KR寄存器中写0xAAAA,喂狗:
void IWDG_ReloadCounter(void);
7.5 往IWDG_KR寄存器中写0xCCCC,使能,启动看门狗工作:
void IWDG_Enable(void);/ /使能看门狗:写0xCCCC到KR//
7.6 从IWDG_SR寄存器中获取看门狗状态,重装载/预分频更新:
FlagStatus IWDG_GetFlagStatus(uint16_t IWDG_FLAG);
8. 独立看门狗操作步骤
8.1 取消寄存器写保护:
IWDG_WriteAccessCmd();
8.2 设置独立看门狗的预分频系数,确定时钟:
IWDG_SetPrescaler();
8.3 设置看门狗重装载值,确定溢出时间:
IWDG_SetReload();
8.4 使能看门狗:
IWDG_Enable();
8.5 应用程序喂狗:
IWDG_ReloadCounter();
8.6 溢出时间计算:
Tout=((4×2^prer) ×rlr) /40 (针对M3内核)
9. 独立看门狗实验相关函数
实现功能:启动后,LED0每隔200ms闪烁,若有任何按键长按或每隔小于200ms的频率连按,则LED0常亮。
跑马灯、按键输入相关代码可参考以前的文章。
9.1 iwdg.h头文件
#ifndef __IWDG_H
#define __IWDG_H
//添加sys.h头文件,里面包含的位操作所需的宏定义,且sys.h引入了stm32f10x.h文件,这样允许使用u8,u16//
#include "sys.h"
//申明一个IWDG_Init初始化函数,包含两个入口参数IWDG_PR(用来设置预分频系数)和IWDG_RLR(用来设置重装载值)//
void IWDG_Init(u8 IWDG_PR,u16 IWDG_RLR);
#endif
9.2 iwdg.c文件
#include "iwdg.h"
//编写IWDG_Init初始化函数//
void IWDG_Init(u8 IWDG_PR,u16 IWDG_RLR)
{
IWDG_WriteAccessCmd(IWDG_WriteAccess_Enable);//取消寄存器写保护//
IWDG_SetPrescaler(IWDG_PR); //设置独立看门狗的预分频系数//
IWDG_SetReload(IWDG_RLR); //设置看门狗重装载值//
IWDG_ReloadCounter(); //喂狗,否则将从0xFFF算起//
IWDG_Enable(); //使能独立看门狗//
}
9.3 main.c文件
#include "led.h"
#include "beep.h"
#include "key.h"
#include "iwdg.h"
#include "delay.h"
#include "sys.h"
int main(void)
{
delay_init(); //延时函数初始化
LED_Init(); //LED端口初始化
KEY_Init(); //初始化与按键连接的硬件接口
BEEP_Init(); //初始化蜂鸣器端口
delay_ms(200); //等待200ms
LED0=0; //先点亮红灯
IWDG_Init(4,625); //根据预分配值和重装载值确定溢出时间//
while(1)
{
//判断是否有按键按下//
if(KEY_Scan(1)==WKUP_PRES|KEY_Scan(1)==KEY0_PRES|KEY_Scan(1)==KEY1_PRES|KEY_Scan(1)==KEY2_PRES)
{
IWDG_ReloadCounter(); //所有任何按键按下,则喂狗//
}
}
}
旧知识点
1)复习如何新建工程模板,可参考STM32学习心得二:新建工程模板;
2)复习基于库函数的初始化函数的一般格式,可参考STM32学习心得三:GPIO实验-基于库函数;
3)复习寄存器地址,可参考STM32学习心得四:GPIO实验-基于寄存器;
4)复习位操作,可参考STM32学习心得五:GPIO实验-基于位操作;
5)复习延迟函数,可参考STM32学习心得九:Systick滴答定时器和延时函数解读;
6)复习ST-LINK调试方法,可参考STM32学习心得十一:ST-LINK调试原理+软硬件仿真调试方法。
上一篇: 产妇的早餐吃什么好
下一篇: 西红柿性寒还是性温,可以多吃吗