找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 1836|回复: 12
收起左侧

大侠发个STC51定时器喂狗代码 学习一下

[复制链接]
ID:302293 发表于 2023-6-16 11:51 | 显示全部楼层 |阅读模式
谢谢大家
回复

使用道具 举报

ID:155507 发表于 2023-6-16 14:13 | 显示全部楼层
不要在定时器中断中喂狗,那将是一条宠物狗!

用定时器喂狗不合适吧,主程序跑飞了,但定时器仍旧喂狗,不能复位系统. 应该在主程序loop里面加喂狗指令, 程序跑飞,超时不能喂狗重启系统.
回复

使用道具 举报

ID:712097 发表于 2023-6-16 14:57 | 显示全部楼层
// 看门狗程序 开始------------------------------------------------

WDT_CONTR = 0x27; //使能看门狗,溢出时间约为8s 通常放在main函数初始化区域

WDT_CONTR = 0x37; //清看门狗,否则系统复位(喂狗)通常放在mainWhile(1)循环体中 注意喂狗间隔不能超过8秒
回复

使用道具 举报

ID:57657 发表于 2023-6-16 18:36 | 显示全部楼层
angmall 发表于 2023-6-16 14:13
不要在定时器中断中喂狗,那将是一条宠物狗!

用定时器喂狗不合适吧,主程序跑飞了,但定时器仍旧喂狗,不 ...

不光是定时器中断,任何中断内或被中断调用的函数都不能喂狗。
回复

使用道具 举报

ID:1034262 发表于 2023-6-16 21:14 | 显示全部楼层
喂狗只在主循环喂一次。
回复

使用道具 举报

ID:517951 发表于 2023-6-17 07:40 | 显示全部楼层
定时器是硬件, 独立于单片机程序执行运行的, 单片机程序跑飞死机了, 定时器还能持续喂狗, 单片机异常后是不能复位重启的.
回复

使用道具 举报

ID:302293 发表于 2023-6-17 08:26 | 显示全部楼层
chxelc 发表于 2023-6-16 14:57
// 看门狗程序 开始------------------------------------------------

WDT_CONTR = 0x27; //使能看门狗 ...

  那怎么计算出每个函数执行的时间,执行完后刚好喂狗呢?
回复

使用道具 举报

ID:624769 发表于 2023-6-17 13:47 | 显示全部楼层
sr861126 发表于 2023-6-17 08:26
那怎么计算出每个函数执行的时间,执行完后刚好喂狗呢?

看门狗不是去算主循环需要跑多少时间,实际上你也算不出来,因为每次循环的时间是不确定的,一旦有中断触发,主循环,一个循环的时间就会被延长。
而是你自己定义一个忍耐极限,就好像电脑多久没有反应了,你判定认为死机了,然后强制重启?
看门狗一个道理,比如,程序比较复杂的,中断比较多的,你定义个3秒,没有完成一个循环,说明死机了,那么就重启,就定义3秒,反正每次喂3秒,超时了就重启。 程序比较简单的,可以定义个 200ms,只要循环超过200ms 就重启。 看你自己的“忍耐极限”
回复

使用道具 举报

ID:712097 发表于 2023-6-17 14:47 | 显示全部楼层
sr861126 发表于 2023-6-17 08:26
那怎么计算出每个函数执行的时间,执行完后刚好喂狗呢?

时间不一定要刚刚好,提前喂狗也是可以的。例如8秒的看门狗,1秒喂狗也是可以的。
只要不影响程序的运行,你勤快点喂狗,爱狗人士会表扬你的。

如果程序块或者函数执行时间超过8秒,就需要在函数或语句块中加入喂狗语句。
关于函数执行的时间,要熟悉下硬件才能估算,1T的单片机,语句执行是很快的,耗时大多在循环或者延时函数上。
回复

使用道具 举报

ID:712097 发表于 2023-6-17 14:49 | 显示全部楼层
发一个STC官网的STC15系列的看门狗测试程序供参考

/*---------------------------------------------------------------------*/
/* --- STC MCU Limited ------------------------------------------------*/
/* --- STC15F4K60S4 系列 看门狗溢出复位测试举例------------------------*/
/* 如果要在程序中使用此代码,请在程序中注明使用了STC的资料及程序        */
/* 如果要在文章中应用此代码,请在文章中注明使用了STC的资料及程序        */
/*---------------------------------------------------------------------*/

//本示例在Keil开发环境下请选择Intel的8058芯片型号进行编译
//若无特别说明,工作频率一般为11.0592MHz


#include "reg51.h"
#include "intrins.h"

sfr P0M1 = 0x93;
sfr P0M0 = 0x94;
sfr P1M1 = 0x91;
sfr P1M0 = 0x92;
sfr P2M1 = 0x95;
sfr P2M0 = 0x96;
sfr P3M1 = 0xb1;
sfr P3M0 = 0xb2;
sfr P4M1 = 0xb3;
sfr P4M0 = 0xb4;
sfr P5M1 = 0xC9;
sfr P5M0 = 0xCA;
sfr P6M1 = 0xCB;
sfr P6M0 = 0xCC;
sfr P7M1 = 0xE1;
sfr P7M0 = 0xE2;

sfr WDT_CONTR   = 0xc1;     //看门狗控制寄存器
sbit P32        = P3^2;     //测试口

void delay(unsigned int i)
{
    while (i--)
    {
        _nop_();
        _nop_();
        _nop_();
        _nop_();
        _nop_();
    }
}

void main()
{
    P0M0 = 0x00;
    P0M1 = 0x00;
    P1M0 = 0x00;
    P1M1 = 0x00;
    P2M0 = 0x00;
    P2M1 = 0x00;
    P3M0 = 0x00;
    P3M1 = 0x00;
    P4M0 = 0x00;
    P4M1 = 0x00;
    P5M0 = 0x00;
    P5M1 = 0x00;
    P6M0 = 0x00;
    P6M1 = 0x00;
    P7M0 = 0x00;
    P7M1 = 0x00;

    P32 = 0;
    delay(10000);           //复位闪灯延时
    P32 = 1;
    WDT_CONTR = 0x04;       //看门狗定时器溢出时间计算公式: (12 * 32768 * PS) / FOSC (秒)
                            //设置看门狗定时器分频数为32,溢出时间如下:
                            //11.0592M : 1.14s
                            //18.432M  : 0.68s
                            //20M      : 0.63s
    WDT_CONTR |= 0x20;      //启动看门狗
    while (1);
}

回复

使用道具 举报

ID:712097 发表于 2023-6-17 15:19 | 显示全部楼层
发个测试看门狗的代码供参考:

#include "reg51.h"

sfr     WDT_CONTR   =   0xc1;
sbit    P32         =   P3^2;

sfr     P0M1        =   0x93;
sfr     P0M0        =   0x94;
sfr     P1M1        =   0x91;
sfr     P1M0        =   0x92;
sfr     P2M1        =   0x95;
sfr     P2M0        =   0x96;
sfr     P3M1        =   0xb1;
sfr     P3M0        =   0xb2;
sfr     P4M1        =   0xb3;
sfr     P4M0        =   0xb4;
sfr     P5M1        =   0xc9;
sfr     P5M0        =   0xca;

void main()
{
    P0M0 = 0x00;
    P0M1 = 0x00;
    P1M0 = 0x00;
    P1M1 = 0x00;
    P2M0 = 0x00;
    P2M1 = 0x00;
    P3M0 = 0x00;
    P3M1 = 0x00;
    P4M0 = 0x00;
    P4M1 = 0x00;
    P5M0 = 0x00;
    P5M1 = 0x00;

//  WDT_CONTR = 0x23;                           //使能看门狗,溢出时间约为0.5s
    WDT_CONTR = 0x24;                           //使能看门狗,溢出时间约为1s
//  WDT_CONTR = 0x27;                           //使能看门狗,溢出时间约为8s
    P32 = 0;                                    //测试端口

    while (1)
    {
//      WDT_CONTR = 0x33;                       //清看门狗,否则系统复位
        WDT_CONTR = 0x34;                       //清看门狗,否则系统复位
//      WDT_CONTR = 0x37;                       //清看门狗,否则系统复位

//      Display();                              //显示模块
//      Scankey();                              //按键扫描模块
//      MotorDriver();                          //电机驱动模块
    }
}
回复

使用道具 举报

ID:401564 发表于 2023-6-18 17:46 | 显示全部楼层
喂狗直接放在主函数
主函数执行时间是不好算出来的,特别是用KEIL来仿真STC
在主函数放一行取反一个IO的代码,用示波器或者逻辑分析仪测量就知道运行时间了
喂狗时间大于这个时间就可以子
回复

使用道具 举报

ID:123289 发表于 2023-6-19 09:03 | 显示全部楼层
喂狗就一条指令而矣。
关键是,你要弄清楚看门狗的应用原理,原理通了,写一个喂狗语句还值得一提。
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表