Hallo liebe Forengemeinde,
ich bin Anfänger im Mikrocontroller Bereich und arbeite grade das
Tutorial zu diesem Forum durch.
Momentan bin ich bei dem Kapitel: "Die Timer: Uhr und CTC Modus."
angelangt
und komme beim Versuch das Beispielprogramm in das AVR-Studio zu
übernehmen nicht weiter.
Sobald ich das Beispielprogramm (im Anhang "uhrtest.asm") assemblieren
möchte erhalte ich die folgenden beiden Errors:
C:\(Dateipfad)\uhrtest.asm(108): error: Duplicate label: 'lcd_number'
C:\Programme\Atmel\AVR
Tools\AvrAssembler2\Appnotes\lcd-routines.asm(170): info: previous
definition of 'lcd_number'
C:\(Dateipfad)\uhrtest.asm(117): error: Duplicate label: 'lcd_number_1'
C:\Programme\Atmel\AVR
Tools\AvrAssembler2\Appnotes\lcd-routines.asm(179): info: previous
definition of 'lcd_number_1'
Assembly failed, 2 errors, 4 warnings
Wenn ich das richtig verstehe sind die Labels "lcd_number" und
"lcd_number_1" zwei mal vorhanden. Wenn ich mir die lcd_routines.asm
(befinden sich auch im Anhang) anschau stimmt das auch.
Das Programm "uhrtest.asm" habe ich aus dem Tutorial herauskopiert und
die LCD-Funktionen ("lcd_routines.asm")stammen ebenfalls
aus dem Tutorial (Kapitel LCD)
Im Uhr-Tutorial wird erwähnt, dass die aus dem Kapitel "LCD" stammenden
lcd-Funktionen verwendet werden sollen.
Nach meinen verständnis sollten diese also kompatibel sein (?).
Jetzt meine Frage: Wo liegt mein Fehler?
Falls mir jemand einen Tipp geben kann wäre ich sehr Dankbar!
Viele grüße, Leon
Leon schrieb:> Jetzt meine Frage: Wo liegt mein Fehler?
Das sind zwei Ausgaberoutinen mit gleichem Namen, ob kompatibel, hab'
ich mir nicht angesehen. Die Sublabels _1, _2 usw. gehören jeweils zum
Hauptlabel lcd_number. Nur eine der Routinen kann mit gleichem
Labelnamen eingebunden werden, also muss die andere inklusive Sublabels
raus.
... ich hab es mir angesehen !
Ab dem Label "lcd_number" ist ein Unterprogramm enthalten, dessen Zweck
es ist, eine Zahl dezimal auszugeben !
Dem Autor des Uhrenprogramms "uhrtest.asm" ist es entgangen, dass die
Subroutinen in "lcd-routines.asm" ein gleichlautendes Unterprogramm
besitzt.
Leider sind die beiden Unterprogramme in uhrtest.asm und
lcd-routines.asm NICHT kompatibel zueinander:
Das Unterprogramm in lcd-routines.asm gibt den Zahlenwert in Register
"temp1" dezimal 3-stellig mit einer führenden 0 aus (was für eine Uhr
unbrauchbar ist), auf dem Display würde bspw. "023" erscheinen.
Das Unterprogramm in uhrtest.asm gibt auch den Zahlenwert dezimal auf
dem Display aus, diesen jedoch nur 2-stellig. Ein Wert von 48 in temp1
würde auf dem Display tatsächlich "48" escheinen lassen (Werte größer
als 99 in temp1 machen "Murks").
Lösung des Problems (beispielhaft fuer den Anfänger):
Im Programm "uhrtest.asm" alles (inklusive des Labels) lcd_number
löschen und durch folgendes ersetzen:
------------------------------------------------------------------------
----
; Eine Zahl aus dem Register temp1 2 stellig ausgeben
2st_lcd_number:
push temp2 ; register sichern,
; wird für Zwsichenergebnisse
gebraucht
ldi temp2, '0'
2st_lcd_number_10:
subi temp1, 10 ; abzählen wieviele Zehner in
brcs 2st_lcd_number_1 ; der Zahl enthalten sind
inc temp2
rjmp 2st_lcd_number_10
2st_lcd_number_1:
push temp1 ; den Rest sichern
mov temp1,temp2 ;
rcall lcd_data ; die Zehnerstelle ausgeben
pop temp1 ; den Rest wiederherstellen
subi temp1, -10 ; 10 wieder dazuzählen, da die
; vorhergehende Schleife 10 zuviel
; abgezogen hat
; das Subtrahieren von -10
; = Addition von +10 ist ein Trick
; da kein addi Befehl existiert
ldi temp2, '0' ; die übrig gebliebenen Einer
add temp1, temp2 ; noch ausgeben
rcall lcd_data
pop temp2 ; Register wieder herstellen
ret
------------------------------------------------------------------------
--
Alle Aufrufe von "rcall lcd_number" zwischen
loop:
und
rjmp loop
durch
"rcall 2st_lcd_number" ersetzen !
Die Anführungszeichen natürlich weglassen !
Riesen Dank schonmal!
Also lag es wohl doch nicht direkt an mir.
Nachdem ich alle Labels im Programm "uhrtest.asm" geändert habe kam bei
der neuen Benennung "2st_lcd_number" usw. eine neue Fehlermeldung, also
änderte ich sie auf "st_lcd_number" usw. (also ohne die 2 davor)
Jetzt sind die Fehlermeldungen schonmal verschwunden.
Es blieben noch 4 Warnungen über, die verschwanden als ich in den
LCD-Routinen die Umbenennungen der Register einfach gelöscht hab.
.def temp2 = r22
.def temp3 = r23
War ja schließlich doppelt gemoppelt.
Jetzt läuft die Uhr sogar, leider braucht sie für 10 Sekunden ca. 39
Sekunden.
Fehler in meinem Testaufbau sind natürlich möglich, vermutlich ist mein
Oscillator falsch eingestellt (?).
Die fast funktionierenden Codes hab ich Angehängt.
Als Blutiger Anfänger werde ich wohl nicht an dem Tutorial rumtüfteln um
nicht an 2 fronten gleichzeitig kämpfen zu müssen.
Vielen Dank nochmal!
Leon schrieb:> Jetzt läuft die Uhr sogar, leider braucht sie für 10 Sekunden ca. 39> Sekunden.
Also ein Faktor von ca 1:4
Das Tutorial ist ausgelegt für einen ATMega8, der auf 4Mhz getaktet ist.
Dein µC ist wahrscheinlich noch im 'Takt'-Original Zustand und läuft
wahrscheinlich noch mit 1Mhz. Und schon erklärt sich der Faktor von 1:4
ganz zwanglos.
Da du aber Lernender bist und auch verstanden hast, was du da
programmierst und nicht einfach nur vorhandene Programme in deinen µC
lädst und dich am Eregbnis erfreust, sollte es für dich kein Problem
sein, diese unterschiedliche Taktfrequenz durch Anpassung der Timerwerte
auf 1Mhz auszugleichen.
Ist ein schöner Test, ob du auch tatsächlich verstanden hast, was da im
Programm warum passiert.
> Als Blutiger Anfänger
... solltest du im Tutorial vorne anfangen und lernen! Lernen bedeutet
nicht, dass man sich von einer Web-Seite ein paar Files runterlädt, die
in den µC lädt und sich zurücklehnt und 'so so' sagt.
Hi
Karl Heinz hat recht. Es mag interessant sein, gleich mit einer (wow)
Uhr anzufangen. Aber um das zu verstehen, was da abgeht, ist die
Thematik schon einen Schritt zu weit. Beginn doch erst einmal wie alle
anderen auch mit einer blinkenden LED. Einer LED, die du mit einem
Taster ein- und aussschaltest. Ein Relais, angesteuert wie eine LED,
aber eben mit Treibertransistor und einer Freilaufdiode. Lern zu
verstehen, was Register sind und wie sie genutzt werden. Schau dir die
Befehle an, entweder im Datenblatt oder im AVR Studio unter Hilfe.
Verstehe, was ein Exclusiv-Oder, ein Und-, ein Oder-Befehl bewirkt und
bau nicht gleich als erstes eine Uhr. Wie willst du eine Fehlersuche
machen, wenn dein Programm nicht läuft. Gut, eine Compilermeldung zu
erklären kriegen wir noch hin, aber wenn zur Laufzeit Fehler auftreten,
was dann? Wir werden uns nicht hinsetzen und seitenweise Assemblercode
prüfen, um dann zu sagen, das Problem liegt in Zeile 349.. Wenn ein
Zeittakt nicht passt, ok, das solltest du selbst finden, ist aber für
uns leicht nachvollziehbar. Doch wenn eine LED 3 mal blinkt und dann für
immer aus bleibt, wird es dann schon schwieriger. Und hier auf der
anderen Seite deines Monitors ungleich mehr. Aber vielleicht hast du ja
auch die ersten Schritte abgearbeitet.
Gruß oldmax
Martin Vogel schrieb:> Es mag interessant sein, gleich mit einer (wow)> Uhr anzufangen. Aber um das zu verstehen, was da abgeht, ist die> Thematik schon einen Schritt zu weit. Beginn doch erst einmal wie alle> anderen auch mit einer blinkenden LED.Leon schrieb:> arbeite grade das> Tutorial zu diesem Forum durch.> Momentan bin ich bei dem Kapitel: "Die Timer: Uhr und CTC Modus."> angelangt
Woher wisst Ihr, dass Leon alles im Tutorial vorher übersprungen hat?