【STC8A8K64S4A12开发板】—学习WDT看门狗

版权声明:本文为博主原创文章,转载请附上原文出处链接。


前言

本次讲解STC8A8K64S4A12系列单片机系统复位的方式,掌握看门狗定时器的原理;掌握单片机看门狗定时器的寄存器配置及程序设计。


一、硬件设计

1.单片机系统复位

STC8A8K64S4A12系列单片机的复位分为硬件复位和软件复位两种。

硬件复位时,所有寄存器的值会复位到初始值,系统会重新读取所有的硬件选项。同时根据硬件选项所设置的上电等待时间进行上电等待。

软件复位时,除与时钟相关的寄存器保持不变外,其余的所有寄存器的值会复位到初始值,软件复位不会重新读取所有的硬件选项。

在这里插入图片描述

图1:STC8A8K64S4A12系列单片机复位分类

STC8A8K64S4A12系列单片机软件复位是通过IAP控制寄存器IAP_CONTR的SWRST使能的,IAP_CONTR寄存器具体如下。

在这里插入图片描述

图2:IAP控制寄存器IAP_CONTR

☆注:如果开启软件复位后,还需操作寄存器SWBS位以确定开始执行代码的区域。

2.单片机看门狗简介

在工业控制/汽车电子/航空航天等需要高可靠性的系统中,为了防止“系统在异常情况下,受到干扰,MCU/CPU程序跑飞,导致系统长时间异常工作”的情况发生,而设计了一种用于检测程序运行状态的芯片或电路,俗称看门狗(即Watchdog)。

看门狗通常有一个输入信号和一个输出信号。输入信号也称“喂狗”,输出信号关联MCU的复位端。系统运行后启动看门狗计数器,看门狗开始计数,当计数满后未收到清零信号(喂狗),看门狗计数器溢出,触发看门狗中断,输出控制MCU复位。

看门狗可分为独立于单片机芯片外的看门狗芯片和集成于单片机芯片内的看门狗外设两种。按照工作原理,独立看门狗和窗口看门狗是最为常见的两种看门狗类型。

☆注:以上描述是针对看门狗的通用性描述,不同型号的单片机看门狗可能会有差异。

3.STC8A8K64S4A12系列单片机看门狗介绍

STC8A8K64S4A12系列单片机看门狗实际上是一个15位的定时器或计数器,简称WDT。单片机运行工作中,如果开启了看门狗外设,则看门狗会对单片机机器周期脉冲不停计数,单片机程序如果不能及时对看门狗的定时器复位(俗称“喂狗”),看门狗就会在其定时器计满溢出时产生一个复位信号,从而使系统重启。

下图可比较形象的诠释看门狗原理,单片机CPU必须在看门狗计数器没有溢出前喂狗,否则计数器一旦溢出,则系统重启。

在这里插入图片描述

图3:看门狗工作原理示意图

☆注:所谓的喂狗,就是将看门狗计数器计数清零。

1.1.看门狗控制寄存器WDT_CONTR

看门狗控制寄存器WDT_CONTR不支持位寻址,该寄存器的B0~B2位用于设置看门狗定时器时钟分频系数,寄存器B3位是单片机空闲模式时的看门狗控制位,寄存器B4位是清零看门狗计数器计数控制位,寄存器B5位是看门狗使能控制位,寄存器B7位是看门狗溢出标志位。

在这里插入图片描述

图4:看门狗控制寄存器WDT_CONTR

1.2.看门狗溢出时间计算

下面给出看门狗溢出时间计算公式:

在这里插入图片描述

图5:看门狗溢出时间计算公式

☆注:STC官方手册上面没有给出看门狗溢出时间的推导过程,也没有明确说明看门狗定时器的时钟频率,以系统时钟12分频后给看门狗定时器提供时钟是最合理的解释。

举例,配置WDT_CONTR寄存器B2位PS2为0,配置WDT_CONTR寄存器B1位PS1和B0位PS0均为1,系统时钟为11.0592MHZ,计算看门狗溢出时间。

  • 1)看门狗定时器时钟分频系数PS[2:0]值为011,转成十进制是3,进而得出分频因子PSC值为16。
  • 2)看门狗溢出时间:(161232768)/11059200=0.5688s=568.8ms。

4.看门狗溢出时间计算

针对STC8A8K64S4A12系列单片机看门狗配置过程如下:

在这里插入图片描述

图6:看门狗配置步骤

☆注:实验例程即是按照上述配置步骤操作寄存器相关位实现,后有详述。

二、软件设计

1.看门狗实验实验(及时喂狗)

1.1.工程需要用到的c文件

本例需要用到的c文件如下表所示,工程需要添加下表中的c文件。

表1:实验需要用到的c文件
序号文件名后缀功能描述
1led.c包含与用户led控制有关的用户自定义函数
2wdt.c看门狗有关的用户自定义函数
3delay.c包含用户自定义延时函数

1.2.头文件引用和路径设置

■ 需要引用的头文件

#include "delay.h"  
#include "wdt.h"  
#include "led.h"  

■ 需要包含的头文件路径

本例需要包含的头文件路径如下表:

表2:头文件包含路径
序号路径描述
1…\ Sourceled.h、wdt.h和delay.h头文件在该路径,所以要包含
2…\UserSTC8.h头文件在该路径,所以要包含

MDK中点击魔术棒,打开工程配置窗口,按照下图所示添加头文件包含路径。

在这里插入图片描述

图7:添加头文件包含路径

1.3.编写代码

首先,在wdt.c文件中编写看门狗初始化函数WDT_Init,代码如下。

程序清单:看门狗初始化函数

/*************************************************************************** 
 * 描  述 : 看门狗初始化 
 * 入  参 : 无 
 * 返回值 : 无 
 **************************************************************************/  
void WDT_Init(void)  
{     
    WDT_CONTR &= 0xF7;          //IDLE_WDT位置0,看门狗定时器在空闲模式下不计数  
    WDT_CONTR &= 0xFB;          //PS2位置0,设置看门狗定时器预分频值  
    WDT_CONTR |= 0x03;          //PS1、PS0位置1,设置看门狗定时器预分频值  
    WDT_CONTR &= 0x7F;          //WDT_FLAG位置0,看门狗溢出标志位清零  
    WDT_CONTR |= 0x20;          //EN_WDT位置1,开启看门狗定时器  
}  

然后,编写喂狗函数,代码如下。

程序清单:喂狗函数

/*************************************************************************** 
 * 描  述 : 喂狗 
 * 入  参 : 无 
 * 返回值 : 无 
 **************************************************************************/  
void WDG_Feed(void)  
{     
    WDT_CONTR |= 0x10;          //CLR_WDT位置1,看门狗定时器重新计数  
} 

最后,在主函数中先控制用户指示灯D3亮,主循环中有软件延时和喂狗操作,喂狗之后会翻转用户指示灯D4并熄灭用户指示灯D3,以方便观察实验现象。

代码清单:主函数

int main()  
{  
        leds_off();             //熄灭开发板上的4个指示灯(D1、D2、D3、D4)  
        WDT_Init();        //看门狗初始化,看门狗溢出时间约568.8ms(11.0592MHZ)
        delay_ms(200);     
        led_on(LED_3);            //点亮用户指示灯D3 
    while(1)  
    {      
          //软件延时200ms,该延时是模拟喂狗前实际执行用户应用代码所用时长  
            delay_ms(200);   
          //喂狗  
            WDG_Feed();     
            led_off(LED_3);          //熄灭用户指示灯D3  
             led_toggle(LED_4);         //翻转用户指示灯D4 
          //软件延时200ms,该延时是模拟喂狗后实际执行用户应用代码所用时长  
            delay_ms(200);                
    }  
} 

2.看门狗实验(未及时喂狗)

2.1.工程需要用到的c文件

本实验需要用到的头文件以及添加头文件包含路径的方法请参考“实验2-7-1:WDT看门狗实验(及时喂狗)”部分。

2.2.编写代码

首先,在wdt.c文件中编写看门狗初始化函数WDT_Init,代码如下。

程序清单:看门狗初始化函数

/*************************************************************************** 
 * 描  述 : 看门狗初始化 
 * 入  参 : 无 
 * 返回值 : 无 
 **************************************************************************/  
void WDT_Init(void)  
{     
    WDT_CONTR &= 0xF7;          //IDLE_WDT位置0,看门狗定时器在空闲模式下不计数  
    WDT_CONTR &= 0xFB;          //PS2位置0,设置看门狗定时器预分频值  
    WDT_CONTR |= 0x03;          //PS1、PS0位置1,设置看门狗定时器预分频值  
    WDT_CONTR &= 0x7F;          //WDT_FLAG位置0,看门狗溢出标志位清零  
    WDT_CONTR |= 0x20;          //EN_WDT位置1,开启看门狗定时器  
}  

然后,编写喂狗函数,代码如下。

程序清单:喂狗函数

/*************************************************************************** 
 * 描  述 : 喂狗 
 * 入  参 : 无 
 * 返回值 : 无 
 **************************************************************************/  
void WDG_Feed(void)  
{     
    WDT_CONTR |= 0x10;          //CLR_WDT位置1,看门狗定时器重新计数  
}

最后,在主函数中先控制用户指示灯D3亮,主循环中有软件延时和喂狗操作,喂狗之后会翻转用户指示灯D4并熄灭用户指示灯D3,以方便观察实验现象。

代码清单:主函数

int main()  
{  
        leds_off();             //熄灭开发板上的4个指示灯(D1、D2、D3、D4)  
        WDT_Init();     //看门狗初始化,看门狗溢出时间约568.8ms(11.0592MHZ)  
        delay_ms(200);     
        led_on(LED_3);            //点亮用户指示灯D3 
    while(1)  
    {      
          //软件延时200ms,该延时是模拟喂狗前实际执行用户应用代码所用时长  
            delay_ms(200);   
          //喂狗  
            WDG_Feed();     
            led_off(LED_3);          //熄灭用户指示灯D3 
            led_toggle(LED_4);         //翻转用户指示灯D4 
          //软件延时500ms,该延时是模拟喂狗后实际执行用户应用代码所用时长  
            delay_ms(500);                
    }  
} 

总结

以上就是今天要讲的内容,本文简单介绍了:1、编写程序观察开启看门狗WDT后及时喂狗系统正常运行的现象/2、编写程序观察开启看门狗WDT但未及时喂狗系统复位的现象。
  • 1
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

电子友人张

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值