Arduino看门狗问题,求助(已解决)
本帖最后由 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);//强制超时引发复位
}
本帖最后由 gaoshine 于 2012-11-12 22:59 编辑
gaoshine 发表于 2012-11-7 17:28 static/image/common/back.gif
bootload很重要,在ArduinoDuemilanove下失败,在 Arduino UNO下就可以实现。另外即便使用新bootload或者 ...
//*******************************************/
//神经元2号控制器
//Neuron Ver 2.02D
//高胜2012-4-1
//修改2012-8-12
//电信基站机房监控
//D0-D1为串口和网络模块接口
//OUT12号口(开关量输出)烟感报警器1按钮接口
//OUT23号口(开关量输出)烟感报警器2按钮接口
//SG 4号口(开关量输出)室外声光警报器输出口
//VD4 5号口(开关量输出)通讯状态灯
//VD3 6号口(开关量输出)设备故障灯
//VD2 7号口(开关量输入)报警灯
//IN5 8号口(开关量输入)测试按钮
//IN6 9号口(开关量输入)烟感报警器1接口
//GZ1 10号口(开关量输入)烟感报警器2接口
//A0 模拟0 (模拟量输入)采集室外声光报警器电压
//********************************************/
//修改输出字串 变DD 为 DD+DH (DH为参数)
/*
写入基本信息指令: {*009,255;010,255;014,060;}
写入标识信息指令: {*041,001;}
保存指令: {#}
*/
//Lib函数库库
#include <EEPROM.h>
#include <avr/wdt.h> //使用WDT看门狗
//数字传感器端口
#define smoke1_pin 9 //烟感报警器1接口
#define smoke2_pin 10 //烟感报警器2接口
#define alarm1_test_pin 2 //烟感报警器1按钮接口
#define alarm2_test_pin 3 //烟感报警器2按钮接口
#define alarm_pin 4 //室外声光警报器输出口
#define reset_pin 4 //电源复位 (常开接点,需要上电是输出高电平)
#define commled_pin 5 //通讯状态灯
#define led_pin 6 //设备故障灯
#define alarmled_pin 7 //报警灯
#define testbutton_pin 8 //测试按钮
//模拟传感器端口
#define ac_pin 0 //电源电压传感器
#define bj_pin 0 //声光报警器电压传感器
int count; //程序控制器计数器
int connect_count; // 通讯计数器
byte alarmcount; //为每个参数分配一个报警计数器
byte unalarmcount; //为每个参数分配一个un报警计数器
byte alarmstatus;
//int resetcount;
int status; //系统进入空闲状态
int address; //程序控制器变量
int values; //程序控制器变量
static uint32_t timer; //计时器
boolean testflag = false; //自检测时标示
boolean alarmflag = false; //报警标示
int checkcount; //烟感报警器和声光报警器状态检测周期计数器 每1小时检测一次
long jiange;
int DD; //动态数据 |ADD|NULL|D2|D3|....|D11|D12|D13|A0|..|A5| 一共20个
byte DH; //:标示为"N" 否则认定没有设置参数
//-为控制位 1-8字节 1(1 启用本通道 0 禁用本通道 ) 2、3(00数字输入 01数字输出 10
//模拟输入 11模拟输出)4(1高位报警 0低位报警) 5、6(00不报、01只监控、10上限报警 11下限报警)
//7、8(00网络报警 01 声音 10 短信 11声音+短信)
//-对应-的报警数值
//设备地址码
//DH DH fire DH timer
void setup()
{
//初始化串口
Serial.begin(9600);
//烟感报警器接口(输入)
pinMode(smoke1_pin,INPUT);
pinMode(smoke2_pin,INPUT);
pinMode(testbutton_pin ,INPUT);
//烟感报警器测试按钮接口(输出)
pinMode(alarm1_test_pin,OUTPUT);
pinMode(alarm2_test_pin,OUTPUT);
//输出 LED灯 报警器 电源复位
pinMode(led_pin,OUTPUT);
pinMode(commled_pin,OUTPUT);
pinMode(alarmled_pin,OUTPUT);
pinMode(reset_pin,OUTPUT);
pinMode(alarm_pin,OUTPUT);
//拉高电平给设备供电
digitalWrite(reset_pin, LOW);
digitalWrite(alarm1_test_pin, LOW);
digitalWrite(alarm2_test_pin, LOW);
digitalWrite(alarm_pin, LOW);
int i;
for (i=0;i<20;i++){
alarmcount=0;
}
for (i=0;i<20;i++){
DD=1;
}
//设备初始化
deviceinit();
//变量初始化
delay(1000);
jiange=millis();
status = 0;
count = 100;
connect_count=0;
//初始化看门狗
wdt_enable(WDTO_8S);
}
//主循环程序
void loop()
{
byte inbyte;
wdt_reset(); //喂狗
if (Serial.available() > 0){ //从串口接收指令
inbyte = Serial.read(); //
action(inbyte); //调用控制函数进入指令状态
}
if (status==0) //status==0 那么系统进入空闲状态,继续采集数据、监控报警,否则进入忙状态暂停采集报警任务
{
data_capture(); //数据采集
if (testflag==true) {
alarmcheck(); //报警检测
}
if (!digitalRead(testbutton_pin)) //按下自检测试按钮
{
testflag=false;
checkcount=0;
checkfire(); //进行火灾探测器的自检测试
delay(1000);
checkalarm(); //进行声光报警器的自检测试
}
}
//设备自检自启动
void selftest(){
Serial.print("<i|SELF_TEST|");
Serial.print(DH,DEC);
Serial.println("|>");
for(int i=1;i<=3;i++){
digitalWrite(led_pin, HIGH);
digitalWrite(alarmled_pin, HIGH);
wdt_reset(); //喂狗
delay(3000);
digitalWrite(led_pin, LOW);
digitalWrite(alarmled_pin, LOW);
}
Serial.print("<i|SYSTEM_RESET|");
Serial.print(DH,DEC);
Serial.println("|>");
delay(10000); //8S后系统复位
}
顺便说一下 看门狗的用法很简单 看看是不是片子和bootload的问题
只需要三句话就可以
#include <avr/wdt.h> //使用WDT看门狗
wdt_enable(WDTO_8S); //初始化看门狗
wdt_reset(); //喂狗
然后给个长于8S的延时,系统就可以重新启动
另外 我还常用软启动来解决系统启动问题,效率比看门狗要高,只是启动后,寄存器和内存变量的值不变,供各位参考:
void software_Reset() // 软启动系统,但不 复位寄存器和变量
{
asm volatile ("jmp 0");
}
这个原理很简单,直接跳转到程序起始位:0000开始运行,学过汇编的应该明白,这个效率真他妈的高啊 呵呵
要用看门狗好像先要烧熔丝位才行 bootload很重要,在ArduinoDuemilanove下失败,在 Arduino UNO下就可以实现。另外即便使用新bootload或者optiboot在 168的芯片上也不行,我的测试环境是:Arduino UNO328P ,看门狗测试没有问题。
嗯,我在UNO上测试DS1232也没问题 呃,原来是用内置看门狗啊,貌似很麻烦,我倒是没用过…… gaoshine 发表于 2012-11-12 22:49 static/image/common/back.gif
//*******************************************/
//神经元2号控制器
//Neuron Ver 2.02D
感谢您的回复,我看写法一样的,但你的就能成功,那可能就是bootloader的原因了。可是我手上的uno 2012的也没成功,也不知道你的uno里烧的什么样的bootloader了 问题已解决,只要去掉Setup中的 wdt_disable();和 delay(30000);程序测试就正常了。
画蛇添足了,呵呵{:soso_e105:} bg1lsy 发表于 2012-11-21 10:24 static/image/common/back.gif
问题已解决,只要去掉Setup中的 wdt_disable();和 delay(30000);程序测试就正常了。
画蛇添足了,呵呵{:so ...
你好 看门狗电路的问题请教您一下。我就是复制的你的代码 然后把setup里面的两句删掉,结果不行,,到该复位的时候 LED13就一直亮着 点重启也没用了。 如果你确认程序没有错误的话,有时用高版本的ide重刷一下bootloader也会有效果,有的低版本的bootloader对看门狗支持的不好 请问你用的是什么板子测试的,我用了nano 和pro mini 测试都不行?:'( 也测试了下
168的bootloader真的不行
328可以
#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();
} 我遇上了同样问题,用的板子好像是个改进版的nano,用的ch340g芯片,mcu是328p,饿死看门狗可以成功导致重启,但是重启后死机,板子上的灯狂闪,烧程序不能,必须拔电再插。
看门狗设置代码:
WDTCSR = 0x18;//WDCE(bit4) & WDE(bit3)
WDTCSR = 0x0D;
饿死狗代码:
while(1){//kill the dog
;
} http://www.arduino.cn/forum.php?mod=viewthread&tid=2638&fromuid=3
需要注意的是Arduino bootloader并不支持看门狗,如果你直接使用看门狗定时器,可能会卡死在bootloader中。如果要使用看门狗建议使用ISP下载器直接下载程序。 学习了!!!
页:
[1]
2