搜索
bottom↓
回复: 9

STC系列单片机 看门狗一旦启动,就无法关闭

[复制链接]

出0入0汤圆

发表于 2016-1-21 16:19:57 | 显示全部楼层 |阅读模式

由于做个设备 ,要添加看门狗做个保险,最后测试发现看门狗一旦开启,就无法关闭,除非断电。

以下是我设置的程序功能:

程序开始的时候 让LED3常亮3秒,然后熄灭,表明程序初始化完成,进入while循环,之后LED3不会再亮。
程序初始化时候,开始定期器1,让其每秒钟改变LED2的状态,也就是1秒钟亮一下,1秒钟灭一下,表明程序正常在跑。
然后利用按键K1来控制看门狗,K1按下1次,LED1会亮,同时初始化看门狗和把开启看门狗标志置1。再按下一次LED1灭,把看门狗标志置0。
在定时器中断里面,只要看门狗标志为1,则每秒钟都喂狗一次。
把看门狗设置为256分频,也就是大概5秒钟的喂狗周期,过了这个时间没喂狗的话,系统就会重启。

下面是我的测试方法和显现:
给单片机上电,LED3开始亮3秒,然后熄灭,
然后只有LED2开始正常闪烁。
按下按键K1,LED1亮起,表明开启看门狗。此时LED2也正常闪烁。
再次按下K1,LED1熄灭,表明看门狗标志位置0,定时器中断里面不会再喂狗。
此时LED2再闪烁几次后,由于没有喂狗,LED3常亮3秒然后熄灭,表明系统重启了,LED2再闪烁几秒,LED3由常亮3秒后熄灭,表明系统又重启,LED2再闪烁几秒,如此循环。

问题的关键是我在程序的开头,就定义了这样一句:“WDT_CONTR = 0x07;                //把看门狗寄存器设置为关闭状态” ,视图把看门狗关闭,但是结果并没有什么用。最后总结出,看门狗一旦开启,就无法关闭,如果没在规定的时间内喂狗,那么就会无限重启。

以下是程序代码



  1. #include<intrins.h>     
  2. #include"STC12C5AXX.h"

  3. #define TM_BASE 100
  4. sbit K1=P2^0;
  5. sbit K2=P2^1;
  6. sbit LED1=P1^0;
  7. sbit LED2=P1^1;
  8. sbit LED3=P1^2;
  9. unsigned char T_BASE=100;     //1s基准
  10. unsigned char WDT_TAG=0;

  11. void Delay10ms( );   //延时10ms
  12. void Timer0Init(void);        //10毫秒@12.000MHz      
  13. void WDTInit(void);     //看门狗初始化
  14. void WDTFeed(void);     //喂狗函数




  15. /*******************************************************************************
  16. * 函 数 名         : main
  17. * 函数功能               : 主函数
  18. * 输    入         : 无
  19. * 输    出         : 无
  20. *******************************************************************************/
  21. void main(void)
  22. {
  23.       unsigned int i,j;
  24.       EA=1;
  25.       i=0;
  26.       j=0;
  27.       WDT_TAG=0;
  28.       LED1=0;
  29.       LED2=0;
  30.       WDT_CONTR = 0x07;       //把看门狗寄存器设置为关闭状态

  31.       /////////////////
  32.       //让LED3亮3秒,表示程序开始启动
  33.       LED3=1;
  34.       for(i=0;i<300;i++)
  35.       {
  36.             Delay10ms();

  37.       }
  38.       LED3=0;
  39.       i=0;
  40.       ////////////

  41.       LED3=0;
  42.       K1=1; //把按键的电平先拉高,之后再去判断是否按下
  43.       Timer0Init();     
  44.       while(1)
  45.       {      
  46.             if(K1==0)         //检测按键K1是否按下
  47.             {           
  48.                   Delay10ms();      //消除抖动
  49.                   Delay10ms();      //消除抖动
  50.                   Delay10ms();      //消除抖动
  51.                   if(K1==0)
  52.                   {
  53.                         if(LED1==0)
  54.                         {
  55.                               LED1=1;     
  56.                               WDTInit();        //开启看门狗
  57.                               WDT_TAG=1;        //看门狗标志置1,表示在定时器里面开始喂狗                    
  58.                         }
  59.                         else
  60.                         {
  61.                               LED1=0;
  62.                               WDT_TAG=0;        //看门狗标志置0,表示在定时器里面不喂狗               
  63.                         }
  64.                         while((i<50)&&(K1==0))    //检测按键是否松开
  65.                         {
  66.                               Delay10ms();
  67.                               i++;
  68.                         }
  69.                         i=0;
  70.                   }
  71.             }           





  72.       }                       
  73. }

  74. void Delay10ms()        //@12.000MHz   延时10ms
  75. {
  76.       unsigned char i, j;

  77.       _nop_();
  78.       _nop_();
  79.       i = 117;
  80.       j = 183;
  81.       do
  82.       {
  83.             while (--j);
  84.       } while (--i);
  85. }                                                        



  86. void Timer0Init(void)         //10毫秒@12.000MHz        定时器0初始化
  87. {
  88.       AUXR &= 0x7F;       //定时器时钟12T模式
  89.       TMOD &= 0xF0;       //设置定时器模式
  90.       TMOD |= 0x01;           //设置定时器模式
  91.       TL0 = 0xF0;       //设置定时初值
  92.       TH0 = 0xD8;       //设置定时初值
  93.       TF0 = 0;          //清除TF0标志
  94.       TR0 = 1;          //定时器0开始计时
  95.       ET0=1;
  96. }



  97. void tm0_isr() interrupt 1 using 1              //定时器0中断
  98. {
  99.       TL0 = 0xF0;       //设置定时初值
  100.       TH0 = 0xD8;       //设置定时初值

  101.       T_BASE--;
  102.       if(T_BASE==0)                       //到1秒后才执行以下操作
  103.       {
  104.             T_BASE=TM_BASE;
  105.             LED2=!LED2;
  106.             if(1==WDT_TAG)          //看门狗标志为1则喂狗
  107.             {
  108.                   WDTFeed();   //喂狗
  109.             }
  110.       }     


  111. }


  112. void WDTInit(void)
  113. {
  114. WDT_CONTR = 0x37;//使能看门狗,预分频256      理论上喂狗周期为5秒钟以内
  115. }
  116.       
  117. void WDTFeed(void)
  118. {
  119. WDT_CONTR = 0x37;//喂狗
  120. }

复制代码

以下是程序文件,在KEIL 4下面编译通过。


本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x

阿莫论坛20周年了!感谢大家的支持与爱护!!

一只鸟敢站在脆弱的枝条上歇脚,它依仗的不是枝条不会断,而是自己有翅膀,会飞。

出0入54汤圆

发表于 2016-1-21 16:22:45 | 显示全部楼层
很多看门狗都是开启就不能关闭啊。

出0入0汤圆

发表于 2016-1-21 16:26:40 | 显示全部楼层
手册中好像说过一旦开启就不能关闭

出0入0汤圆

发表于 2016-1-21 16:37:39 | 显示全部楼层
任何单片机的看门狗都这样,除非复位。

出0入0汤圆

发表于 2016-1-21 16:44:36 | 显示全部楼层
居然定时器喂狗~

出0入0汤圆

发表于 2016-1-21 21:33:26 | 显示全部楼层
居然定时器喂狗+1

出0入0汤圆

 楼主| 发表于 2016-1-22 10:06:26 | 显示全部楼层
superAFE 发表于 2016-1-21 21:34
定时器喂狗背离了 看门狗的作用了

在主循环里面,我不知道什么时候喂,因为说不清楚主循环里面耽搁的时间是多少 ,即使我选择256分频 5秒钟喂一次,那么也会存在有时候主循环里面函数执行超时而没有喂狗。。

出0入0汤圆

 楼主| 发表于 2016-1-22 10:06:42 | 显示全部楼层

在主循环里面,我不知道什么时候喂,因为说不清楚主循环里面耽搁的时间是多少 ,即使我选择256分频 5秒钟喂一次,那么也会存在有时候主循环里面函数执行超时而没有喂狗。。

出0入0汤圆

发表于 2016-1-23 13:24:20 | 显示全部楼层
碰到过主程序飞了,定时中断还是正常工作的情况

出0入0汤圆

发表于 2016-1-24 07:15:47 来自手机 | 显示全部楼层
定时器里可以喂狗,但需要在定时器里监视其他重要线程!
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-5-15 14:54

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

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