LED data 090h
mov a,#010h
start:
mov dptr,#tabelle
inc a
movc a, @a+dptr
mov LED,a
call zeit
zeit:
mov 08h,#255
loop1: mov 01h,#255
loop2: djnz 01h,loop2
djnz 08h,loop1
ljmp start
tabelle:
db 3fh, 06h, 5bh, 4fh
db 66h, 6dh, 7dh, 07h
db 7fh, 6fh
END
Ich versuche das eine 7-Segment Anzeige auf 9 zählt, kann mir jemand
sagen, wo mein Fehler ist?
hier:
movc a, @a+dptr
a hat am Anfang den Wert 10h, dann erhöhst du und hast somit 11h.
Die Tabelle hat aber kein 17 Einträge !
Du musst a auf 0 setzen und vor movc a, @a+dptr sichern, denn nach movc
a, @a+dptr steht in a der Wert aus der Tabelle.
UND AUSSERDEM SOLLTEST DU DAS UNTERPROGRAMM
'zeit:' mit einem 'RET' - Befehl beenden wenn du es
mit 'call' aufrufst!
d.h.:
LED data 090h
mov a,#0FFh ; damit a beim nächsten inc 0 wird
start:
mov dptr,#tabelle
inc a
push a
movc a, @a+dptr
mov LED,a
pop a
call zeit
ljmp start
zeit:
mov 08h,#255
loop1: mov 01h,#255
loop2: djnz 01h,loop2
djnz 08h,loop1
ret
tabelle:
db 3fh, 06h, 5bh, 4fh
db 66h, 6dh, 7dh, 07h
db 7fh, 6fh
END
mfg leo
@Sascha:
bei "ihm" scheint es sich dem Namen nach um eine Sie zu handeln.
@Christine
Mit push wird ein Wert auf den Stack gelegt. Mit pop wieder
zurückgeholt. Sieh Dir dazu mal detailliert Tutorials über den Stack
des 8051 an.
push acc ; legt den Inhalt des Akkus auf den Stack
.... ; mach irgendwas anderers z.B. Akku erhöhen
pop acc ; hole den Akkuinhalt zurück
je nach Assembler kann acc auch, wie bei Dir, a heissen.
Sorry, habe im Moment keine Zeit das detailliert mit dem Stack zu
erklären.
Grüße
Andreas
also das mit dem push und pop funktioniert nicht, wenn ich das target
bilde meldet es fehler, aber ich habe am anfang auch nichts includ ...
gemacht,
es erscheint eine 0 aber sonst passiert leider nichts
Meiner Meinung nach kann das ganze nicht funktionieren.
Du erhöhst a durch inc a. Und wann soll die Schleife beendet werden.
Nach dem 10. Durchlauf wird über das Ende von "Tabelle" hinaus
zugegriffen.
irgendwo muss ein Vergleich mit a >= 10d sein und dann wieder von
Anfang an gestartet oder komplett gestoppt werden.
Sonst läuft a bis FFh und dann wieder von 0 los.
Ausserdem verstehe ich nicht den Inhalt von "Tabelle". Wie ermittelt
sich daraus das entsprechende Zeichen für die Werte 0-9.
Im Moment sehe ich nur, daß der Wert aus Tabelle auf die Adresse 90,
also Port 1, gelegt wird. Wenn ich mich richtig an meine
7-Segment-Displays erinnere, benötigten die den Wert BCD-mäßig. Sorry
für die blöde Anmerkung. Habe schon länger nicht mehr damit
gearbeitet.
Welchen Assembler benutzt Du. Du sagst es gibt Fehlermeldungen. Aber
welche?
Grüße
Andreas
AndreasH hat Recht! Es muss ein Vergleich gemacht werden,
außerdem sieht es danach aus, als käme er vom Unterprogramm 'call'
nicht mehr zurück!
Probier mal, dass du am Anfang schreibst:
ORG 0
MOV SP, #0027h
mfg leo
@ leo
was bewirkt das org und das mov spa,
was genau ist das ?
@ andreas
ich verwende den at89S8252
mh ich versuche jetzt mal das mit einer abfrage weil sonst geht es ja
unendlich so weiter
Gib mal nur
LED data 090h
mov a, #3Fh
mov LED,a
Loop: ajmp Loop
ein. Jetzt muß die 0 angezeigt werden. Wenn dies funktioniert, bist
du schon recht weit.
Josef
Bei den 8051 kann man doch mit CJNZ vergleichen (Compare) und bei
Ungleichheit wo hin springen.
Z. B. mit:
CJNZ A,#10,START
Prüfe, ob A=10, wenn nicht, dann zu Start wenn ja, dann nächster
Befehl.
Probiere doch mal folgendes:
LED data 090h
MOV SP,#0027h
reset:
mov a,#0FFh ; damit a beim nächsten inc 0 wird
start:
mov dptr,#tabelle
inc a
push a
movc a, @a+dptr
mov LED,a
pop a
call zeit
CJNZ A,#10,START ;Zu Start, wenn A <> 10
LJMP RESET ;Ansonsten A zurücksetzen (Reset)
zeit:
mov 08h,#255
loop1: mov 01h,#255
loop2: djnz 01h,loop2
djnz 08h,loop1
ret
tabelle:
db 3fh, 06h, 5bh, 4fh
db 66h, 6dh, 7dh, 07h
db 7fh, 6fh
END
Bin eigentlich ein AVR´ler aber zu den 8051 schiele ich schon ne weile
rüber.
Gruß
Andi
Ich meinte eigentlich mit welchen Assembler Du benutzt nicht den
Controller sondern eben welchen Assembler/Compiler.
Wenn Du sagst "Target", kann es sein dass Du den Keil meinst.
Die Idee von Josef:
mov a, #3Fh
mov LED,a
Loop: ajmp Loop
ist nicht schlecht. Das Problem ist nur, daß sie ständig die 0
angezeigt bekommt und kein Target gebildet wird. Ich vermute, da ist
was im Quellcode falsch und das assemblieren klappt nicht.
Außerdem die Frage, welche Werte braucht die BCD-Anzeige um 0/1...9
anzeigen zu können. Hier könnte auch noch ein Fehler liegen. Woher
kommen die Werte in "Tabelle".
Grüße
Andreas
ja ich verwende keil
die Hex-Zahlen für 1,2,3,4... haben wir in der Schule zusammen
herausgefunden die stimmen ich habe jetzt den Code und es wird nur die
0 angezeigt:
LED data 090h
mov r4,#0ffh
start:
mov dptr,#tabelle
mov a, r4
inc a
movc a, @a+dptr
mov LED,a
call zeit
cjne a, #09h , start
ljmp start
zeit:
mov 08h,#255
loop1: mov 01h,#255
loop2: djnz 01h,loop2
djnz 08h,loop1
ret
tabelle:
db 3fh, 06h, 5bh, 4fh
db 66h, 6dh, 7dh, 07h
db 7fh, 6fh
END
irgendwie zählt es einfach nicht hoch
Es geht hier doch um eine 7-Segment-Anzeige und nicht um ein LCD.
Anscheinend ist das so aufgebaut das ein High-Bit ein Segment zum
leuchten bringt.
Hier mal in Binär aufgeschlüsselt:
3fh = 00111111 = 0 , 6 Segmente leuchten
06h = 00000110 = 1 , 2 Segmente leuchten
5bh = 01011011 = 2 , 5 Segmente leuchten
4fh = 01001111 = 3 , 5 Segmente leuchten
66h = 01100110 = 4 , 4 Segmente leuchten
6dh = 01101101 = 5 , 5 Segmente leuchten
7dh = 01111101 = 6 , 6 Segmente leuchten
07h = 00000111 = 7 , 3 Segmente leuchten
7fh = 01111111 = 8 , 7 Segmente leuchten (alle)
6fh = 01101111 = 9 , 6 Segmente leuchten
Von da her stimmen die LED-Daten.
@Christine:
Wenn Du schon R4 benutzt, dann mußt Du auch dieses verarbeiten statt
den Accu.
Z. B.:
LED data 090h
Reset:
mov r4,#0ffh
start:
mov dptr,#tabelle
inc r4 ;R4 erhöhen, nicht A
mov a, r4
movc a, @a+dptr
mov LED,a
call zeit
mov a,r4 ;Zum Prüfen auf 10 R4 nach A
cjne a, #09h , start ;Ist A(R4) = 9? Wenn nicht, dann zu Start
ljmp Reset ;Ansonsten zu Reset. R4 auf den Startwert
Gruß
Andi
hallo,
ich habe mal ein programm geschrieben zu dein problem ...
ist in as31 unter linux entwickelt, sollte aber auch übertragbar sein.
im simulator ist es gelaufen ohne probleme.
CA
hallo christine
das mov sp, #0027h
bewirkt, dass der stackpointer (SP) auf einen gültigen wert
initialisiert wird. wenn dein compiler sp nicht erkännt, musst du aus
dem datenblatt die hexadresse von SP ermitteln und sie anstatt von SP
einsetzen!
wenn du das nicht machst kannst du ev. keine unterprogramme aufrufen,
wie z.B. 'call'!!!! das ist vielleicht der grund warum er aus dieser
routine nicht mehr zurückfindet!
außerdem musst du schreiben:
push acc
pop acc
und nicht
push a
pop a
weil: für push und pop muss 'acc' und nicht 'a' angegeben werden!
ein bisschen komisch aber es ist so!
Hast Du denn immer noch den Fehler daß Dein Target nicht gebildet wird?
Dann liegt das Problem nämlich erstmal ganz woanders. Du bekommst schon
gar kein lauffähiges Programm assembliert bzw. gelinkt.
Wenn er z.B. den SP nicht kennt, fehlt ein komplettes include-file.
Habe im Moment hier nur den Keil für den C251 und nicht für den 8051.
Daher kann ich Dir nicht sagen wie das heisst. Ich meine aber es gibt
sogar beim Keil eins für den AT89S8252.
Ich habe vor mehreren Monaten was mit dem Keil in Assembler gemacht.
Ich meine dass heisst dann push acc statt push a.
Ausserdem könnstes Du dann statt:
LED data 090h
LED data P1 oder so ähnlich schreiben. Ist kein Fehler, sieht aber
einfach schöner aus.
Erst wenn Dein Programm fehlerfrei assembliert/compiliert kannst Du
anfangen im Quellcode fehler zu suchen.
Das schöne am Keil ist, dass Du in Deiner Zielhardware debuggen kannst.
Dann siehst Du solche Fehler wie die unendliche Schleife oder dass er
über die Tabelle hinausgreift direkt. Vorausgesetzt Du hast das
Monitereprom drin.
Grüße
Andreas
Sorry,
Leopold und mein Beitrag haben sich überschnitten.
Klar geht das mit der hex-Adresse. ISt aber unsauberer Programmierstil
und zum anderen kennt der Keil die Bezeichnungen für den Stack.
Der muß auf jeden Fall initialisiert sein, sonst gehen die Calls
daneben.
ok christine,
hab kurz ins datenblatt gesehen... schreib mal:
SP equ 081h
ACC equ 0E0h
LED data 090h
mov SP,#0027h
reset:
mov a,#0FFh ; damit a beim nächsten inc 0 wird
start:
mov dptr,#tabelle
inc a
push ACC
movc a, @a+dptr
mov LED,a
pop ACC
call zeit
cjnz a,#10,start ;Zu Start, wenn A <> 10
ljmp reset
zeit:
push 08h
push 01h
mov 08h,#255
loop1: mov 01h,#255
loop2: djnz 01h,loop2
djnz 08h,loop1
pop 01h
pop 08h
ret
tabelle:
db 3fh, 06h, 5bh, 4fh
db 66h, 6dh, 7dh, 07h
db 7fh, 6fh
END
sag bescheid wies läuft!
mfg leo
hallo christine,
wenn du mit den asm-file nix anfangen kannst recht es einfach mal die
komentare zu lesen mit einen text-editor, ich denke mal dann kommt ein
bischen licht ins dunkle. Es sollte dann auch kein problem sein das auf
dein programm deiner wahl zu übertragen.
CA
@ all
vielen dank ihr habt mir sehr geholfen !
@leo danke das programm funktioniert wirklich :-)
ich versuche jetzt alles nachzuvollziehen und dann eventuell bis 99
zählen zu können
Ich versuche jetzt mein Programm weiter zu entwickeln,
sodass mein Zähler auf 99 Zählen kann, aber ich habe Probleme
mit der Ansteuerung der anderen 7Segment Anzeigen.
Also auf der Platine sind 4 7Segmentanzeigen und zwei
Ports. Das eine Port wählt automatisch die erste
Anzeige aus und das andere Port da muss man irgendwas
setzten um die anderen Anzeigen anwählen zu können, es
ist sozusagen das Steuerport,
hast du vielkleicht eine Ahnung?
Über das "Steuerport" muß das ganze nun gemultiplext werden.
Da wird das "Zählen" total zur Nebensache und Du mußt Dich nun auf
die Darstellung einer 16Bit-Zahl per Timer-Multiplexer und
Binär-BCD-Wandlung konzentrieren.
Gruß
Andi
Im groben kann man das so machen:
1. Main-Programm: Wert hochzählen oder aktuallisieren so ungefähr
wie gehabt.
2. Aktuallisierten (hochgezählten) Wert zu einem Unterprogramm
schicken (Binär zu BCD) und dem die einzelnen 4 Ziffern ermitteln
lassen.
Diese einzelnen Ziffern sollten in 4 einzelne RAM-Bytes
gespeichert werden.
Also 1 Byte für die 1000´er-Stelle, 1 für die 100´er-Stelle,
10´er Stelle und 1´er Stelle.
3. Du mußt ein Interrupt-Programm (Timer-Interrupt) mit ca. 200Hz
erstellen welches die einzelnen 7-Segment-Dinger am Steuerport der
Reihe nach aktiviert (multiplext), sich die zugehörige
Ziffer für die 1000´er- 100´er-Stelle etc. im RAM abholt und dann
per gehabter Tabelle ausgibt.
Das ganze ist nicht so einfach und ich kann Dir leider kein fertiges
Programm dafür geben (AVR-User).
Aber so in der Art funktioniert das.
Google einfach ein bißchen nach "8051 7-Segment multiplexen" etc.
Wirst schon noch drauf kommen.
Gruß
Andi