mikrocontroller.net

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


Autor: Alex Haydl (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: crazy horse (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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 :-)

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.