Lauflicht mit interupts

Gast #3126399
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
Angehängte Dateien:
Gast #3127470
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
Angehängte Dateien:
Gast #3127525
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.
#3127868
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.
#3127932
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
}
#3128003
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.
Gast #3128161
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
Angehängte Dateien:
#3128181
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.
Gast #3128418
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
Angehängte Dateien:

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren