Forum: Mikrocontroller und Digitale Elektronik Lauflicht mit interupts


von paulnothu (Gast)


Angehängte Dateien:

Lesenswert?

Hallo alle miteinander,

ich soll von der Schule aus einen ATmega32 programmieren, dabei soll 
ausdrücklich mit Interrupts gearbeitet werden.

Am Port A sind ganz klassisch 8 LEDs angebracht.

Die erste Aufgabe lautet den Port A für 1 Sekunde lang ansteuern und 
dann alle LEDs ausschalten und in einer endlos Warteschleife enden.

Dazu habe ich mal meinen Sourcecode hochgeladen würde mich über Feedback 
freuen.

Die zweite Aufgabe ist eine Interruptserviceroutine zu schreiben, die 
abhängig vom aktuellen Zustand(0-7) die Leuchtdioden im Sekundentakt 
umschaltet, sodass sie ein Lauflicht von rechts nach links ergeben.

Dabei soll wieder der Timer 1 verwendet werden.
Für den Zustand soll eine variable vom Typ unsigned char verwendet 
werden.

Komme bei der zweiten Aufgabe einfach nicht weiter hättet ihr dazu 
irgendwelche Ideen wie man das umsetzen kann?

Schon im voraus vielen Dank für eure Hilfe.

Gruß Paul

von Falk B. (falk)


Lesenswert?

Siehe Interrupt.

von Karl H. (kbuchegg)


Lesenswert?

Deine LED blinkt nur 'zufällig', weil du den µC regelmässig in den Reset 
schickst.

FAQ: Timer

von paulnothu (Gast)


Angehängte Dateien:

Lesenswert?

@ Karl Heinz

Danke für das Feedback habe den Code nochmal überarbeitet und eingekürzt 
hoffe er läuft noch richtig.

Wäre nett wenn da jemand mal drüber schauen könnte.

Gruß Paul

von paulnothu (Gast)


Angehängte Dateien:

Lesenswert?

Hallo alle miteinander
habe mich jetzt auch mal am zweiten Aufgabenteil versucht.

Bin mir nicht sicher ob es funktioniert.

Leider bekomme ich es nicht hin das der Simulator im avr studio 6 mir 
anzeigt ob das Programm das macht was es soll.

Hätte jemand einen Tipp?

Gruß Paul

von Anfänger (Gast)


Lesenswert?

Hallo
Ich denke das ist noch "größerer Unfug". Eine ISR sollte möglichst fix 
abgearbeitet werden und nur den zwingend notwendigen Code enthalten. 
Daran musst du dein Problem ausrichten. Wenn noch nichts zu schalten ist 
musst du ganz fix wieder raus aus der ISR.

von A. F. (elagil)


Lesenswert?

1
    for(z=0;z<8;z++)
2
    {
3
      PORTA=(1<<z);
4
    }

Die for-Schleife läuft mit maximaler Geschwindigkeit (vielleicht 1Mhz), 
sie steht auch noch innerhalb der while-Schleife und wird ständig 
ausgeführt, sobald auch nur ein Mal die ISR aufgerufen wird. Beim ersten 
"tick" läuft also dauerhaft deine Schleife durch, womit es so aussehen 
wird als ob durchgängig alle LEDs leuchten.

Du brauchst weder die while, noch die for Schleife.

Aus Gründen der Übersicht könntest du statt
1
TCCR1B=1<<WGM12;  //Timer 1 mode auf CTC setzen mit Vergleichsregister OCR1A
2
TCCR1B|=1<<CS12;  //Prescaller setzen auf 1024
3
TCCR1B|=1<<CS10;

auch
1
TCCR1B = (1<<WGM12) | (1<<CS10) | (1<<CS12);

schreiben.

von paulnothu (Gast)


Angehängte Dateien:

Lesenswert?

Danke für die Hilfe. Das Problem mit der For Schleife habe ich 
verstanden.

Wenn ich nun aber die While und For  Schleife raus nehme,
habe ich aber doch kein Lauflicht mehr.

Wie realisiere ich das Lauflicht denn sonst?


Gruß Paul

von A. F. (elagil)


Lesenswert?

> Wie realisiere ich das Lauflicht denn sonst?

Deine ISR wird sekündlich aufgerufen, das ist dann deine Schleife mit 
definierter Durchlaufzeit.

Wie in den meisten anderen Schleifen auch, kannst du nun eine Variable 
hochzählen und sie benutzen:
1
#define LEDS 8
2
3
// ...
4
5
ISR(...) {
6
static int z=0;   // static: zahl bleibt für den nächsten schleifendurchlauf erhalten, steht an fester speicherstelle.
7
8
if(++z >= LEDS) {z=0;}    // z wird zuerst erhöht, dann mit LEDS verglichen
9
// wenn du bei der letzten LED angekommen bist, wieder zur ersten springen.
10
11
// benutze das z !
12
13
}

von Falk B. (falk)


Lesenswert?


von Falk B. (falk)


Lesenswert?

@ paulnothu (Gast)

>    mc1fertig.c (1 KB, 5 Downloads) | Codeansicht

Eine Endlosschleife im Interrupt? Nicht wirklich ;-)

>Danke für die Hilfe. Das Problem mit der For Schleife habe ich
>verstanden.

Glaub ich nicht.

>Wenn ich nun aber die While und For  Schleife raus nehme,
>habe ich aber doch kein Lauflicht mehr.

Dann muss man es halt anders machen.

>Wie realisiere ich das Lauflicht denn sonst?

Siehe mein vorheriges Posting. Und lies den Artikel LANGSAM und 
MEHRFACH, denk drüber nach. Ist eigentlich nicht so schwer, das Prinzip 
zu verstehen.

von Christian (Gast)


Lesenswert?

Die while(1) Schleife wird trotzdem benötigt, da das main-Programm nie 
enden darf!
Also while(1) Schleife leer lassen und im Timer Interrupt den Pin 
weiterschalten.

von paulnothu (Gast)


Angehängte Dateien:

Lesenswert?

Ich habe jetzt versucht den Vorschlag von Adrian(vielen Dank dafür) in 
meinen Code zu integrieren.

Bin mir aber nicht sicher das er auch das Lauflicht mit einer Sekunde 
unterbrechung realisiert.

Im avr studio Simulator zeigt er mir das zu mindestens nicht an.

Ist der Source Code so richtig?

Gruß Paul

von A. F. (elagil)


Lesenswert?

paulnothu schrieb:
> Bin mir aber nicht sicher das er auch das Lauflicht mit einer Sekunde
> unterbrechung realisiert.

Tut er nicht ;)

Die Stelle "// benutze das z !" in meinem Code war durchaus ernst 
gemeint :)
Du musst nur noch den Pin Z am gewünschten Port schalten.

Mir ist auch nicht ganz klar, wozu du dein "enum LED" brauchst, es 
scheint keine Verwendung zu finden.

Dir scheint es noch etwas am Grundverständnis zu fehlen, ich kann sehr 
das AVR-Turorial hier empfehlen, es hat mir oft geholfen.

von paulnothu (Gast)


Angehängte Dateien:

Lesenswert?

Mit dem enum hast du recht stammt noch aus einem früheren 
Lösungsversuch. Jetzt erfüllt es tatsächlich keinen Nutzen mehr.


Bin mir nicht sicher wie du das mit dem Pin schalten meinst.
Würde das so lösen:

z = PORTB | ( 1<<PB0 );

ist das so richtig?

Weiß aber nicht wo das in den Code eingebaut gehört.

Könnte jemand meinen Sourcecode vielleicht ergänzen; sodass
ich das Programm mal durch den Simulator laufen lassen kann.

Bräuchte mal wieder ein Erfolgserlebnis.

Gruß Paul

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.