STM32看门狗实验

独立看门狗实验

在由单片机构成的微型计算机系统中,由于单片机的工作常常会受到来自外界电磁场的干扰,造成程序的跑飞,而陷入死循环,程序的正常运行被打断,由单片机控制的系统无法继续工作,会造成整个系统的陷入停滞状态,发生不可预料的后果,所以出于对单片机运行状态进行实时监测的考虑,便产生了一种专门用于监测单片机程序运行状态的芯片,俗称"看门狗"。

建议:看门狗是定时器的一种,学习看门狗对于理解定时器有着借鉴作用

实验目的:

1.分析和学习固件库

2.理解固件库的结构

3.通过stm32f10x_iwdg.c/.h文件,熟悉IWDG(独立看门狗)的控制和工作原理

4.复习按键中断的使用方法

实验要求:

1.使用LED灯LED1来指示程序是否重启(IWDG)

2.使用按键WAKEUP来不断地喂狗,并用LED4灯指示

硬件分析:

看门狗原理:

看门狗又叫watchdogtimer(WDT),是一个定时器电路。

一个输入端:叫喂狗引脚;

一个输出端:连接到MCU的RESET引脚;

在系统运行以后,启动了看门狗的计数器,看门狗就开始自动计数;MCU正常工作时,每隔一段时间输出一个信号到喂狗端,将WDT清零;一旦单片机由于干扰造成程序跑飞后,而进入死循环状态时,在超过规定的时间内“喂狗”程序不能被执行,看门狗计数器就会溢出,从而引起看门狗中断,就会输出一个复位信号到MCU,造成系统复位。

在使用看门狗时,要注意适时喂狗。

STM32看门狗简介:

启动方式:

通过选项字设定:硬件或软件启动;

基本特色:

自由运行的递减计数器;

内部独立的低功耗时钟LSI提供时钟,即使主时钟失效,看门狗仍处于激活状态;

一旦启动独立看门狗,就不能停止(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*/

...

#ifdef_IWDG

EXTIWDG_TypeDef*IWDG;

#endif/*_IWDG*/

...

#endif

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

#define_IWDG

键寄存器(IWDG_KR)键寄存器(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)

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

位,其他都是保留位。预分频寄存器各位定义如下:

位31:3保留,始终读为0。

位2:0PR[2:0]:预分频因子(Prescalerdivider)这些位具有写保护设置.

通过设置这些位来选择计数器时钟的预分频因子。要改变预分频因子,IWDG_SR寄存器的PVU位必须为0。000:预分频因子=4

001:预分频因子=8

010:预分频因子=16

011:预分频因子=32

100:预分频因子=64

101:预分频因子=128

110:预分频因子=256

111:预分频因子=256

注意:对此寄存器进行读操作,将从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_RLR)

在介绍完IWDG_PR之后,我们介绍一下重装载寄存器。该寄存器用来保存重装载到计数器中的值。该寄存器也是一个32位寄存器,但是只有低12

位是有效的,该寄存器的各位描述如下:

位31:12保留,始终读为0。

位11:0RL[11:0]:

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

用于定义看门狗计数器的重装载值,每当向IWDG_KR寄存器写入0xAAAA时,重装载值会被传送到计数器中。随后计数器从这个值开始递减计数。看门狗超时周期可通过此重装载值和时钟预分频值来计算。只有当IWDG_SR寄存器中的RVU位为0时,才能对此寄存器进行修改。

注:对此寄存器进行读操作,将从VDD电压域返回预分频值。如果写操作正在进行,则读回的值可能是无效的。因此,只有当IWDG_SR寄存器的RVU位为0时,读出的值才有效。

(IWDG_SR)状态寄存器状态寄存器(IWDG_SR)

位31: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中我们找到输入参数的定义,如下所示

#defineIWDG_WriteAccess_Enable((uint16_t)0x5555)

#defineIWDG_WriteAccess_Disable((uint16_t)0x0000)

#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中.

#defineIWDG_Prescaler_4

#defineIWDG_Prescaler_8

#defineIWDG_Prescaler_16

#defineIWDG_Prescaler_32

#defineIWDG_Prescaler_64

#defineIWDG_Prescaler_128

#defineIWDG_Prescaler_256

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

函数原型如下:((uint8_t)0x00)((uint8_t)0x01)((uint8_t)0x02)((uint8_t)0x03)((uint8_t)0x04)((uint8_t)0x05)((uint8_t)0x06)

voidIWDG_SetPrescaler(uint8_tIWDG_Prescaler)

{

/*Checktheparameters*/

assert_param(IS_IWDG_PRESCALER(IWDG_Prescaler));

IWDG->PR=IWDG_Prescaler;

}

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

使用方法,例如:

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

IWDG_SetPrescaler(IWDG_Prescaler_8);

函数IWDG_SetReload

函数原型如下:

voidIWDG_SetReload(uint16_tReload)

{

/*Checktheparameters*/

assert_param(IS_IWDG_RELOAD(Reload));

IWDG->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)

{

IWDG->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)

{

IWDG->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_Enable

该函数原型如下:

FlagStatusIWDG_GetFlagStatus(uint16_tIWDG_FLAG)

{

FlagStatusbitstatus=RESET;

/*Checktheparameters*/

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)介绍.

程序设计简要分析:

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

1.初始化定时器的设置。包括工作方式等,并开启中断和计数功能。

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

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

与一般定时器不同的是,看门狗溢出所对应的中断服务程序只须一条指令,即在中断向量地址写入"无条件转移"命令,把计算机拖回整个程序的第一行,对单片机重新进行初始化并获得正确的执行顺序

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

IWDG_KR写入0X5555。1)向)向IWDG_KRIWDG_KR写入写入0X55550X5555。

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

设置IWDG_PR和IWDG_RLR的值。

这两步设置看门狗的分频系数,和重装载的值。由此,就可以知道看门狗的喂狗时间,该时间的计算方式为:Tout=40Khz/((4*2^prer)*rlr);当然这个值是个粗略的计算值,因为时钟不准确,所以无法得到准确的喂狗时间。

2)向IWDG_KR写入0XAAAA。

通过这步操作,将使STM32重新加载IWDG_RLR的值到看门狗计数器里面。也可以用该命令来喂狗。

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

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

TB开发板LED程序流程图

TB开发板程序源代码:

Main.c

/*

*Jason

*jiangjj@emsym

**/

/*iwdg*/

#include"stm32f10x.h"

#include"stm32f10x_iwdg.h"

#include"TB_LED.h"

#include"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_PR和IWDG_RLR的写保护IWDG_SetReload(0xfff);//设置重装载值为0xfff

IWDG_SetPrescaler(IWDG_Prescaler_32);//设置预分频系数为32

IWDG_ReloadCounter();

IWDG_Enable();//使能看门狗//

}

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

//函数名称:voiddelay()

//入口参数:无

//输出:无

//函数功能:延时函数

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

voiddelay()

{

uint32_ti=0xfffff;

for(;i>0;i--);

}

中断服务程序

voidEXTI0_IRQHandler(void)

{

//while(1);

TB_LEDOn(LED3);

IWDG_ReloadCounter();

TB_PBClearInterrupt(BUTTON_WAKEUP);delay();

TB_LEDOff(LED3);

}//使LED3亮,可以证明成功进入了中断//把重装载值写入看门狗中,俗称喂狗//清除按键的中断标志位//延时一段时间//使LED3灭,表示退出了中断服务程序


相关文章

  • 20**年南邮毕业设计选题
  • 南京邮电大学高等教育自学考试(专接本) 毕业设计选题范围 毕 业 设 计 题 目 题目1:简易电子称设计 指导教师:薛波(江苏理工学院) 要求: 研究并设计一个由单片机控制的电子称,包括单片机主控电路.电源电路.信号放大电路.A/D转换电路.LCD显示电路.按键电路以及报警电路. 1.独立电源:+5 ...

  • 大学生创新创业训练项目研究报告
  • 河北大学工商学院 大学生创新创业训练项目研究报告 题目: 项目编号 学 部 信息科学与工程学部 年级专业 2012级自动化 负 责 人 主要成员 指导教师 2015年1月14日 四轴飞行器系统的研究与制作 一. 摘 要 本设计实现基于STM32开发板的X字形四旋翼飞行器,四旋翼由主控制板.陀螺仪.电 ...

  • 1 扫描隧道显微镜(STM)
  • 1 扫描隧道显微镜(STM ) 扫描隧道显微镜(STM )的基本原理是利用量子理论中的隧道效应 .将原子线度的极细探针和被研究物质的表面作为两个电极,当样品与针尖的距离非常接近时(通常小于1nm ),在外加电场的作用下,电子会穿过两个电极之间的势垒流向另一电极 .这种现象即是隧道效应.隧道电流 I ...

  • 音频信号分析仪
  • 音频信号分析仪 指导老师:邓晶 年纪专业:11信息工程 成员: 刘丽梅(1128401039) 东飞(1128401014) 罗兰(1128401128) 日期:2014年6月 摘 要:本音频信号分析仪基于快速傅里叶变换的原理,以32位CPU STM32构成的最小系统为控制核心,由电压跟随.程控放大 ...

  • 自动走迷宫对抗机器人(攻方)简介
  • 自动走迷宫对抗机器人的设计(攻方) 自动化 12220217 冉旭升 指导教师:潘峥嵘 教授 摘要 本文设计了以STM32F103单片机为核心的自动走迷宫对抗机器人系统,包括了传感器信息的采集与处理.电机驱动.走迷宫的算法及控制策略等方面.采用激光传感器采集道路信息并反馈给单片机控制系统.通过设置S ...

  • SDH设备光传输距离计算指导
  • ZXMP-S360/S380/S390 本部用服部 光传输距离计算指导 安全/保密警告 文件信息和修改信息 目录 传输距离受限的理论分析及计算方法 . .......................................................................... ...

  • 扫描隧道显微镜在微电子方面的应用及其研究进展
  • 扫描隧道显微镜在微电子方面的应用及其研究进展 摘要:微电子技术的发展为我们的生活带来了很大的便利,然而关于微电子产品 的测试又对人类现有的技术提出了挑战,本文主要讲述了扫描隧道显微镜的原理.最新研究进展以及其在微电子等行业的应用. 关键字:扫描隧道显微镜,隧道电流,电子阱,自旋化扫描隧道显微镜. 一 ...

  • 研究内容和主要技术
  • 研究内容和主要技术.主要创新点: (1)针对现有 3D 打印输出误差较大的问题,在打印输出驱动控制方面做了研究工作,研究步进电机细分驱动控制,在设计中选用 A3979 (步进驱动芯片)为主要驱动芯片搭建了硬件电路.在打印输出算法方面研究一种合理算法,将点离散态有序抖动算法运用到 3D 打印系统中. ...

  • 两轮自平衡小车毕业设计04161120
  • 两轮自平衡小车的设计 摘要 最近这几年来,自平衡电动车的研发与商用获得了快速发展.自平衡车具有 体积小,运动十分灵活,便利,节能等特点.本文提出了一种双轮自平衡小车的设计方案,机械结构采用了双轮双马达驱动:控制主要采用的是反馈调节,为了使车体更好的平衡,使用了PID调节方式:硬件上采用陀螺仪GY52 ...

© 2024 范文中心 | 联系我们 webmaster# onjobs.com.cn