一旦触发,看门狗就会连续重置AVR Atmega 1281

时间:2016-06-25 09:42:45

标签: arduino avr atmega watchdog

我正在使用经过改进的Arduino板:Gizduino X和板载Atmega 1281 MCU芯片。使用Arduino IDE编程器将应用程序上传到MCU。我试图使用Atmega 1281的看门狗定时器复位功能,并使用了库" wdt.h"。问题是在看门狗复位后,微型电路似乎连续循环复位。我知道数据表的规格是必须在setup()之前禁用看门狗,因为它在复位后自动启用,因此我的代码中包含的内容如下:

#include <stdint.h>
#include <avr/wdt.h> //Watchdog Timer library
#define RST_PIN 38        //pin for MCU reset indicator

uint8_t mcusr_mirror __attribute__ ((section (".noinit")));
void get_mcusr(void) __attribute__((naked)) __attribute__((section(".init3")));
void get_mcusr(void)
{
    mcusr_mirror = MCUSR;
    MCUSR = 0;
    wdt_disable();
}

char ch;
char pn = 0;
bool ledState = false;

#define wdtReset()  wdt_reset(); \
                digitalWrite(RST_PIN, LOW)

#define wdtBegin()  wdt_reset(); \
                wdt_enable(WDTO_500MS); \
                bitSet(WDTCSR, WDIE)
/******************************************/
void setup() {
  wdtBegin();
  Serial.begin(115200);

  // initialize digital pin 13 as an output.

  wdtReset();
  pinMode(13, OUTPUT);
  pinMdoe(RST_PIN, OUTPUT);
}
/******************************************/
// the loop function runs over and over again forever
void loop() {
  if(Serial.available()) {
    ch = Serial.read();
    if(ch == 'R' || ch == 'r') {
      ledState = !ledState;
      digitalWrite(13, ledState);
      while(true);
    }
  }
  if(pn >= 255) pn = 0;
  Serial.println(pn++);
  wdtReset();
}
/******************************************/
ISR(WDT_vect) {
  digitalWrite(RST_PIN, HIGH);
}

代码的目的是隔离看门狗问题并根据需要调用看门狗复位。当MCU通电时,代码运行良好,但是当我发送一个字符来调用看门狗复位(&#39; r&#39; R&#39; R&#39;)时,RST_PIN设置为HIGH(表示中断触发)然后在复位后设置为低电平,但电路板上的LED指示灯亮。一旦处于此状态,按下复位按钮不会重置MCU,直到我从电路板上移除电源。此外,如果我连续按下复位按钮,当我意外触摸复位按钮旁边的一个ICSP引脚时,板上的LED指示灯会变暗并开始闪烁。

我还按照以下链接设置了看门狗的说明:http://donalmorrissey.blogspot.com/2011/09/using-watch-dog-on-atmega1281-as-lock.html

我在Atmega328 MCU上上传了相同的代码但是工作正常。我认为新问题存在问题,因为看门狗在系统复位后仍然使用默认值启用。

我错过了什么吗?问题硬件是否具体?

1 个答案:

答案 0 :(得分:0)

那是因为您的Arduino引导程序在主应用程序之前运行。当引导加载程序启动时,WDT仍然启用并设置为最小时段16ms。数据表说:

  

注意:如果意外启用看门狗,例如失控指针或欠压条件,则   器件将复位,看门狗定时器将保持使能状态​​。如果代码未设置为处理Watchdog,   这可能会导致永久性的超时重置循环。为避免这种情况,应用软件应该   始终清除初始化程序中的看门狗系统复位标志(WDRF)和WDE控制位,   即使看门狗没有使用。

您需要修改bootloader以在重置时禁用Watchdog或忘记主应用程序中的Watchdog。

UPDATE 要在引导加载程序中禁用WDT,请尽快执行此代码:

MCUSR &= ~(1 << WDRF);
wdt_disable();