ATtiny88初体验(四):看门狗
ATtiny88初体验(四):看门狗
ATtiny88单片机的看门狗使用内部独立的128KHz时钟源,拥有3种工作模式:
- Interrupt模式:超时产生中断;
- System Reset模式:超时产生系统复位;
- Interrupt & System Reset模式:超时产生中断,中断处理完成后产生系统复位。

当熔丝位 WDTON 被编程时(值为0),将强制将看门狗设为System Reset模式,此时 WDE 和 WDIE 位将被锁定为 1 和 0 。
清除 WDE 位和修改 WDP 需要按照下面的顺序进行操作:
- 向
WDCE和WDE位写1,不管WDE位先前是什么值,都必须写1。 - 在接下来的4个时钟里,修改
WDE和WDP位,清除WDCE位,这些必须在一次操作内完成。
注意:
- 为了防止程序陷入复位循环,不管有没有用到看门狗,在初始化时,都建议清除
WDRF标志位和WDE位。 - 在任何对
WDP位的修改之前,建议都复位看门狗,否则可能会导致意外的复位。
寄存器

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

WDIF:看门狗中断标志位。WDIE:看门狗中断使能。WDCE:看门狗修改使能,只有设置此位,才能修改WDE和WDP位。WDE:看门狗系统复位使能。

WDP[3:0]:看门狗定时器分频。

代码
代码的文件结构如下:
.
├── 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的输出状态。
参考资料
- ATtiny88 Datasheet