历史上的今天
返回首页

历史上的今天

今天是:2024年11月08日(星期五)

正在发生

2021年11月08日 | stm32f10x独立看门狗

2021-11-08 来源:eefocus

一、IWDG介绍

1.1、独立看门狗简介

STM21F1芯片内部含有两个看门狗外设,独立看门狗(IWDG)与窗口看门狗(WWDG)。

两个看门狗都可以用于检测并解决由软件错误导致的故障。

独立看门狗可以简单的理解为一个12位的递减计数器,当计数器从某个值递减到0时(如果看门狗已激活),那么系统会产生一次复位。

如果在计数器递减到0之前刷新了计数器值,那么系统就不会产生复位。

这个刷新计数器值得过程称为“喂狗”。

独立看门狗功能由VDD电压域供电,在停止模式和待机模式下仍能工作。


1.2、IWDG结构框图

LSI:内部低速时钟,频率约在30~60KHz之间   仅适用于时间精度较低的场合,即便在主时钟发生 故障时仍然保持工作状态。


8 位预分频寄存器 IWDG_PR :LSI 时钟并不是直接提供给计数器时钟,而是通过一个 8 位预分频寄存器 IWDG_PR 分频后输入给计数器时钟。操作 IWDG_PR 寄存器来设置分频因子。8位预处理器(寄存器):分频因子有2,4,8,16,32,64,128,256。分频后的计数器时钟为:CK_CNT= 40/ 4*2^PRE,PRE 为预分频系数(0-6),4*2^PRE 大小就是 4、8、16、32、64、128、256 值。每经过一个计数器时钟, 计数器就减 1。

12位递减计数器:独立看门狗的计数器是一个 12 位的递减计数器,计数最大值为 0XFFF,当递减到 0 时,会产生一个复位信号,让系统重新启动运行,如果在计数器减到 0

之前刷新了计数器值的话,就不会产生复位信号,这个刷新计数器值过程称 之为“喂狗”。


12位  重加载数值:重装载寄存器是一个 12 位的寄存器,里面装着要刷新到计数器的值,这个值的大小决定着独立看门狗的溢出时间。溢出时间 Tout = (4*2^pre) / 40 * rlr

(ms), pre 是预分频器系数(0-6),rlr 是重装载寄存器的值,公式内的 40 是 独立看门狗的时钟。 比如设置 pre=4,rlr=800,那么独立看门狗溢出时间是 1280ms,也就是说

如果在 1280ms 内没有进行喂狗,那么系统将进行重启,即程序重新开始运行

键寄存器(IWDG_KR)又称关键字寄存器或密钥寄存器(IWDG_KR)。此寄存器可以说 是 IWDG 的一个控制寄存器。往该寄存器写入三种值会有三种控制效果:

①写入 0X5555,由于 IWDG_PR 和 IWDG_RLR 寄存器具有写访问保护。若要 修改寄存器,必须首先对 IWDG_KR 寄存器写入代码 0x5555。若写入其他值将重 启写保护。

②写入 0XAAAA,把 IWDG_RLR 寄存器内值重装载到计数器中。


③写入 0XCCCC,启动 IWDG 功能。此方式属于软件启动,一旦开启独立看门 狗,它就关不掉,只有复位才能关掉IWDG的控制寄存器    

状态寄存器 IWDG_SR 只有位 0: PVU 和位 1: RVU 有效,这两位只能由硬件操作。RVU:看门狗计数器重装载值更新,硬件置 1 表示重装载值的更新正在进行中,更新完毕之后由硬件清 0。 PVU: 看门狗预分频值更新,硬件置 1 表示预分频值的更新正在进行中,当更新完成后,由硬件清 0。所以只有当 RVU/PVU 等于 0 的时候才可以更新重装载寄存器/预分频寄存器

二、IWDG配置

独立看门有自己的时钟LSI(内部低速时钟),不存在使能问题,但固件库还是提供LSI的使能函数

RCC_LSICmd(ENABLE); // 

while(RCC_GetFlagStatus(RCC_FLAG_LSIRDY)==0){} // 复位LSE振荡器时钟

/**

  * @brief  Enables or disables the Internal Low Speed oscillator 振荡器(LSI).                                           使能或失能内部低速时钟

  * @note   LSI can not be disabled if the IWDG is running.                                                                        注意:当IWDG处于运行状态时,无法禁用LSI。

  * @param  NewState: new state of the LSI. This parameter can be: ENABLE or DISABLE.

  * @retval None

  */

void RCC_LSICmd(FunctionalState NewState)

{

  /* Check the parameters */

  assert_param(IS_FUNCTIONAL_STATE(NewState));

  *(__IO uint32_t *) CSR_LSION_BB = (uint32_t)NewState;

}


内部低速时钟开启为的别名地址


#define CSR_LSION_BB              (PERIPH_BB_BASE + (CSR_OFFSET * 32) + (LSION_BitNumber * 4))


#define PERIPH_BB_BASE        ((uint32_t)0x42000000) /*!< Peripheral base address in the bit-band region */   位带区域内的外围基地地址


#define CSR_OFFSET                (RCC_OFFSET + 0x24)


/* ------------ RCC registers bit address in the alias region ----------- */    RCC在别名区域寄存器位地址

#define RCC_OFFSET                (RCC_BASE - PERIPH_BASE)


#define LSION_BitNumber           0x00


(1)IWDG相关库函数在stm32f10x_iwdg.c和stm32f10x_iwdg.h文件中 

  开启寄存器访问(给IWDG_KP寄存器写入0x5555)

IWDG_WriteAccesscmd(IWDG_WriteAccess_Enable); // 取消寄存器写保护

/**

  * @brief  Enables or disables write access to IWDG_PR and IWDG_RLR registers.                                  失能或使能独立看门狗的预分频寄存器和独立看门狗重装载寄存器的写访问

  * @param  IWDG_WriteAccess: new state of write access to IWDG_PR and IWDG_RLR registers.          独立看门狗的预分频寄存器与独立看门狗重装载寄存器 写访问的新状态

  *   This parameter can be one of the following values:

  *     @arg IWDG_WriteAccess_Enable: Enable write access to IWDG_PR and IWDG_RLR registers         

  *     @arg IWDG_WriteAccess_Disable: Disable write access to IWDG_PR and IWDG_RLR registers

  * @retval None

  */

void IWDG_WriteAccessCmd(uint16_t IWDG_WriteAccess)

{

  /* Check the parameters */

  assert_param(IS_IWDG_WRITE_ACCESS(IWDG_WriteAccess));           assert_param宏 拥有检测函数的参数

  IWDG->KR = IWDG_WriteAccess;                                                              IWDG的KR(健存寄存器) 的0~15位写入0x5555 (0101 0101 0101 0101)   表示允许操作IWDG_PR与IWDG_RLR  即取消寄存器写保护           

}


#define IWDG_WriteAccess_Enable     ((uint16_t)0x5555)                 //  取消写保护

#define IWDG_WriteAccess_Disable    ((uint16_t)0x0000)                 //  写保护

#define IS_IWDG_WRITE_ACCESS(ACCESS) (((ACCESS) == IWDG_WriteAccess_Enable) ||

                                      ((ACCESS) == IWDG_WriteAccess_Disable))


(2)设置IWDG预分频系数和重装载值

void IWDG_SetPrescaler(uint8_t IWDG_Prescaler )       // 设置预分频的值

 

void IWDG_SetReload(uint16_t Reload);  // 设置重装载的值

 

Tout =(4*2^pre)/40*rlr

 

Tout独立看门狗的溢出时间,单位:ms。pre是预分频系数(0-6),rlr是重装载寄存器的值,

公式内的40是独立看门狗的时钟。

比如设置 pre=4,rlr=800,那么独立看门狗溢出时间是 1280ms,

只要在 1280ms 之内,有一次写入 0XAAAA 到 IWDG_KR,就不会导致看门狗复位   

看门狗的时钟不是准确的40Khz,所以在喂狗的时候,最好不要太晚了,否则,有可能发生看门狗复位

/**

  * @brief  Sets IWDG Prescaler value.                                                    设置预分频寄存器的值

  * @param  IWDG_Prescaler: specifies the IWDG Prescaler value.

  *   This parameter can be one of the following values:                         4     8     16      32      64    128     256

  *     @arg IWDG_Prescaler_4: IWDG prescaler set to 4

  *     @arg IWDG_Prescaler_8: IWDG prescaler set to 8

  *     @arg IWDG_Prescaler_16: IWDG prescaler set to 16

  *     @arg IWDG_Prescaler_32: IWDG prescaler set to 32

  *     @arg IWDG_Prescaler_64: IWDG prescaler set to 64

  *     @arg IWDG_Prescaler_128: IWDG prescaler set to 128

  *     @arg IWDG_Prescaler_256: IWDG prescaler set to 256

  * @retval None

  */


void IWDG_SetPrescaler(uint8_t IWDG_Prescaler)

{

  /* Check the parameters */

  assert_param(IS_IWDG_PRESCALER(IWDG_Prescaler));

  IWDG->PR = IWDG_Prescaler;                                                                预分频寄存器

}


/**

  * @brief  Sets IWDG Reload value.                                               独立看门狗重装载的值

  * @param  Reload: specifies the IWDG Reload value.                 设置独立看门狗重装载的值

  *   This parameter must be a number between 0 and 0x0FFF.     参数的取值范围0 ~ 0x0FFF

  * @retval None

  */

void IWDG_SetReload(uint16_t Reload)

{

  /* Check the parameters */

  assert_param(IS_IWDG_RELOAD(Reload));

  IWDG->RLR = Reload;

}


(3)重载计数器值(喂狗)给IWDG_KR寄存器写入0xAAAA

IWDG_ReloadCounter();

/**

  * @brief  Reloads IWDG counter with value defined in the reload register

  *   (write access to IWDG_PR and IWDG_RLR registers disabled).

  * @param  None

  * @retval None

  */

void IWDG_ReloadCounter(void)

{

  IWDG->KR = KR_KEY_Reload;

}


/* KR register bit mask */

#define KR_KEY_Reload    ((uint16_t)0xAAAA)       

#define KR_KEY_Enable    ((uint16_t)0xCCCC)


(4)开启IWDG(给IWDG_KR寄存器写入0xCCCC)

IWDG_Enable();

/**

  * @brief  Enables IWDG (write access to IWDG_PR and IWDG_RLR registers disabled).

  * @param  None

  * @retval None

  */

void IWDG_Enable(void)

{

  IWDG->KR = KR_KEY_Enable;

}


四、编写独立看门狗

通过 KEY_UP 按键进行喂狗,喂狗的时候 DS1 点亮, 同时串口输出“喂狗”提示信息,超过喂狗时间系统重启 DS1 熄灭,同时串口输 出“复位系统”提示信息,同时使用 DS0 指示灯闪烁表示系统运行编写看门狗例子1

#include "iwdg.h"

 

/*******************************************************************************

* 函 数 名         : IWDG_Init

* 函数功能    : IWDG初始化

* 输    入         : pre:预分频系数(0-6)

rlr:重装载值(12位范围0xfff)

独立看门狗复位时间计算公式:t=(4*2^pre*rlr)/40

* 输    出         : 无

*******************************************************************************/

void IWDG_Init(u8 pre,u16 rlr)

{

IWDG_WriteAccessCmd(IWDG_WriteAccess_Enable); //取消寄存器写保护

IWDG_SetPrescaler(pre);//设置预分频系数 0-6

IWDG_SetReload(rlr);//设置重装载值

IWDG_ReloadCounter();  //重装载初值

IWDG_Enable(); //打开独立看门狗

}

 

/*******************************************************************************

* 函 数 名         : IWDG_FeedDog

* 函数功能    : 喂狗

* 输    入         : 无

* 输    出         : 无

*******************************************************************************/

void IWDG_FeedDog(void)  //喂狗

{

IWDG_ReloadCounter();  //重装载初值

}

 

头文件


#ifndef _iwdg_H

#define _iwdg_H

 

#include "system.h"

void IWDG_Init(u8 pre,u16 rlr);

void IWDG_FeedDog(void);  //喂狗

 

#endif

 

主函数


#include "system.h"

#include "SysTick.h"

推荐阅读

史海拾趣

COMPUTAR公司的发展小趣事

随着摄影和摄像技术的不断发展,市场对镜头性能的要求也越来越高。为了满足这一需求,CBC株式会社于1985年成功研制出第一款非球面高速镜头。这款镜头采用了先进的非球面设计,有效减少了像差和畸变,提高了成像质量。非球面高速镜头的诞生,不仅为CBC赢得了更多的市场份额,也为整个光学行业树立了新的技术标杆。

GSR Technology Ltd公司的发展小趣事

随着数字化时代的到来,GSR Technology Ltd积极响应国家关于数字经济发展的号召,开始推进企业的数字化转型。公司引入先进的智能制造技术,对生产线进行智能化改造,提高了生产效率和产品质量。同时,公司加强数据管理和分析,利用大数据和人工智能技术优化产品设计和生产流程。这一系列的数字化转型措施为公司带来了显著的经济效益和市场竞争力提升。

Hewlett Packard Co公司的发展小趣事
合理布线以减少信号干扰和噪声影响,提高音质表现。
HDK(北陆电气)公司的发展小趣事
合理布线以减少信号干扰和噪声影响,提高音质表现。
ABL Heatsink公司的发展小趣事

ABL Heatsink公司在电子散热领域一直默默耕耘,直到某天,公司的研发团队成功开发了一种新型的高效散热材料。这种材料不仅导热性能卓越,而且成本相对较低,立即引起了业界的关注。随着这种新型散热材料的广泛应用,ABL Heatsink公司的订单量激增,公司规模迅速扩大。

Fukushima Futaba Electric Co Ltd公司的发展小趣事

Fukushima Futaba Electric Co., Ltd.(以下简称“Futaba Electric”)的创立可以追溯到1948年,由熊本县出身的卫藤五郎和北海道出身的细矢礼二在千叶县共同创立。公司名“Futaba”取自两人故乡的首字,寓意着双叶的结合与协作。初期,Futaba Electric专注于电气设备的制造与研发,凭借创始人的远见卓识和不懈努力,逐渐在电子行业崭露头角。这一时期,公司主要生产基础的电气元件,如电阻器、电容器等,为后续的发展奠定了坚实的基础。

问答坊 | AI 解惑

ucos/2经典中文教程

我做毕业论文时导师给我的,很好的哦,跟大家分享一下.…

查看全部问答>

opc开发是遇到一个问题,请大家帮帮,在此先谢谢了

Set Server = New OPCServer ’生成OPC对象,     Servers = Server.GetOPCServers(\"\") Server.Connect sServerName, \"\" ’连接OPC服务器     Server.OPCGroups.DefaultGroupUpdateRate = 800’设定组的刷新速率   ...…

查看全部问答>

外部RAM问题

本帖最后由 dontium 于 2015-1-23 13:29 编辑 在一批2812的电路板焊好后,发现绝大部分板子程序不能LOAD到外部RAM,其原因可能是啥,是外部RAM坏吗,DSP坏. …

查看全部问答>

请教看程序大小

430烧入程序是text.d43吧 看程序的大小是用仿真器看程序的起始跟结束段吗? 还是看text.d43文件的大小呢? 或是其他办法…

查看全部问答>

常用模块电路集

一些常用模块的论述,大家学习下。…

查看全部问答>

uCOS-II的中文注释

这是我分享的一个uCOS-II的源代码中文注释的资料,很不错,希望对需要的人有所帮助,有些人传一些资料,还得售价,哎,一点共享贡献意识也没有啊 这个不是邵贝贝的,邵的那个我会传的,放心都是不要“钱”的…

查看全部问答>

浅谈MSP430 系列与89C51 系列的比较

我国的多数读者对89C51 系列的单片机是很熟悉的,为了加深对MSP430 系列单片机的认识,我们不妨将两者进行一下比较。 描述:MSP430VS AT89C51 图片:MSP430VS AT89C51 .jpg 首先, 89C51 单片机是8 位     单片机。其指 ...…

查看全部问答>

12864在画波形时清屏特慢

做了一个12864驱动的心跳监测系统,每次扫过128位后清屏,要用近1秒才能完成,请高手指教一下,你们是不是也碰上类似的问题?…

查看全部问答>

keil4的头文件有点迷糊~

#include \"inc/hw_ints.h\"和#include \"hw_ints.h\"有什么区别吗?为什么我的Keil的头文件里有#include \"inc/hw_ints.h\"但是在文件里没有找到#include \"inc/hw_ints.h\"。只有#include \"hw_ints.h\"。还有就是#include \"hw_ints.h\"和#inclu ...…

查看全部问答>