极客工坊

 找回密码
 注册

QQ登录

只需一步,快速开始

查看: 47566|回复: 16

Arduino看门狗问题,求助(已解决)

[复制链接]
发表于 2012-11-7 12:38:35 | 显示全部楼层 |阅读模式
本帖最后由 bg1lsy 于 2012-11-21 10:23 编辑

为了测试Arduino的看门狗功能,在网上找了以下代码。运行后应该有的效果是超时重启,但实际效果却是超时后死机,求成功使用过Arduino看门狗功能的朋友帮忙看看原因。
死机后就算按主控板上的reset按键都不能让单片机复位,只能断电才能重启!

#include <avr/io.h>
#include <avr/wdt.h>
#include <arduino.h>

#define LED_PIN 13 //LED引脚

void setup(){
  pinMode(LED_PIN,OUTPUT);
  digitalWrite(LED_PIN,HIGH);
  wdt_disable();
  delay(30000);  //此处设置长时间等待,是为了上电后有足够时间下载程序
  wdt_enable(WDTO_4S);
}

void loop(){
  wdt_reset();
  digitalWrite(LED_PIN,LOW);
  delay(5000);  //强制超时引发复位
}
回复

使用道具 举报

发表于 2012-11-12 22:49:33 | 显示全部楼层
本帖最后由 gaoshine 于 2012-11-12 22:59 编辑
gaoshine 发表于 2012-11-7 17:28
bootload很重要,在Arduino  Duemilanove下失败,在 Arduino UNO下就可以实现。另外即便使用新bootload或者 ...

  1. //*******************************************/
  2. //神经元2号控制器
  3. //Neuron Ver 2.02D
  4. //高胜  2012-4-1
  5. //修改  2012-8-12
  6. //电信基站机房监控
  7. //D0-D1为串口和网络模块接口
  8. //OUT1  2号口(开关量输出)烟感报警器1按钮接口
  9. //OUT2  3号口(开关量输出)烟感报警器2按钮接口
  10. //SG    4号口(开关量输出)室外声光警报器输出口
  11. //VD4   5号口(开关量输出)通讯状态灯
  12. //VD3   6号口(开关量输出)设备故障灯
  13. //VD2   7号口(开关量输入)报警灯
  14. //IN5   8号口(开关量输入)测试按钮
  15. //IN6   9号口(开关量输入)烟感报警器1接口
  16. //GZ1   10号口(开关量输入)烟感报警器2接口
  17. //A0    模拟0 (模拟量输入)采集室外声光报警器电压
  18. //********************************************/
  19. //修改输出字串 变DD[20] 为 DD[0-19]+DH[4-10] (DH[4-10]为参数)
  20. /*
  21. 写入基本信息指令: {*009,255;010,255;014,060;}
  22. 写入标识信息指令: {*041,001;}
  23. 保存指令:         {#}
  24. */
  25.   

  26. //Lib函数库库
  27. #include <EEPROM.h>
  28. #include <avr/wdt.h>                                                                //使用WDT看门狗


  29. //数字传感器端口

  30. #define smoke1_pin                            9                 //烟感报警器1接口
  31. #define smoke2_pin                            10                //烟感报警器2接口
  32. #define alarm1_test_pin          2                 //烟感报警器1按钮接口
  33. #define alarm2_test_pin                         3                 //烟感报警器2按钮接口

  34. #define alarm_pin                         4                 //室外声光警报器输出口
  35. #define reset_pin                            4                 //电源复位 (常开接点,需要上电是输出高电平)

  36. #define commled_pin                                 5                                   //通讯状态灯         
  37. #define led_pin                          6                 //设备故障灯
  38. #define alarmled_pin                        7                 //报警灯
  39. #define testbutton_pin                    8                 //测试按钮


  40. //模拟传感器端口
  41. #define ac_pin                            0                   //电源电压传感器
  42. #define bj_pin                            0                   //声光报警器电压传感器


  43. int count;                                           //程序控制器计数器
  44. int connect_count;                                                                        // 通讯计数器
  45. byte alarmcount[20];                                 //为每个参数分配一个报警计数器
  46. byte unalarmcount[20];                               //为每个参数分配一个un报警计数器
  47. byte alarmstatus[20];
  48. //int resetcount;
  49. int status;                                                                                 //系统进入空闲状态
  50. int address;                                                                                 //程序控制器变量
  51. int values;                                                                                 //程序控制器变量
  52. static uint32_t timer;                                                                 //计时器
  53. boolean testflag = false;                           //自检测时标示
  54. boolean alarmflag = false;                                                        //报警标示                                               
  55. int        checkcount;                                                                       //烟感报警器和声光报警器状态检测周期计数器 每1小时检测一次
  56. long jiange;

  57. int DD[20];                                          //动态数据 |ADD|NULL|D2|D3|....|D11|D12|D13|A0|..|A5| 一共20个

  58. byte DH[42];                                                      //[0]:标示为"N" 否则认定没有设置参数
  59.                                                                                                  //[1]-[20]为控制位 1-8字节 1(1 启用本通道 0 禁用本通道 ) 2、3(00数字输入 01数字输出 10
  60.                                                                                                  //模拟输入 11模拟输出)4(1高位报警 0低位报警) 5、6(00不报、01只监控、10上限报警 11下限报警)
  61.                                                                                                  //7、8(00网络报警 01 声音 10 短信 11声音+短信)
  62.                                                                                                  //[21]-[40]对应[1]-[20]的报警数值
  63.                                                                                                  //[41]设备地址码  
  64.                                                                                                  //DH[9] DH[10] fire        DH[14] timer      
  65. void setup()
  66. {
  67.         //初始化串口
  68.         Serial.begin(9600);         
  69.        
  70.         //烟感报警器接口(输入)
  71.         pinMode(smoke1_pin,INPUT);
  72.         pinMode(smoke2_pin,INPUT);
  73.         pinMode(testbutton_pin ,INPUT);
  74.        
  75.         //烟感报警器测试按钮接口(输出)
  76.         pinMode(alarm1_test_pin,OUTPUT);
  77.         pinMode(alarm2_test_pin,OUTPUT);
  78.        
  79.         //输出 LED灯 报警器 电源复位
  80.         pinMode(led_pin,OUTPUT);
  81.         pinMode(commled_pin,OUTPUT);
  82.         pinMode(alarmled_pin,OUTPUT);

  83.         pinMode(reset_pin,OUTPUT);
  84.         pinMode(alarm_pin,OUTPUT);


  85.        
  86.         //拉高电平给设备供电
  87.         digitalWrite(reset_pin, LOW);  
  88.         digitalWrite(alarm1_test_pin, LOW);  
  89.         digitalWrite(alarm2_test_pin, LOW);  
  90.         digitalWrite(alarm_pin, LOW);         
  91.     int i;
  92.     for (i=0;i<20;i++){
  93.                 alarmcount[i]=0;
  94.                 }
  95.     for (i=0;i<20;i++){
  96.                 DD[i]=1;
  97.                 }
  98.     //设备初始化
  99.         deviceinit();
  100.        
  101.         //变量初始化
  102.         delay(1000);
  103.     jiange=millis();
  104.         status = 0;
  105.     count = 100;
  106.         connect_count=0;
  107.         //初始化看门狗
  108.         wdt_enable(WDTO_8S);      

  109. }

  110.   
  111. //主循环程序   
  112. void loop()  
  113. {  
  114.         byte inbyte;
  115.         wdt_reset();                                                                          //喂狗         
  116.    if (Serial.available() > 0){                          //从串口接收指令
  117.     inbyte = Serial.read();                              //
  118.     action(inbyte);                                      //调用控制函数进入指令状态
  119.    }

  120. if (status==0)                         //status==0 那么系统进入空闲状态,继续采集数据、监控报警,否则进入忙状态暂停采集报警任务
  121. {
  122.     data_capture();                //数据采集
  123.     if   (testflag==true)        {
  124.         alarmcheck();                 //报警检测
  125.         }
  126.         if (!digitalRead(testbutton_pin))        //按下自检测试按钮
  127.         {
  128.     testflag=false;
  129.         checkcount=0;
  130.         checkfire();         //进行火灾探测器的自检测试
  131.         delay(1000);
  132.         checkalarm();    //进行声光报警器的自检测试

  133.         }
  134. }





  135. //设备自检自启动
  136. void selftest(){

  137.         Serial.print("<i|SELF_TEST|");
  138.         Serial.print(DH[41],DEC);
  139.         Serial.println("|>");

  140. for(int i=1;i<=3;i++){
  141.         digitalWrite(led_pin, HIGH);  
  142.         digitalWrite(alarmled_pin, HIGH);  
  143.     wdt_reset();                                                                                          //喂狗               
  144.         delay(3000);
  145.         digitalWrite(led_pin, LOW);
  146.         digitalWrite(alarmled_pin, LOW);
  147.         }
  148.        
  149.         Serial.print("<i|SYSTEM_RESET|");
  150.         Serial.print(DH[41],DEC);
  151.         Serial.println("|>");
  152.         delay(10000);                                                                                                //8S后系统复位
  153.         }
复制代码




顺便说一下 看门狗的用法很简单 看看是不是片子和bootload的问题
只需要三句话就可以

#include <avr/wdt.h>                                                                //使用WDT看门狗

wdt_enable(WDTO_8S);                                                                  //初始化看门狗

wdt_reset();                                                                                          //喂狗

然后给个长于8S的延时,系统就可以重新启动


另外 我还常用软启动来解决系统启动问题,效率比看门狗要高,只是启动后,寄存器和内存变量的值不变,供各位参考:


void software_Reset() // 软启动系统,但不 复位寄存器和变量
{
        asm volatile ("  jmp 0");
}  

这个原理很简单,直接跳转到程序起始位:0000开始运行,学过汇编的应该明白,这个效率真他妈的高啊 呵呵
回复 支持 1 反对 0

使用道具 举报

发表于 2012-11-7 16:24:06 | 显示全部楼层
要用看门狗好像先要烧熔丝位才行
回复 支持 反对

使用道具 举报

发表于 2012-11-7 17:28:07 | 显示全部楼层
bootload很重要,在Arduino  Duemilanove下失败,在 Arduino UNO下就可以实现。另外即便使用新bootload或者optiboot在 168的芯片上也不行,我的测试环境是:Arduino UNO  328P ,看门狗测试没有问题。

回复 支持 反对

使用道具 举报

发表于 2012-11-7 18:45:41 | 显示全部楼层
嗯,我在UNO上测试DS1232也没问题
回复 支持 反对

使用道具 举报

发表于 2012-11-10 10:51:59 | 显示全部楼层
呃,原来是用内置看门狗啊,貌似很麻烦,我倒是没用过……
回复 支持 反对

使用道具 举报

 楼主| 发表于 2012-11-20 22:16:20 | 显示全部楼层
gaoshine 发表于 2012-11-12 22:49
//*******************************************/
//神经元2号控制器
//Neuron Ver 2.02D

感谢您的回复,我看写法一样的,但你的就能成功,那可能就是bootloader的原因了。可是我手上的uno 2012的也没成功,也不知道你的uno里烧的什么样的bootloader了
回复 支持 反对

使用道具 举报

 楼主| 发表于 2012-11-21 10:24:59 | 显示全部楼层
问题已解决,只要去掉Setup中的 wdt_disable();和 delay(30000);程序测试就正常了。
画蛇添足了,呵呵{:soso_e105:}
回复 支持 反对

使用道具 举报

发表于 2013-10-5 19:50:49 | 显示全部楼层
bg1lsy 发表于 2012-11-21 10:24
问题已解决,只要去掉Setup中的 wdt_disable();和 delay(30000);程序测试就正常了。
画蛇添足了,呵呵{:so ...

你好 看门狗电路的问题请教您一下。我就是复制的你的代码 然后把setup里面的两句删掉,结果不行,,到该复位的时候 LED13就一直亮着 点重启也没用了。
回复 支持 反对

使用道具 举报

 楼主| 发表于 2013-10-6 09:56:11 | 显示全部楼层
如果你确认程序没有错误的话,有时用高版本的ide重刷一下bootloader也会有效果,有的低版本的bootloader对看门狗支持的不好
回复 支持 反对

使用道具 举报

发表于 2014-12-10 10:34:29 | 显示全部楼层
请问你用的是什么板子测试的,我用了nano 和pro mini 测试都不行?
回复 支持 反对

使用道具 举报

发表于 2014-12-15 08:45:53 | 显示全部楼层
也测试了下
168的bootloader真的不行
328可以

[pre lang="arduino" line="1" file="Watchdog_328.ino"]#include <avr/wdt.h>         //watchdog

#define TIMEOUT WDTO_8S      // predefine time, refer avr/wdt.h
const int ledPin =  13;      // the number of the LED pin

void setup(){
  //disable the watchdog
  //wdt_disable();
  pinMode(ledPin,OUTPUT);
  // LED light once after start or if timeout
  digitalWrite(ledPin,HIGH);
  delay(1000);
  // enable the watchdog
  wdt_enable(TIMEOUT);
}

void loop(){
  // process runing  
  digitalWrite(ledPin,LOW);
  delay(9000); //if timeout trig the reset
  //feed dog
  wdt_reset();
}[/code]
回复 支持 反对

使用道具 举报

发表于 2015-3-25 16:52:38 | 显示全部楼层
我遇上了同样问题,用的板子好像是个改进版的nano,用的ch340g芯片,mcu是328p,饿死看门狗可以成功导致重启,但是重启后死机,板子上的灯狂闪,烧程序不能,必须拔电再插。
看门狗设置代码:
WDTCSR = 0x18;//WDCE(bit4) & WDE(bit3)
WDTCSR = 0x0D;
饿死狗代码:
while(1){//kill the dog
        ;
}
回复 支持 反对

使用道具 举报

发表于 2015-4-22 21:31:34 | 显示全部楼层
http://www.arduino.cn/forum.php?mod=viewthread&tid=2638&fromuid=3
需要注意的是Arduino bootloader并不支持看门狗,如果你直接使用看门狗定时器,可能会卡死在bootloader中。如果要使用看门狗建议使用ISP下载器直接下载程序。
回复 支持 反对

使用道具 举报

发表于 2015-7-2 12:48:26 | 显示全部楼层
学习了!!!
回复 支持 反对

使用道具 举报

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

本版积分规则 需要先绑定手机号

Archiver|联系我们|极客工坊

GMT+8, 2024-3-28 21:47 , Processed in 0.055491 second(s), 28 queries .

Powered by Discuz! X3.4 Licensed

Copyright © 2001-2021, Tencent Cloud.

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