【问题标题】:Watchdog resets AVR Atmega 1281 continuously once triggered看门狗一旦触发就会连续重置 AVR Atmega 1281
【发布时间】:2016-06-25 09:42:44
【问题描述】:

我正在使用经过修改的 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 通电时运行良好,但是当我发送一个字符来调用看门狗复位(“r”或“R”)时,RST_PIN 设置为 HIGH(表示中断已触发),然后在复位,但板上的 LED 指示灯亮。一旦处于这种状态,按下重置按钮不会再重置 MCU,直到我从板上移除电源。此外,如果我连续按下复位按钮,当我不小心触摸到复位按钮旁边的一个 ICSP 引脚时,板上的 LED 指示灯会变暗并开始闪烁。

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

我在 Atmega328 MCU 上上传了相同的代码,但它工作正常。我想这个问题存在于较新的芯片上,因为在系统重置后看门狗仍然使用默认值启用。

我错过了什么吗?问题是特定的硬件吗?

【问题讨论】:

    标签: arduino avr atmega watchdog


    【解决方案1】:

    那是因为您的 Arduino 引导加载程序在您的主应用程序之前运行。当引导加载程序启动时,WDT 仍处于启用状态并设置为 minimal 周期 16ms。数据表说:

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

    您需要修改引导加载程序以在重置时禁用 Watchdog,或者在您的主​​应用程序中忘记 Watchdog。

    更新要在引导加载程序中禁用 WDT,请尽快执行以下代码:

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-06-21
      • 1970-01-01
      • 1970-01-01
      • 2021-09-11
      • 1970-01-01
      • 2021-11-12
      • 2014-07-13
      • 1970-01-01
      相关资源
      最近更新 更多