STM32 例程看门狗文档格式.docx
- 文档编号:17830712
- 上传时间:2022-12-11
- 格式:DOCX
- 页数:15
- 大小:1,008.89KB
STM32 例程看门狗文档格式.docx
《STM32 例程看门狗文档格式.docx》由会员分享,可在线阅读,更多相关《STM32 例程看门狗文档格式.docx(15页珍藏版)》请在冰豆网上搜索。
一旦启动独立看门狗,就不能停止(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();
//使能看门狗
/*-------------------------------------------------
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- STM32 例程看门狗 例程 看门狗