Folgender Code geht erwartungsgemäß in den Power-Down Modus, lässt sich dann aber durch einen low-Pegel an PD3 nicht mehr "wecken".
1 | #include <stdint.h> |
2 | #include <avr/io.h> |
3 | #include <avr/wdt.h> |
4 | #include <avr/sleep.h> |
5 | #include <avr/interrupt.h> |
6 | |
7 | int main(void) |
8 | {
|
9 | wdt_disable(); |
10 | ACSR = (1<<ACD); |
11 | PORTD = 0xFF; |
12 | DDRD = 0xFF; |
13 | TCCR0A = 0; |
14 | TCCR0B = (1<<CS01); |
15 | OCR0A = 124; |
16 | TIMSK0 = (1<<OCIE0A); |
17 | TCCR1A = 0; |
18 | TCCR1B = (1<<CS12) | (1<<CS10); |
19 | OCR0A = 65535; |
20 | TIMSK1 = (1<<OCIE1A); |
21 | LEDpattern = 0; |
22 | sei(); |
23 | while(1) |
24 | {
|
25 | LEDpattern++; |
26 | set_sleep_mode(SLEEP_MODE_IDLE); |
27 | sleep_mode(); |
28 | }
|
29 | }
|
30 | |
31 | ISR( TIMER0_COMPA_vect ) |
32 | {
|
33 | OCR1A += 124; |
34 | PORTD = LEDpattern; |
35 | }
|
36 | |
37 | ISR( TIMER1_COMPA_vect ) |
38 | {
|
39 | PORTD = 0xFF; |
40 | DDRD &= ~(1<<PD3); |
41 | EICRA = 0; |
42 | EIFR = 0; |
43 | EIMSK = (1<<INT1); |
44 | set_sleep_mode(SLEEP_MODE_PWR_DOWN); |
45 | sleep_mode(); |
46 | }
|
47 | |
48 | ISR( INT1_vect ) |
49 | {
|
50 | EIMSK = 0; |
51 | DDRD |= (1<<PD3); |
52 | PORTD = 0x00; |
53 | }
|
Es ist vermutlich der Aufruf von sleep_mode() im interrupt - wieso? http://www.nongnu.org/avr-libc/user-manual/group__avr__sleep.html http://www.atmel.com/images/Atmel-8271-8-bit-AVR-Microcontroller-ATmega48A-48PA-88A-88PA-168A-168PA-328-328P_datasheet_Complete.pdf