Forum: Mikrocontroller und Digitale Elektronik Hilfe! Verzweifle an Timer: Ist dieser Code in Ordnung (asm)


von Alex Haydl (Gast)


Lesenswert?

Ich bin gerade dabei eine Lichtschranke zu programmieren (mit µC der
8051 - Familie von Atmel) und verzweifle an diesen blöden Interrupt
einsprungaddressen.
Und zwar folgender aufbau:

Ich habe zwei Lichtschranken. Wenn der Körper die erste Lichtschranke
durchquert sendet diese ein 1. Dieses SIgnal aktiviert den Timer.
Dieser Zählt auf 50.000 µSekunden, sprich 0,05 Sekunden und gibt dann
ein Interrupt (TF0) frei.
Wenn ihr Fehler findet bitte sagt sie mir, denn ich habe mit der µC
-Programmierung erst frisch angefangen.

Oder könntet ihr mir einmal einen vorschlag am Quelltext machen wie ihr
eine "Stoppuhr" oder so eine Lichtschranke (ist ja prinzipiell das
selbe) programmieren würde, damit ich mir auch mal eure vorschläge
ansehen könntet.
Ich wäre euch unendlich dankbar für eure Hilfe!!!!

Aber mal der quelltext dazu:


org 000Ch          // Ich bin weitgenug vorne um mit dem
                      Interrupt nicht in Konflikt zu kommen

mov r0, #00h       // Register 0 wird mit "0" beschrieben
mov TMOD, #01h     // In Modus 2 des Timers wechseln (16 - Bit)
setb 0AFh          // Generelle Freigabe aller Interrupts

mov TL0, #0B6h     // Timer0 wird mit dem Startwert 15536d versehen
mov TH0, #03Ch     // sodass er 0,05 Sek. braucht bis er Überläuft.

jb P0.1,Sprung1    // Wenn 2. Bit des P0 = 1 --> zu "Sprung1"

-------------- Hier beginnt eigentliche Lichtschranke -------------

Sprung1:

setb ET0           // Freigeben des Timer0 - Interrupts
setb TR0           // Startbit des Timers gesetzt

jb TF0, Sprung2    // Wenn Überlaufbit des T0 = 1  --> zu "Sprung2"

Sprung 2:

clr TR0            // Timer 0 wird angehalten
clr TF0            // Timer - Interruptbit wird gelöscht

setb TR0           // Timer 0 wird wieder gestartet, denn
                   // 2*0,05 Sek. --> die gewünschten 0,1 Sek

org 000Bh          // Sprung zur T0 - Interrupt Einsprungadresse
inc R0             // Wenn TF0 = 1 wird R0 um 1 erhöht

jb P1.1,Sprung3    // Es wird zu "Sprung3" gesprungen wenn die
                   // andere Lichtschranke "1" ist

Sprung3:

clr TR0            // Timer 0 wird angehalten

von crazy horse (Gast)


Lesenswert?

irgendwie ist das kein Programm:-)
Erstmal was prinzipielles:
Ein Programm für einen 8051 (und viele andere auch) mit einem
Sprungbefehl an Adresse 0 zu einer anderen Adresse, dort beginnt dann
das eigentliche Programm mit allen erforderlichen Grundeinstellungen
(Initialisierung des MC). Das muss eigentlich immer gemacht werden, da
die Hardware-Reset-Einstellungen i.a. nicht das machen, was man gerade
will. Beliebter Anfängerfehler: Setzen des Stackpointers vergessen. Der
wird (fast) immer gebraucht.
Anschliessend an den Reset-Vektor kommen die Sprungadressen für die
diversen Interupts. Ich nehme immer alle Adressen mit rein, als Code
steht da erstmal nur ein reti, wird der Interrupt benutzt, kommt an
diese Stelle ein Sprung zur entsprechenden Interupt-Service-Routine
hin. Die org-Anweisung solltest du erstmal ganz aussen vor lassen,
brauchst du noch nicht oder gar nicht, immer alles symbolisch anweisen,
um die Adressen soll sich der Assembler kümmern, nicht der
Programmierer.
Und fang bitte gar nicht erst an, Sprungmarken mit Sprung1 o.ä. zu
benennen. Dem Assembler ist es egal, was da steht, aber du selbst
findest dich bald nicht mehr zurecht und andere schon gar nicht. Da
sollte man ein Bezeichnung wählen, die schon erklärt, was dort
passiert.
Der Sprung von Adresse 0 heißt bei mir und vielen anderen auch:
jmp reset
.
.
reset: bl bla bla
Ansonsten solltest du dich mit dem Befehlssatz vertraut machen, nicht
nur, wie die einzelnen Befehle heissen, sondern vor allem, was sie
bewirken.
Wenn ich sowas sehe:

jb TF0, Sprung2    // Wenn Überlaufbit des T0 = 1  --> zu "Sprung2"
Sprung 2:
scheinst du nicht verstanden zu haben, wie dieser Befehl funktioniert -
du denkst zu menschlich. Wahrscheinlich hast du dir gedacht, gehe nach
Sprung2, wenn das Bit gesetzt ist, sonst warte.
So funktioniert das aber nicht, ist entsprechende Bit gesetzt, wird der
Sprung ausgeführt, wenn nicht, wird der komplette Befehl ignoriert. Und
so, wie du das geschrieben hast, bewirkt es überhaupt nichts, das
Programm kommt immer an "Sprung2" an, unabhängig von TF0.
Falls du wirklich warten willst, könnte das so aussehen:
warten:
jb TF0, Sprung2 ;springt, wenn TF0=1
jmp warten      ;TF0 war 0, zurück, nochmal prüfen
Sprung2:

besser aber so:
warten: jnb TF0, warten
weiter:

Aber lass dich nicht entmutigen, nochmal überarbeiten, nachdenken,
lesen, andere Programme anschauen, dann wieder hier melden :-)

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.