Hallo
Es wird auf Mikrokontroller die Funktion sleep und Interrupt
vorgestellt.
Dabei wird dieses Programm für den Atmega32 als Beispiel angegeben:
1 | /*************************************************************************
|
2 | * Sleep Mode Demo, Power Down Mode ATmega32 mit internem 1 MHz Oszillator
|
3 | * LOW Fuse Byte = 0xE1 An PD5 muss eine LED mit 1 kOhm Vorwiderstand angeschlossen werden An PD2 muss ein Taster gegen GND angeschlossen sein
|
4 | *************************************************************************/
|
5 | #define F_CPU 1000000
|
6 | #include <avr/io.h>
|
7 | #include <avr/sleep.h>
|
8 | #include <avr/interrupt.h>
|
9 | #include <util/delay.h>
|
10 | // lange, variable Wartezeit, Einheit in Millisekunden
|
11 | void long_delay(uint16_t ms)
|
12 | {
|
13 | for (; ms>0; ms--) _delay_ms(1);
|
14 | }
|
15 | int main (void)
|
16 | { // IO konfigurieren
|
17 | DDRA = 0xFF;
|
18 | DDRB = 0xFF;
|
19 | DDRC = 0xFF;
|
20 | DDRD = 0xFB; // PD2 = INT0 = Eingang
|
21 | PORTD = 0x04; // Pull Up aktivieren
|
22 | // Analogcomparator ausschalten
|
23 | ACSR = 0x80;
|
24 | // Interrupt konfigurieren
|
25 | MCUCR &= ~0x3; // levelgesteuerter Interrupt an INT0
|
26 | // Interrupts freigeben
|
27 | sei();
|
28 | // Endlose Hauptschleife
|
29 | while(1)
|
30 | {
|
31 | GICR |= (1 << INT0); // externen Interrupt freigeben
|
32 | set_sleep_mode(SLEEP_MODE_PWR_DOWN);
|
33 | sleep_mode(); // in den Schlafmodus wechseln
|
34 | // hier wachen wir wieder auf
|
35 | GICR &= ~(1 << INT0); // externen Interrupt sperren
|
36 | // WICHTIG! falls der externe LOW Puls an INT0 sehr lange dauert
|
37 | PORTD |= (1 << PD5); // LED für eine Sekunde anschalten
|
38 | long_delay(1000);
|
39 | PORTD &= ~(1 << PD5);
|
40 | }
|
41 | }
|
42 |
|
43 | // externer Interrupt INT0
|
44 | // Die Interruptroutine kann leer sein, ABER sie muss existieren! Sonst springt der AVR nach // dem Aufwachen zum Reset, weil kein sinnvoller Interruptvektor eingetragen ist!
|
45 | ISR(INT0_vect)
|
46 | {
|
47 | }
|
Versuche dieses Programm nun für den Attiny841 zu übersetzen.
Dabei liegt die LED auf PA3 und der Taster auf PB2 (nach GND).
Da die Bezeichnungen der einzelnen Register sich wieder unterscheiden
oder eben anders sind, klappt es nicht. Mein Code bisher:
1 |
|
2 | #define F_CPU 16000000UL // Angabe der Frequenz, wichtig für die Zeit
|
3 | #include "util/delay.h" // Einbindung Datei Pause
|
4 | #include "avr/io.h" // Einbindung Datei Ausgänge
|
5 | #include "avr/sleep.h"
|
6 | #include "avr/interrupt.h"
|
7 |
|
8 | int main (void)
|
9 | { // IO konfigurieren
|
10 | DDRA=0b00001000; // DDR A auf Ausgang schalten
|
11 | PORTA=0b00001000; // Port A auf aus
|
12 | DDRB = 0b00000000; // PD2 = INT0 = Eingang
|
13 | PORTB=0b00000000; // Port A auf aus
|
14 | // Interrupt konfigurieren
|
15 | MCUCR |= (1<<ISC01)|(1<<ISC00); // levelgesteuerter Interrupt an INT0
|
16 | // Interrupts freigeben
|
17 | sei();
|
18 | // Endlose Hauptschleife
|
19 | while(1)
|
20 | {
|
21 | GIFR |= (1 << INT0);
|
22 | PCMSK1 |= (1 << PCINT10); // externen Interrupt freigeben
|
23 | set_sleep_mode(SLEEP_MODE_PWR_DOWN);
|
24 | sleep_mode(); // in den Schlafmodus wechseln
|
25 | // hier wachen wir wieder auf
|
26 | GIFR &= ~(1 << INT0);
|
27 | PCMSK1 &= ~(1 << PCINT10); // externen Interrupt sperren
|
28 | // WICHTIG! falls der externe LOW Puls an INT0 sehr lange dauert
|
29 | PORTA |= (1 <<PINA3); // LED für eine Sekunde anschalten
|
30 | _delay_ms(1000);
|
31 | PORTA &= ~(1<<PINA3);
|
32 | }
|
33 | }
|
34 |
|
35 | ISR(INT0_vect)
|
36 | {
|
37 | }
|
Habe versucht die Änderungen aus dem DB des Attiny841 korrekt
umzusetzen, leider ohne Erfolg.
Kann mir jemand helfen den fehler zu finden?