Forum: Compiler & IDEs Anfängerfehler (?) mit Interrupts


von Thomas B. (thomasbarends)


Angehängte Dateien:

Lesenswert?

Hallo Alle,
Hier eine Frage eines blutigen Anfängers: ich habe eine ATMEGA32 die ich 
versuche als Funktionsgenerator ein zu setzen (schien mir ein schönes, 
ausbaufähiges Anfängerprojekt; erst mal einen Sinus erzeugen, dann 
Tasten anschliessen um Frequenz etc. zu ändern, später noch ein Display, 
usw. Ausserdem konnte ich existierenden Code aus einem Buch einfach 
"klauen").

Das programm schickt digitale Werte an PORTB die dann von einer 
R2R-Leiter in einem analogen Signal umgewandeld werden. Das Funktioniert 
alles noch. So weit, so gut.

Jetzt habe ich an den INT0 und INT1-pins Tasten angeschlossen (über eine 
einfache Entprellbeschaltung) und ISRs definiert, die die Frequenz und 
die Form des Signals ändern sollen, wenn eine Taste gedrückt wird (der 
Pin wird durch drücken der Taste auf Hoch geschaltet). Dazu habe ich die 
volatile ints "waveform" und "step" definiert, die im Hauptprogramm die 
Signalform und die Frequenz beeinflüssen. (siehe Code im Anhang). Auch 
dachte ich die entsprechenden Bits in MCUCR und GIMSK richtig gesetzt zu 
haben... Auch sind die Interrupts "enabled" mit sei() und tauschen ISRs 
und Hauptprogramm Daten nur aus über volatile ints.

Jetzt habe ich aber ein komisches Problem - wenn ich das ganze 
einschalte passiert erst mal gar nichts, bis ich die INT0-Taste drücke. 
Dann bekomme ich, solange die Taste gedrückt ist, ein Dreieckssignal. 
Lasse ich die Taste wieder los, passiert nichts mehr.

Ich habe warscheinlich etwas ganz einfaches falsch gemacht, und wäre für 
jede Hilfe sehr dankbar.

Viele Grüsse,

Thomas

von Peter II (Gast)


Lesenswert?

cli();
und sei(); solltest du nicht in der ISR aufrufen!

ich kann mir vorstellen das der speicher nicht ausreicht. Du verwendest 
schon 3*256*2 = 1536byte und der Atmege hat nur 2048. Aber C braucht 
auch noch platz für den Stack und in paar variablen.

von immer das gleiche (Gast)


Lesenswert?

1
{
2
    cli();
3
    waveform=waveform+1;
4
  if (waveform>5)
5
  {waveform=1;}
6
    sei();
7
}
cli und sei restlos streichen, das geht automatisch.
1
ISR(INT1_vect)
Hier auch.
1
volatile int waveform = 1;
2
volatile int step = 0;
Mach da mal uint8_t (stdint.h) draus, ansonsten muss der Zugriff atomar 
erfolgen.

von Stefan E. (sternst)


Lesenswert?

1
#define outp(a, b) b = a
2
...
3
  outp((1<<ISC01)|(1<<ISC00), MCUCR); // trigger int0 on rising flank
4
  outp((1<<ISC11)|(1<<ISC10), MCUCR); // trigger int1 on rising flank
Das funktioniert so nicht.

Der Sinn dieses Makros erschließt sich mir sowieso nicht. Das ist doch 
ein reines "Verschleierungs-Makro", das noch nicht einmal Tipparbeit 
einspart.

von Thomas B. (thomasbarends)


Lesenswert?

Mir ist der Sinn eigentlich auch nicht klar, habe es jetzt mal in
1
GIMSK = (1<<INT0)|(1<<INT1);
2
MCUCR = (1<<ISC01)|(1<<ISC00)|(1<<ISC11)|(1<<ISC10);

geändert, und die von den Anderen gemachten Korrekturen durchgeführ, und 
jetzt funktioniert es!

Es war also nicht nur einen, sondern gleich mehrere Anfängerfehler.... 
:)

Vielen Dank an alle,

Thomas

von Tipp (Gast)


Lesenswert?

Schön das es läuft. Hier noch ein paar Anregungen:
- die Felder können als uint8_t definiert werden. Das spart reichlich 
Speicher.
- die Felder können als const im FLASH verschwinden, wenn RAM knapp 
wird.
- die Ausgaben in den while Schleifen sollten im Timer Interrupt laufen. 
Das aktive Warten fällt weg und es bleibt Zeit für Weiteres.
- die Tasten können in der main loop gepollt werden. Das erlaubt eine 
einfache SW Entprellung.

von Thomas B. (thomasbarends)


Lesenswert?

Danke!
Das erste habe ich eingebaut, es spart gewaltig Speicher! An den beiden 
anderen Sachen bin ich dran.

Frohe Ostern,

Thomas

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.