C8051F410看门狗的使用方法

8051F410看门狗的使用方法
一、 看门狗概念

  1. 看门狗产生复位的条件:
    通过 PCA 的模块 5 可以实现可编程看门狗定时器( WDT)功能。如果两次对 WDT 更新寄存器( PCA0CPH5)的写操作相隔的时间超过规定的极限, WDT 将产生一次复位。
  2. 使能/禁止WDT的软件实现方法:
    可以根据需要用软件配置(操作寄存器)来使能/禁止 WDT。
    当 PCA0MD 寄存器中的 WDTE 位被置 1 时,模块 5 被作为看门狗定时器( WDT)使用。WDTE = 1: PCA 模块 5 被用作看门狗定时器。
  3. 防止复位的方法:
    如果在 WDT 被使能时 PCA0CPH5 和 PCA0H 发生匹配,则系统将被复位。为了防止 WDT 复位,需要通过写 PCA0CPH5 来更新 WDT(写入值可以是任意值)。
    二、 看门狗定操作注意点
    a) 在系统复位后看门狗被使能。也就是一上电,系统默认是打开看门狗的。解析:这里要特别注意,一般项目中,全局变量一多的话,会导致启动文件初始化过程延长,结果就是程序重复重启,进入不了main函数,主程序执行不了,解决办法就是在启动文件里加入关闭看门狗的汇编语句。
    b) 在看门狗被使能时,对某些 PCA 寄存器的写操作受到限制。
    解析:这样的话,就需要在设置PCA 寄存器之前,先禁止看门狗功能,在设置完成以后,再使能看门狗功能。
    比如:
    PCA0MD &= ~0x40;
    PCA0L = 0x00;
    PCA0H = 0x00;
    PCA0CPL5 = 0xFF;
    PCA0MD |= 0x40;
    c) 在 WDT被使能的情况下,软件可以通过向 CCF5 标志( PCA0CN.2)写 1 来强制产生 WDT 复位。(做BootLoader的时候,可以使用此功能。)
    d) 当 WDT 被使能时,模块 5 被强制进入软件定时器方式。写 CR 位并不改变 PCA 计数器的状态;计数器将一直保持运行状态,直到 WDT 被禁止。如果 WDT 被使能,但用户软件没有使能 PCA 计数器,则读 PCA 运行控制( CR)位时将返回 0。(CR=0,禁止 PCA 计数器/定时器。)

三、 看门狗定时器,定时时间的计算方法。
a) 看门狗定时器的概念:
答:看门狗定时器时间一到,如果此刻没有喂狗动作的话,那系统就会复位,所以此定时器定时的值,是防止系统复位,两次喂狗之间的时间间隔。
b) 如何确定看门狗定时器的值。

  1. 先看看C8051F410手册,相关定时器的值,有哪些概念。手册中说,
    在WDT 被使能时,如果PCA0CPH5 和 PCA0H 发生匹配,则系统将被
    复位。因为PCA0H是计数器的高字节,PCA0CPH5是捕获模块的高字节。那可以这样理解,PCA0H是从0开始递增计数(一次+1),PCA0H的值一直增加到和PCA0CPH5的值一样的时候,就是定时器定时时间到了。

那下一步,如果我们要设置看门狗定时时长,就需要知道PCA0CPH5 和 PCA0H 的值。

PCA0H的值,可以给个初值,以后每过来一个PCA时钟周期,PCA0H的值就会加1。PCA0H的初值,一般给0。

手册中说到,为防止 WDT 复位,需要通过写 PCA0CPH5 来更新 WDT(写入值可以是任意值)。在写 PCA0CPH5 时, PCA0H 的值加上 PCA0CPL5 中保存偏移值后被装入到 PCA0CPH5(见图 25.10)。

这句话的意思是,为防止 WDT 复位,可以给PCA0CPH5写任何值(可以写0x00),比如我给PCA0CPH5 写个A值,在给PCA0CPH5写A值的时候,PCA0H寄存器里的值(B)加上 PCA0CPL5寄存器里的值©会被装入到PCA0CPH5.也就是B+C的值会影响到看门狗定时时间,PCA0CPH5写A值,只是一个动作,表示它要开始装载定时时间(B+C)。这个A值和计算定时器定长时间没有任何关系。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

C). 看门狗定时器定时公式。
上图25.10的解析:
PCA0H 的值加上 PCA0CPL5 中保存的偏移值后被装入到 PCA0CPH5, 然后 PCA0CPH5与 PCA0H相比较,如果PCA0CPH5与PCA0H值相等,并且PCA0L的值溢出,则定时器定时时间到,此刻如果不喂狗,则会产生一次复位。
PCA0L是计数器的低位,它也是随PCA时钟周期递增加1, PCA0L第一次溢出周期取决于进行更新操作时 PCA0L 的初值,最长可达 256 (0-0xFF,8位0xFF)个 PCA 时钟。
所以看门狗定时器偏移值如方程25.4所示,所以看门狗定时器定时时长等于PCA时钟数×PCA周期=偏移值×PCA周期。
偏移值 = ( 256 × PCA0CPL5) + ( 256 - PCA0L )
方程25.4 看门狗定时器偏移值( PCA时钟数)

偏移值已确定,下面我们研究一下PCA周期。

PCA周期等于1 / PCA时钟频率,用户手册中,提供了PCA时钟源的选择表,也提供了看门狗定时器超时间隔表格(PCA时钟源对应的可定时超时间隔关系表)。用户可以根据需要,来选择自己需要的PCA时钟源。
比如系统时钟为24.5MHZ时,PCA时钟源可以选择12分频或者4分频,不同的PCA0CPL5值,那么超时间隔就可为4mS,16mS, 32mS。从表25.3可以看出,当系统时钟为24.5MHZ时,超时间隔最大为32.1ms,这并不能满足一些大的项目。解决的办法就是选择PCA源为定时器0,或者选择低的系统主频。选择低系统主频的办法是,将内部系统时钟分频,比如64分频,或者128分频,但是这样会影响项目中已有串口波特率,定时器的工作。还有一个办法就是就算超时间隔不大,我们也可以选择多次喂狗的办法,在有时延的地方喂狗,比如延时,flash操作,for循环处。
在这里插入图片描述
在这里插入图片描述

四、 总结:
是不是觉得上面说的很多,觉得很复杂,其实原理很简单,就是当捕获模块寄存器高字节与计数器寄存器高字节的值匹配的时候,并且计数器寄存器低字节溢出的时候,这就是复位时刻,这个时间长度就是定时器超时间隔。而捕获模块寄存器高字节的值=捕获模块寄存器高字节+计数器寄存器高字节初值。计数器寄存器低字节溢出时刻是256-PCA0L.
在这里插入图片描述

学习完是不是还算简单。就是计数器一边递增,一边检查是否匹配,值匹配,计数器低字节溢出后,就是定时时间间隔。
给大家个例程:

扫描二维码关注公众号,回复: 10066721 查看本文章
#include "C8051f410.h"

/*
  如果写入WDT更新寄存器(PCA0CPH5)之间的时间间隔超过指定的限制,则使用WDT产生复位。
  可以根据需要在软件中禁用和启用WDT。启用后,PCA模块5充当WDT。
  复位是由于WDT溢出引起的,可以通过检查RSTSRC寄存器的值(第3位为)来确认。
*/

/*
名称:  看门狗初始化
寄存器:
	CIDL = 1;    当系统控制器处于空闲方式时, PCA 停止工作。
	WDTE = 1:   PCA 模块 5 被用作看门狗定时器。
	WDLCK = 1;   锁定看门狗定时器使能位.WDLCK 被置 1 时,在发生下一次系统复位之前将不能禁止 WDT
	CPS2-CPS0:  PCA 计数器/定时器时钟选择,这些位选择 PCA 计数器的时钟源。 000:系统时钟的 12 分频
	ECF = 1;     当 CF( PCA0CN.7)被置位时,允许 PCA 计数器/定时器溢出的中断请求。

功能:将PCA初始化为使用SYSCLK / 12作为其时钟源。
      它还通过写入PCA0CPL5设置偏移值.
*/
void PCA_Init(void)
{
    PCA0CN     =  0x40;        		// PCA counter enable  							允许 PCA 计数器/定时器
    PCA0MD    &= ~0x40 ;       		// Watchdog timer disabled-clearing bit 6  		看门狗定时器被禁止
    PCA0MD    &=  0xF1;        		// Timebase selected - System clock / 12        SYSCLK / 12作为PCA的时钟源
    PCA0CPL5   =  0xFF;        		// Offset value
}

/*
配置看门狗

Calculate Watchdog Timer Timeout
Offset calculated in PCA clocks
Offset = ( 256 x PCA0CPL5 ) + 256 - PCA0L
       = ( 256 x 255(0xFF)) + 256 - 0
Time   = Offset * (12/SYSCLK)   
       = 32.1 ms ( PCA uses SYSCLK/12 as its clock source)

*/
void WDT_Config(void)
{
   PCA0MD  &= ~0x40;                   // WDTE = 0 (clear watchdog timer enable)
   PCA0L    = 0x00;                    // Set lower byte of PCA counter to 0  
   PCA0H    = 0x00;                    // Set higher byte of PCA counter to 0
   PCA0CPL5 = 0xFF;                    // Write offset for the WDT 
   PCA0MD  |= 0x40;                    // Enable the WDT
}


void feeding_dog(void)
{
	PCA0CPH5  = 0x00;
}

发布了95 篇原创文章 · 获赞 28 · 访问量 15万+

猜你喜欢

转载自blog.csdn.net/happygrilclh/article/details/105033888