Forum: Mikrocontroller und Digitale Elektronik Probleme mit Timer0 (TL0 TH0) beim 8051


von Jens Heruth (Gast)


Lesenswert?

Hallo zusammen, ich weiß nicht ob ich hier richtig bin, aber ich hoffe
ihr könnt mir weiter helfen. Im Rahmen meiner Fortbildung machen wir
auch ein wenig Assemblerprogrammierung auf Basis vom 8051.
Ich verstehe aber noch nicht so ganz den Zusammenhang zw. den THn und
TLn und dem Timer/Zähler. Vielleicht könnt ihr mir an Hand folgender
Aufgabe erklären wie ich TH0 und TL0 berechne. Ich habe ein
Hauptprogramm in dem ich den Timer0 initialisiere und auch den
Interrupt, ein Register auf den Wert 10H setze und dann noch eine
Abfrage einbaue die dann zu einer Schleife wird. Das Unterprogramm hat
eine Verzögerung die über die Dekrementierung von den 10H zusammen
hängt. Ist das Register ungleich 0 dann springe raus, falls Register =
0 dann löse Ereignis aus und setze Register wieder auf 10H.
Die Bedingung für das Unterprogramm lautet:
Timer0 wird als 16bit Timer programmiert und bis zum Überlauf sind
10000 Zählungen durchzuführen.
Jetzt meine Frage: Wie errechne ich die Werte für TH0 und TL0 um auf
die 10000 Zählschritte zu kommen??

von peter dannegger (Gast)


Lesenswert?

Wo ist das Problem ?

Der Timer zählt aufwärts, also einfach mit einer negativen Zahl laden:

mov th0, #high(-10000)
mov tl0, #low(-10000)


Peter

von crazy horse (Gast)


Lesenswert?

65536-10000=55536=0xd8f0
THx=0xd8
TLx=0xf0

kannst du dir aber auch eleganter vom assembler berechnen lassen:
mov TH1, # high(-10000)
mov TL1, #low (-10000)

Hoffentlich ist jetzt Syntax richtig, ist schon lange her :-)

von Jens Heruth (Gast)


Lesenswert?

Hmmm ... ne negative Zahl laden? die Geschichte mit dem #high oder #low
sagt mir nicht viel, sorry.

Laut Musterlösung sollte das dabei heraus kommen:

mov TH0 ,#0D8H
mov TL0 ,#0EFH

Das wäre also zusammengesetzt: D8EF = 55535 , warum nicht 55536 so wie
von dir vorgeschlagen?? (oder ist möglicherweise meine Lösung falsch?)
Oder ist das deswegen, weil ich ja nur bis 65535 zählen kann?

Der Zusammenhang ist mir aber noch nicht ganz klar, da es in unseren
Unerlagen zu dem Thema nicht wirklich viel zu finden gibt.

Kann mir vielleicht noch mal einer in einfachen Worten den Zusammenhang
erklären?

Ich kann aber erst mal selber versuchen drauf zu kommen:

Also mein Ziel ist es 10000 mal zu zählen, bevor es zum Überlauf kommt.
Der Überlauf wäre dann bei 2^16(65536), da ich nur 16bit zur Verfügung
habe (2x8) und bei 2^16 schon die 17. Stelle angesprochen wird, oder?
(Voraussetzung war ja der Betrieb als 16bit-Timer und TL0 und TH0 kann
ich mit je 8bit belegen).
Das heißt jetzt das ich einen Startwert nehmen muß, auf den ich dann
10000 drauf zähle und dann den Überlauf auslöse? oder muß ich jetzt
2^16 - 1 rechnen und davon die 10000 abziehen?


Gruß Jens

von Sebastian (Gast)


Lesenswert?

der überlauf findet statt beim "wechsel" von (2^16 - 1) zu (2^16)
wenn du den windows taschenrechner nimmst, die kiste auf hex und word
stellst und dann "FFFF" eingibst hast du 65535

 65535
-10000
------
 55535 => hex(0xD8EF)

entspricht
TH0 ,#0D8H

und
TL0 ,#0EFH

high und low ist weil der wert ist 16bit breit, dein register aber nur
8
mit high und low teilst du das praktisch in bytes auf
high(byte)+low(byte)(beides 8bit) von einem 16bit word

von peter dannegger (Gast)


Lesenswert?

"die Geschichte mit dem #high oder #low sagt mir nicht viel, sorry."


Wie fängt man bloß mit Assembler an, ohne jemals einen Blick in die
Syntaxbeschreibung getan zu haben ???

Ich kenne keinen einzigen Assembler, der die Funktionen high() und
low() nicht unterstützt.

Aber die Musterlösung deutet ja an, daß selbst Dein Lehrer zu faul dazu
ist.
Assembler können wunderbar rechnen (auch negativ und dezimal), man muß
sie nur lassen.
Diese "Faulheit" wird also sofort bestraft durch unleserliche
kryptische Hex-Hyroglyphen.


Und wenn es ganz genau sein soll, dann mußt Du sogar 5 Zyklen abziehen,
da das Laden und Starten ja schon solange dauert:

mov th0, #high(-(10000-5)) ;2Zyklen
mov tl0, #low(-(10000-5)) ;2Zyklen
setb tr0 ;1Zyklus


Peter

von Jens Heruth (Gast)


Lesenswert?

@Sebastian: Danke für die Erklärung, obwohl das mit dem High und Low
noch etwas unklar ist ... aber der Rest war klasse erklärt und hat mich
dahingehend bestätigt das ich zumindest Ansatzweise etwas begriffen habe
;-)

Hallo Peter,

schön wenn du dich so gut damit aus kennst, aber ich glaube andere zu
verurteilen nur weil sie nicht deinen Wissensstand haben ist in einem
Forum eher nicht angebracht,oder?
Lass mich das mal so erklären, ich mache eine Fortbildung deren
Bestandteil eben Assemblerprogrammierung auf Basis des 8051 ist. Der
Unterrichtsumfang ist nicht gerade groß und auch das Lehrmaterial
begrenzt und ich muß damit klar kommen mit dem was wir dort
"beigebracht" bekommen ... entweder gebe ich mich damit zufrieden
oder hinterfrage eben aus eigenem Antrieb noch ein paar Sachen die
meiner Meinung nur unzureichend erklärt sind und da bin ich eben auf so
ein Forum wie dieses hier angewiesen!

Der Stoff hat die Funktion mit dem Low und High nun mal nicht
beinhaltet. Als Programm arbeiten wir mit der Keil Software µVision2.

Vielleicht hast du ja die Geduld mir das mit dem negativen Wert für TL0
und TH0 noch mal zu erklären, bzw. mir so zu erklären das ich es auch
verstehe.
Kann ich das denn so eingeben? mov TH0, #high(-10000) ? Versteht das
Programm diese Eingabe ohne Hex Umrechnung und kann ich das mit jedem
beliebigen Wert machen?

Gruß
Jens

von Sebastian (Gast)


Lesenswert?

du hast einen 16 bit hex-wert...zahl.. wie auch immer.
in deinem beispiel also sagen wir

0xD8EF

HIGH-->0xD8, un LOW-->0xEF sollte man so eigentlich sehen können

das mit den (-10000) ist eigentlich ganz einfach
um es einfach zu halten nehmen wir mal als beispiel nur 8bit... also
max 255
der aktuelle wert is 0
wenn du jetzt in das register 200 laden willst so  kannst du entweder
200 addieren oder 55 abziehen. um das ganze zu ergründen empfehle ich
die den windows taschenrechner stelle hex und byte ein und teste das
aus. du solltest dich über binäres rechnen informieren um das zu
verstehen. wenn du dir das im taschenrecher in binär anguckst wird es
sicherlich nich klarer. rechen mal 0-1 (im bin modus/byte) und guck was
passiert

von Jens Heruth (Gast)


Lesenswert?

Ja danke, das mit dem Low/High habe ich (glaube ich zumindest) in so
weit schon verstanden was die Sache mit den 8bit bzw. 16bit an geht.

Es war mir bislang nur nicht klar, das ich als Wert #high (-10000)
eingeben kann und der Assembler damit umgehen kann. Ich hatte vorher
bislang nur die Variante mit der Hex Umrechnung gesehen, die auch in
der Lösung genommen wurde. Deswegen war ich etwas irritiert wegen der
Angabe mit dem Wert #high bzw. #low (-10000) und mir war jetzt nicht
klar das ich die 10000 einfach eingeben kann und nicht noch umrechnen
muß.

von peter dannegger (Gast)


Lesenswert?

@Jens

"schön wenn du dich so gut damit aus kennst, aber ich glaube andere
zu
verurteilen nur weil sie nicht deinen Wissensstand haben ist in einem
Forum eher nicht angebracht,oder?"


Nun, für mich ist es eine völlig selbstverständliche Vorgehensweise,
daß man zumindest mal einen Blick ins Manual wirft, ehe man ein neues
Tool verwendet.
Beim Keil ist unter dem Ordner HLP das A51.PDF zu finden, darin ist
alles erklärt.

Das hat überhaupt nichts mit "verurteilen" zu tun, sondern einfach
mit systematischem Herangehen an eine Aufgabe.

Wie Du ja gesehen hast, hast Du Dich damit auch nur selber bestraft,
indem Du ein Problem hattest, welches dann gar keines gewesen wäre.



Peter

von Jens Heruth (Gast)


Lesenswert?

Also da du dich weiterhin bemühst relativ wenig mit vielen Worten zu
sagen macht eine weitere Diskussion mit dir wohl wenig Sinn, aber ich
schreibe trotzdem noch mal.
In der sogenannten Hilfe der Keil Soft ist das Benutzen der Timer
meiner Meinung nach auch nicht nicht wirklich hilfreich erklärt, genau
so wenig wie in unseren Unterlagen (in denen auch die Funktionen High()
Low() nicht behandelt worden sind).
Wenigstens war Sebastian so nett und hat mit einem Beispiel versucht
mir weiter zu helfen ohne dabei überheblich zu wirken ... Ich habe kein
Interesse daran deine Kompetenz anzuzweifeln, aber die Art und Weise wie
du dich gegenüber jemandem verhältst der dir im Bereich Asm weit
unterlegen ist, ist nicht gerade hilfreich. Wenigstens hast du dich
herabgelassen und in deiner ersten Antwort einen Lösungsvorschlag
gemacht, was ich dir auf Grund deiner weiteren Posting wohl hoch
anrechnen muß!?
Die Anzahl der benötigten Zyklen können wir bei unseren Berechnungen
übrigens vernachlässigen ... auch wenn das für dich sicher nicht
Praxisgerecht ist, für UNS ist es aber eine weitere Tatsache ... genau
so wie der deiner Meinung nach "faule" Lehrer, mit dem wir aber leben
müssen.

Gruß
Jens

von peter dannegger (Gast)


Lesenswert?

"Die Anzahl der benötigten Zyklen können wir bei unseren Berechnungen
übrigens vernachlässigen ... auch wenn das für dich sicher nicht
Praxisgerecht ist"


Praxisgerecht ist es immer, wenn man sich darüber Gedanken macht, ob
man es vernachlässigen kann oder nicht.

Die A51.PDF bezog sich doch nur auf Deine Frage zu den Syntaxelementen
"high" und "low".

Zu Fragen bezüglich der Timer muß man natürlich die Datenblätter und
Application-Notes konsultieren, z.B.:

ftp://download.intel.com/design/mcs51/applnots/01502a01.pdf

http://www.atmel.com/dyn/resources/prod_documents/doc4316.pdf


Peter

von Thomas (Gast)


Lesenswert?

Peter hat vollkommen recht wenn er dir die Lösung High und Low
als Lösung angeboten hat Der Syntax und die Beschreibung steht
im a51.pdf. Was der Assembler daraus macht kann man wunderbar
im .LST file anschauen.
Timer beschreibungen stehen im Datenblatt zum Controller.
Leider ist es halt so dass auch viele Lehrer meist nicht viel mehr
wissen deshalb solch obskuren Musterlösungen
Auch wenn alles in Englisch ist gewöhn dich schon mal dran :-)
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.