Loading

ATtiny88初体验(四):看门狗

ATtiny88初体验(四):看门狗

ATtiny88单片机的看门狗使用内部独立的128KHz时钟源,拥有3种工作模式:

  • Interrupt模式:超时产生中断;
  • System Reset模式:超时产生系统复位;
  • Interrupt & System Reset模式:超时产生中断,中断处理完成后产生系统复位。

image.png

当熔丝位 WDTON 被编程时(值为0),将强制将看门狗设为System Reset模式,此时 WDEWDIE 位将被锁定为 10

清除 WDE 位和修改 WDP 需要按照下面的顺序进行操作:

  1. WDCEWDE 位写1,不管 WDE 位先前是什么值,都必须写1。
  2. 在接下来的4个时钟里,修改 WDEWDP 位,清除 WDCE 位,这些必须在一次操作内完成。

注意:

  1. 为了防止程序陷入复位循环,不管有没有用到看门狗,在初始化时,都建议清除 WDRF 标志位和 WDE 位。
  2. 在任何对 WDP 位的修改之前,建议都复位看门狗,否则可能会导致意外的复位。

寄存器

image.png

  • WDRF :看门狗系统复位标志位。
  • BORF :欠压复位标志位。
  • EXTRF :外部复位标志位。
  • PORF :上电复位标志位。

image.png

  • WDIF :看门狗中断标志位。
  • WDIE :看门狗中断使能。
  • WDCE :看门狗修改使能,只有设置此位,才能修改 WDEWDP 位。
  • WDE :看门狗系统复位使能。
    image.png
  • WDP[3:0] :看门狗定时器分频。
    image.png

代码

代码的文件结构如下:

.
├── Makefile
├── inc
│   ├── serial.h
│   └── serial_stdio.h
└── src
    ├── main.c
    ├── serial.c
    └── serial_stdio.c

其中, src/main.c 的内容如下:

#include <stdint.h>
#include <stdio.h>
#include <avr/io.h>
#include <avr/interrupt.h>
#include <avr/wdt.h>
#include <serial_stdio.h>

static void watchdog_setup(void);

int main(void)
{
    cli();
    DDRD = _BV(DDD0);                   // set PD0 as output
    stdio_setup();                      // initialize stdio
    sei();

    if (MCUSR & _BV(WDRF)) {            // check if watchdog reset
        printf("Watchdog Reset.\r\n");
    }
    if (MCUSR & _BV(BORF)) {            // check if brown-out reset
        printf("Brown-out Reset.\r\n");
    }
    if (MCUSR & _BV(EXTRF)) {           // check if external reset
        printf("External Reset.\r\n");
    }
    if (MCUSR & _BV(PORF)) {            // check if power-on reset
        printf("Power-on Reset.\r\n");
    }
    MCUSR = 0;                          // clear reset flags

    watchdog_setup();                   // initialize watchdog as timer

    for (;;);
}

static void watchdog_setup(void)
{
    cli();
    wdt_reset();                        // reset watchdog counter
    MCUSR &= ~_BV(WDRF);                // clear watchdog reset flag
    WDTCSR = _BV(WDCE) | _BV(WDE);      // enable watchdog change
    WDTCSR = _BV(WDIE) | _BV(WDP2) | _BV(WDP0); // interrupt mode, 0.5s
    sei();
}

ISR(WDT_vect)
{
    uint8_t sreg = SREG;
    PIND = _BV(PIND0);                  // toggle PD0
    SREG = sreg;
}

上述代码将看门狗设置为定时器中断模式,定时周期为0.5s,在中断程序里,翻转PD0的输出状态。

参考资料

  1. ATtiny88 Datasheet
posted @ 2023-08-25 15:24  chinjinyu  阅读(295)  评论(0编辑  收藏  举报