STM32 例程看门狗文档格式.docx

上传人:b****4 文档编号:17830712 上传时间:2022-12-11 格式:DOCX 页数:15 大小:1,008.89KB
下载 相关 举报
STM32 例程看门狗文档格式.docx_第1页
第1页 / 共15页
STM32 例程看门狗文档格式.docx_第2页
第2页 / 共15页
STM32 例程看门狗文档格式.docx_第3页
第3页 / 共15页
STM32 例程看门狗文档格式.docx_第4页
第4页 / 共15页
STM32 例程看门狗文档格式.docx_第5页
第5页 / 共15页
点击查看更多>>
下载资源
资源描述

STM32 例程看门狗文档格式.docx

《STM32 例程看门狗文档格式.docx》由会员分享,可在线阅读,更多相关《STM32 例程看门狗文档格式.docx(15页珍藏版)》请在冰豆网上搜索。

STM32 例程看门狗文档格式.docx

一旦启动独立看门狗,就不能停止(LSI也不能被禁止);

看门狗被激活后,则在计数器计数至0x000时产生复位;

在电源稳定期间,即使系统进入STOP和STANDBY模式,独立看门狗复位能将系统从STANDBY模式唤醒。

最适合应用于要求看门狗运行时,完全独立与主应用之外的项目

[编辑]硬件电路分析:

这里的核心是在STM32内部进行,并不需要外部电路。

但是考虑到指示当前状态和喂狗等操作,我们需要2个IO口,一个用来输入喂狗信号,另外一个用来指示程序是否重启。

喂狗我们采用板上的WAKEUP键来操作,而程序重启,则是通过LED4来指示的。

LED4和WAKEUP的连接在前面跑马灯实验已经介绍了,这里我们不再多说.

.

STM32的独立看门狗由内部专门的40Khz低速时钟驱动,即使主时钟发生故障,它也仍然有效。

这里需要注意独立看门狗的时钟并不是准确的40Khz,而是在30~60Khz之间变化的一个时钟,只是我们在估算的时候,以40Khz的频率来计算,看门狗对时间的要求不是很精确,所以,时钟有些偏差,都是可以接受的。

通过对LSI进行校准可获得相对精确的看门狗超时时间。

有关LSI校准的问题,详见数据手册LSI时钟一节。

IWDG的功能框图如上所示。

可以看出,IWDG主要由4个寄存器控制。

Prescalerregister:

预分频寄存器

Statusregister:

状态寄存器

Reloadregister:

重装载寄存器

KeyRegister:

键值寄存器

IWDG的工作流程如下:

40KHz的LSI时钟信号发送至8位预分频器进行分频,分频后的时钟信号发送至12位的递减计数器,重装载寄存器把12位的重装载数值发送至递减计数器,如果12位的递减计数器没有得到12位的重装载数值,当计数减至0x000时IWDG则复位

具体的寄存器的使用和特点见下。

IWDG寄存器介绍:

IWDG寄存器结构,IWDG_TypeDeff,在文件“stm32f10x_map.h”中定义如下:

typedefstruct

{

vu32KR;

//KeyRegister键值寄存器

vu32PR;

//Prescalerregister预分频寄存器

vu32RLR;

//Reloadregiste重装载寄存器

vu32SR;

//Statusregister状态寄存器

}IWDG_TypeDef;

IWDG外设声明于文件“stm32f10x_map.h”:

#definePERIPH_BASE((u32)0x40000000)

#defineAPB1PERIPH_BASEPERIPH_BASE

#defineAPB2PERIPH_BASE(PERIPH_BASE+0x10000)

#defineAHBPERIPH_BASE(PERIPH_BASE+0x20000)

#defineIWDG_BASE(APB1PERIPH_BASE+0x3000)

#ifndefDEBUG

...

#ifdef_IWDG

#defineIWDG((IWDG_TypeDef*)IWDG_BASE)

#endif/*_IWDG*/

#else/*DEBUG*/

EXTIWDG_TypeDef*IWDG;

#endif

为了访问IWDG寄存器,_IWDG必须在文件“stm32f10x_conf.h”中定义如下:

#define_IWDG

[编辑]键寄存器(IWDG_KR)

.

位31:

16保留,始终读为0。

位15:

0KEY[15:

0]:

键值(只写寄存器,读出值为0x0000)(Keyvalue)

软件必须以一定的间隔写入0xAAAA,否则,当计数器为0时,看门狗会产生复位。

写入0x5555表示允许访问IWDG_PR和IWDG_RLR寄存器。

写入0xCCCC,启动看门狗工作(若选择了硬件看门狗则不受此命令字限制)。

在WDG_KR中写入0xCCCC,开始启用独立看门狗;

此时计数器开始从其复位值0xFFF递减计数。

当计数器计数到末尾0x000时,会产生一个复位信号(IWDG_RESET)。

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

IWDG_PR和IWDG_RLR寄存器具有写保护功能。

要修改这两个寄存器的值,必须先向IWDG_KR寄存器中写入0x5555。

以不同的值写入这个寄存器将会打乱操作顺序,寄存器将重新被保护。

重装载操作(即写入0xAAAA)也会启动写保护功能。

对于寄存器的典型值,在stm32f10x.h中有如下定义

#defineIWDG_WriteAccess_Enable((uint16_t)0x5555)

#defineIWDG_WriteAccess_Disable((uint16_t)0x0000)

 

[编辑]预分频寄存器(IWDG_PR)

预分频寄存器(IWDG_PR),该寄存器用来设置看门狗时钟的分频系数,最低为4,最高位256,该寄存器是一个32位的寄存器,但是我们只用了最低3位,其他都是保留位。

预分频寄存器各位定义如下:

3保留,始终读为0。

位2:

0PR[2:

预分频因子(Prescalerdivider)这些位具有写保护设置.

通过设置这些位来选择计数器时钟的预分频因子。

要改变预分频因子,IWDG_SR寄存器的PVU位必须为0。

000:

预分频因子=4

001:

预分频因子=8

010:

预分频因子=16

011:

预分频因子=32

100:

预分频因子=64

101:

预分频因子=128

110:

预分频因子=256

111:

注意:

对此寄存器进行读操作,将从VDD电压域返回预分频值。

如果写操作正在进行,则读回的值可能是无效的。

因此,只有当IWDG_SR寄存器的PVU位为0时,读出的值才有效。

预分频值的设定,在stm32f10x.h中有如下定义

#defineIWDG_Prescaler_4((uint8_t)0x00)

#defineIWDG_Prescaler_8((uint8_t)0x01)

#defineIWDG_Prescaler_16((uint8_t)0x02)

#defineIWDG_Prescaler_32((uint8_t)0x03)

#defineIWDG_Prescaler_64((uint8_t)0x04)

#defineIWDG_Prescaler_128((uint8_t)0x05)

#defineIWDG_Prescaler_256((uint8_t)0x06)

[编辑]重装载寄存器(IWDG_RLR)

在介绍完IWDG_PR之后,我们介绍一下重装载寄存器。

该寄存器用来保存重装载到计数器中的值。

该寄存器也是一个32位寄存器,但是只有低12位是有效的,该寄存器的各位描述如下:

12保留,始终读为0。

位11:

0RL[11:

看门狗计数器重装载值(Watchdogcounterreloadvalue)这些位具有写保护功能。

用于定义看门狗计数器的重装载值,每当向IWDG_KR寄存器写入0xAAAA时,重装载值会被传送到计数器中。

随后计数器从这个值开始递减计数。

看门狗超时周期可通过此重装载值和时钟预分频值来计算。

只有当IWDG_SR寄存器中的RVU位为0时,才能对此寄存器进行修改。

注:

因此,只有当IWDG_SR寄存器的RVU位为0时,读出的值才有效。

[编辑]状态寄存器(IWDG_SR)

2保留。

位1RVU:

看门狗计数器重装载值更新(Watchdogcounterreloadvalueupdate)此位由硬件置’1’用来指示重装载值的更新正在进行中。

当在VDD域中的重装载更新结束后,此位由硬件清’0’(最多需5个40kHz的RC周期)。

重装载值只有在RVU位被清’0’后才可更新。

位0PVU:

看门狗预分频值更新(Watchdogprescalervalueupdate)此位由硬件置’1’用来指示预分频值的更新正在进行中。

当在VDD域中的预分频值更新结束后,此位由硬件清’0’(最多需5个40kHz的RC周期)。

预分频值只有在PVU位被清’0’后才可更新。

[编辑]IWDG寄存器映像

IWDG寄存器映像和复位值

有关寄存器的起始地址,参见数据手册.

[编辑]程序分析

[编辑]固件库库函数分析:

IWDG的库函数如下所示:

[编辑]函数IWDG_WriteAccessCmd

IWDG_WriteAccess

该参数使能或者失能对寄存器IWDG_PR和IWDG_RLR的写操作

函数原型如下:

voidIWDG_WriteAccessCmd(uint16_tIWDG_WriteAccess)

{

/*Checktheparameters*/

assert_param(IS_IWDG_WRITE_ACCESS(IWDG_WriteAccess));

IWDG->

KR=IWDG_WriteAccess;

}

可以看出,该函数的作用就是把输入参数传递到IWDG_KR中去.

在stm32f10x.h中我们找到输入参数的定义,如下所示

#defineIS_IWDG_WRITE_ACCESS(ACCESS)(((ACCESS)==IWDG_WriteAccess_Enable)||\

((ACCESS)==IWDG_WriteAccess_Disable))

由硬件分析可知,写入0x5555表示允许访问IWDG_PR和IWDG_RLR寄存器。

重装载操作(即使写入0xAAAA)也会启动写保护功能。

所以IWDG_WriteAccess_Enable和IWDG_WriteAccess_Disable的含义与字面含义不同,作用分别为使能和失能IWDG_PR和RWDG_RLR的写操作.

IWDG_WriteAccessCmd(IWDG_WriteAccess_Enable);

//关闭IWDG_PR和IWDG_RLR的写保护

IWDG_WriteAccessCmd(IWDG_WriteAccess_Disable);

//打开IWDG_PR和IWDG_RLR的写保护

[编辑]函数IWDG_SetPrescaler

IWDG_Prescaler

该参数设置了IWDG的预分频值

这些参数被定义在stm32f10x.h中.

1.defineIWDG_Prescaler_4((uint8_t)0x00)

2.defineIWDG_Prescaler_8((uint8_t)0x01)

3.defineIWDG_Prescaler_16((uint8_t)0x02)

4.defineIWDG_Prescaler_32((uint8_t)0x03)

5.defineIWDG_Prescaler_64((uint8_t)0x04)

6.defineIWDG_Prescaler_128((uint8_t)0x05)

7.defineIWDG_Prescaler_256((uint8_t)0x06)

详见硬件分析中的预分频寄存器.

voidIWDG_SetPrescaler(uint8_tIWDG_Prescaler)

assert_param(IS_IWDG_PRESCALER(IWDG_Prescaler));

PR=IWDG_Prescaler;

可以看出该函数的作用也仅仅为把IWDG_Prescaler的值传递至预分频寄存器中.

使用方法,例如:

/*设置预分频为8分频*/

IWDG_SetPrescaler(IWDG_Prescaler_8);

[编辑]函数IWDG_SetReload

voidIWDG_SetReload(uint16_tReload)

assert_param(IS_IWDG_RELOAD(Reload));

RLR=Reload;

如上面的函数一样,该函数的作用一样简单清晰,仅仅为把需要设定的重装载值传递到IWDG_RLR寄存器中.

喂狗时间(单位ms)=(预分频系数/4)*0.1*RLR(重装载值)

比如,我想达到喂狗时间越为1S的效果,为此我们选择32分频,带入计算可得

1000=(32/4)*0.1*RLR

RLR=1000/(32/4*0.1)=1250=0x4E2

即当设置了预分频为32后,我们使用IWDG_SetReload(0x4E2);

后,喂狗时间约为1S

实际上,喂狗时间不可能无穷大,或者无穷小。

下图为看门狗超时时间:

[编辑]函数IWDG_ReloadCounter

/*喂狗*/

IWDG_ReloadCounter();

该函数原型为

voidIWDG_ReloadCounter(void)

KR=KR_KEY_Reload;

在stm32f10x.c中我们可以找到以下的定义

#defineKR_KEY_Reload((uint16_t)0xAAAA)//初始的喂狗值,格段时间喂一次

KR_KEY_Reload的值为0xAAA,对照着函数代码可知,该函数的作用仅仅是向IWDG_KR中传输0xAAA,由上面的寄存器分析可知,向KR寄存器写入0XAAA后,IWDG_RLR中的值就会被重新加载到计数器中从而避免产生看门狗复位。

这个也就是我们说的喂狗操作.

[编辑]函数IWDG_Enable

该函数的原型如下:

voidIWDG_Enable(void)

KR=KR_KEY_Enable;

和上个函数相同,该函数的作用为向IWDG_KR中写入KR_KEY_Enable的值.

我们可以在stm32f10x.c中找出KR_KEY_Enable的定义

#defineKR_KEY_Enable((uint16_t)0xCCCC)

通过硬件分析中的KR寄存器分析可知,向IWDG_KR中写入0xCCCC的效果为启用看门狗.

直接调用这个函数就可以启用看门狗.

[编辑]函数IWDG_GetFlagStatus

该函数原型如下:

FlagStatusIWDG_GetFlagStatus(uint16_tIWDG_FLAG)

FlagStatusbitstatus=RESET;

assert_param(IS_IWDG_FLAG(IWDG_FLAG));

if((IWDG->

SR&

IWDG_FLAG)!

=(uint32_t)RESET)

{

bitstatus=SET;

}

else

bitstatus=RESET;

/*Returntheflagstatus*/

returnbitstatus;

在stm32f10x.h中有如下定义:

typedefenum{RESET=0,SET=!

RESET}FlagStatus,ITStatus;

可以看出RESET和SET的值分别为0,1.

由此可以看出,该函数的作用为,通过读取IWDG_SR寄存器的相应位,来检测IWDG当前的的状态,并返回。

详见上面状态寄存器(IWDG_SR)介绍.

[编辑]程序设计简要分析:

看门狗是定时器的一种,一般定时器的使用过程如下:

初始化定时器的设置。

包括工作方式等,并开启中断和计数功能。

2.启用寄存器后,经过一定的耗时,如果在定时器溢出之前没有刷新定时器的数值,则定时器将溢出,并申请中断。

3.定时器中断后执行相应的中断服务程序.

与一般定时器不同的是,看门狗溢出所对应的中断服务程序只须一条指令,即在中断向量地址写入"

无条件转移"

命令,把计算机拖回整个程序的第一行,对单片机重新进行初始化并获得正确的执行顺序

通过硬件分析可知,事实上我们只要三个寄存器进行相应的设置,就可以启动STM32的独立看门狗,启动过程可以按如下步骤实现:

1)向IWDG_KR写入0X5555。

通过这步,我们取消IWDG_PR和IWDG_RLR的写保护,使后面可以操作这两个寄存器。

设置IWDG_PR和IWDG_RLR的值。

这两步设置看门狗的分频系数,和重装载的值。

由此,就可以知道看门狗的喂狗时间,该时间的计算方式为:

Tout=40Khz/((4*2^prer)*rlr);

当然这个值是个粗略的计算值,因为时钟不准确,所以无法得到准确的喂狗时间。

2)向IWDG_KR写入0XAAAA。

通过这步操作,将使STM32重新加载IWDG_RLR的值到看门狗计数器里面。

也可以用该命令来喂狗。

向IWDG_KR写入0XCCCC通过这步操作,我们就可以启动STM32的看门狗。

如果一段时间内,不向IWDG_KR写入0XAAAA,则程序复位,调回整个程序的第一行.

[编辑]TB开发板LED程序流程图=

[编辑]TB开发板程序源代码:

Main.c

/*

*Jason

*jiangjj@emsym

**/

/*iwdg*/

#include"

stm32f10x.h"

stm32f10x_iwdg.h"

TB_LED.h"

TB_KEY.h"

voidiwdg_init();

voiddelay();

/*--------------------------------------------------------------------------------------------------

//函数名称:

intmain()

//入口参数:

//输出:

//函数功能:

主函数

--------------------------------------------------------------------------------------------------*/

intmain(void){

//初始化LED1和LED3

TB_LEDInit(LED1);

TB_LEDInit(LED3);

//立即熄灭LED3

TB_LEDOff(LED3);

//延时一段时间后,熄灭LED1

delay();

TB_LEDOff(LED1);

//初始化按键WAKEUP按键的中断

TB_PBInit(BUTTON_WAKEUP,BUTTON_MODE_EXTI);

//PA0

//初始化看门狗

iwdg_init();

while

(1);

return0;

voidiwdg_init()

初始化看门狗

voidiwdg_init(){

IWDG_WriteAccessCmd(IWDG_WriteAccess_Enable);

IWDG_SetReload(0xfff);

//设置重装载值为0xfff

IWDG_SetPrescaler(IWDG_Prescaler_32);

//设置预分频系数为32

//IWDG_ReloadCounter();

IWDG_Enable();

//使能看门狗

/*-------------------------------------------------

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 求职职场 > 简历

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1