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.rn"); } if (MCUSR & _BV(BORF)) { // check if brown-out reset printf("Brown-out Reset.rn"); } if (MCUSR & _BV(EXTRF)) { // check if external reset printf("External Reset.rn"); } if (MCUSR & _BV(PORF)) { // check if power-on reset printf("Power-on Reset.rn"); } 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的输出状态。