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
was sind denn diese 'push' und 'pop' Befehle, die kenne ich noch nicht, kannst du sie mir kurz erklären, ansonsten euch beiden: Vielen Dank !
mh jetzt erscheint die 0 aber ich wollte das es auf 9 hochzählt, wie schaffe ich das ?
... da kann man nur das tut zur asm-Programmierung empfehlen :http://www.avr-asm-tutorial.net/avr_de/index.html
@pumann Würde ihm auch nur helfen, wenn er einen AVR benutzen würde. So wie es scheint, ist es ein 8051er. Mfg Sascha
@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
ach ja, hab mich glaub ich geirrt, es müsste korrekt push acc pop acc heißen! probier das mal aus! mfg leo
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
meine favoriten : http://www.erikbuchmann.de/ http://www.goblack.de/desy/mc8051chip/index.html http://www.8052.com ( englisch ) http://www.batronix.com/elektronik/know-how/mikrocontroller-technik.shtml http://www.keil.com/dd/docs/datashts/philips/p51_pg.pdf
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
Hätt ich´s lieber gelassen! Meinte natürlich "CJNE". War schon spät :-) Also, statt "CJNZ A,#10,START" "CJNE A,#10,START" schreiben. Gruß Andi
@ Andi ich habe das jetzt mal ausprobiert aber ich kann kein target bilden weil push a, pop a und MOV SP,#0027h nicht erkannt werden ???
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
@ dirk das programm funktioniert einwandfrei aber ich kann mit dem loop.asm leider nicht viel anfangen
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
na toll, falls etwas unklar ist, melde dich! kannst auch mailen! lg & gute nacht, leo
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
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.