stm32f407关于独立看门狗各种函数(一)(HAL库)

以下内容全部来自正点原子,本人只是对主要知识点进行整理,方便以后查看。

一、独立看门狗

独立看门狗本质上是一个定时器,这个定时器有一个输出端,可以输出复位信号。该定时 器是一个 12 位的递减计数器,当计数器的值减到 0 的时候,就会产生一个复位信号。如果在计 数没减到 0 之前,重置计数器的值的话,那么就不会产生复位信号,这个动作我们称为喂狗。 看门狗功能由 VDD 电压域供电,在停止模式和待机模式下仍然可以工作。

STM32F407 的独立看门狗由内部专门的 32Khz 低速时钟(lsi_ck)驱动,即使主时钟发生故障,它也仍然有效。独立看门狗的时钟不是准确 的 32Khz,而是在 17~47Khz 之间的一个可变化的时钟,我们在估算的时候,以 32Khz 的 频率来计算,看门狗对时间的要求不是很精确,所以,时钟有些偏差,都是可以接受的。

二、独立看门狗寄存器

IWDG 主要用到其中 3 个寄存器:关键字寄存器(IWDG_KR)、预分频寄存器(IWDG_PR)和重载寄存器(IWDG_ RLR)。

2.1、关键字寄存器(IWDG_KR)

关键字寄存器可以看作是独立看门狗的控制寄存器

在键寄存器(IWDG_KR)中写入 0xCCCC,开始启用独立看门狗;此时计数器开始从其复位值 0xFFF 递减计数。当计数器计数到末尾 0x000 时,会产生一个复位信号(IWDG_RESET)。

无 论何时,只要关键字寄存器 IWDG_KR 中被写入 0xAAAA,IWDG_RLR 中的值就会被重新加 载到计数器中从而避免产生看门狗复位。

IWDG_PR 和 IWDG_RLR 寄存器具有写保护功能。要修改这两个寄存器的值,必须先向 IWDG_KR 寄存器中写入 0x5555。将其他值写入这个寄存器将会打乱操作顺序,寄存器将重新 被保护。重装载操作(即写入 0xAAAA)也会启动写保护功能。 

2.2、预分频寄存器(IWDG_PR)

 2.3、重载寄存器(IWDG_ RLR)

该寄存器用来保存重装载到计数器中的值。该寄存器也是一个 32 位寄存器,只有低 12 位 是有效的。

三、相关函数

IWDG 的初始化函数,其声明如下:

HAL_StatusTypeDef   HAL_IWDG_Init(IWDG_HandleTypeDef *hiwdg);

参数如下

typedef struct 
{
IWDG_TypeDef *Instance; /* IWDG 寄存器基地址 */ 
IWDG_InitTypeDef Init; /* IWDG 初始化参数 */ 
}IWDG_HandleTypeDef;

1)Instance:指向 IWDG 寄存器基地址。

2)Init:IWDG 初始化结构体,用于配置计数器的相关参数。

IWDG_InitTypeDef 这个结构体类型定义如下:

typedef struct
{
 uint32_t Prescaler; /* 预分频系数 */
 uint32_t Reload; /* 重装载值 */
} IWDG_InitTypeDef;

1)Prescaler:预分频系数,IWDG_PRESCALER_4 到 IWDG_PRESCALER_256。

2)Reload:重装载值,范围:0 到 0x0FFF。

HAL_IWDG_Refresh 函数是独立看门狗的喂狗函数。

HAL_StatusTypeDef     HAL_IWDG_Refresh(IWDG_HandleTypeDef *hiwdg);

函数返回值: HAL_StatusTypeDef 枚举类型的值。

独立看门狗配置步骤

1)取消寄存器写保护,通过函数 HAL_IWDG_Init 实现。

看门狗的喂狗时间(也就是看门狗溢 出时间)的计算方式为:

Tout=((4×2^prer) ×rlr) /32

其中 Tout 为看门狗溢出时间(单位为 ms)。

prer 为看门狗时钟预分频值(IWDG_PR 值),范围为 0~7。

rlr 为看门狗的重装载值(IWDG_RLR 的值)。

比如我们设定 prer 值为 4(因为4×2^4=64,所以 prer =4代表的是 64 分频,HAL 库中可以使用宏定义标识符 IWDG_PRESCALER_64),rlr 值为 500,那么就可以得到 Tout=64×500/32=1000ms,这样,看 门狗的溢出时间就是 1s,只要在一秒钟之内,有一次写入 0xAAAA 到 IWDG_KR,就不会导 致看门狗复位。

注:看门狗的时钟不是准确的 32Khz,最好不要太晚喂狗,否则,有可能发生看门狗复位。

2)重载计数值喂狗(向 IWDG_KR 写入 0xAAAA) 在 HAL 中重载计数值的函数是 HAL_IWDG_Refresh,把值 0xAAAA 写入 到 IWDG_KR 寄存器,从而触发计数器重载,即实现独立看门狗的喂狗操作。

3) 启动看门狗(向 IWDG_KR 写入 0xCCCC) HAL 库函数里面启动独立看门狗是通过宏定义标识符来实现的:

#define __HAL_IWDG_START(__HANDLE__) 
WRITE_REG((__HANDLE__)->Instance->KR, IWDG_KEY_ENABLE);

我们只需要调用宏定义标识符__HAL_IWDG_START 即可实现看门狗使能。实际上,当我 们调用了看门狗初始化函数 HAL_IWDG_Init 之后,在内部已经调用了该宏启动看门狗。

注:调用了看门狗初始化函数 HAL_IWDG_Init 之后,在内部会自动启动看门狗。

四、实战


#include "stm32f4xx.h"
#include "core_cm4.h"
#include "stm32f4xx_hal.h"
#include "stdio.h"

IWDG_HandleTypeDef g_iwdg_handle;
uint8_t keyval = 0;                         /* 保存按键状态 */ 

void KEY_int(void)
{
 
    GPIO_InitTypeDef gpio_init_struct;                      /* 定义结构体 */
   
    gpio_init_struct.Pin = GPIO_PIN_0;                     /* LED1引脚 */
    gpio_init_struct.Mode = GPIO_MODE_INPUT;                /* 输入 */
    gpio_init_struct.Pull = GPIO_PULLUP;                    /* 上拉 */
    gpio_init_struct.Speed = GPIO_SPEED_FREQ_HIGH;          /* 高速 */
 
    HAL_GPIO_Init(GPIOA, &gpio_init_struct);                /* 初始化KEY引脚 */
}

/* ↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓看门狗参数配置↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓ */
void iwdg_init(uint8_t prer, uint16_t rlr)
{
 g_iwdg_handle.Instance = IWDG;
 g_iwdg_handle.Init.Prescaler = prer; /* 设置 IWDG 分频系数 */
 g_iwdg_handle.Init.Reload = rlr;     /* 重装载值 */
 HAL_IWDG_Init(&g_iwdg_handle);
}

/* ↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓喂狗↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓ */
void iwdg_feed(void)
{ 
 HAL_IWDG_Refresh(&g_iwdg_handle); /* 重装载计数器 */
}

/* ↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓检测按键↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓ */
void key(void)
{ 
    if(keyval=1) keyval=0;
    if(HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_0)==0)
        {
            delay_ms(10);  /* 消抖 */
            if(HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_0)==0) keyval=1;
        } 
}

int main()
{
    HAL_Init();                             /* 初始化HAL库 */
    __HAL_RCC_GPIOA_CLK_ENABLE();           /* 端口A的时钟使能 */
    delay_init(168);                        /* 延时初始化 */
    KEY_init();                             /* 初始化LED */
    iwdg_init(IWDG_PRESCALER_64,500);
    keyval = 0;
    while(1)
        {
            key();
            if(keyval==1)
                {
                   iwdg_feed(); 
                }
            delay_ms(10);
        }
}

注:delay_ms(500);  在后面时钟才能学到,这里只是表示一下。

  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值