Hallo, ich habe ein Problem mit meinen Lauflichtprogramm: Aber erstmal was liegt hier vor mir: Ich habe eine Schaltung zur Ausgabe eines Programms vom AT89c2051, 8 Transistoren und 8 LED´s. Nun habe ich folgendes Programm in Assembler: ;Hanse Derby INCLUDE 89c2051.mc init: MOV DPTR,#Tabelle ;Adresse der Tabelle angeben MOV R0,#00h ;Schrittzähler auf 0 start: MOV A,R0 MOVC A,@a+dptr ;Tabellenplatz berechnen if A = #FFh THEN JMP init ;Wenn Tabelle zuende neuanfang MOV P1,A ;Muster Ausgeben call wait_50000 ;Pause INC R0 ;Schrittzähler erhöhen JMP start Tabelle: ;Muster DB 11111001b, DB 11111100b, DB 11110110b, DB 11110011b, DB 11111001b, DB 11111100b, DB 11110110b, DB 11110011b, DB 11111001b, DB 11111100b, DB 11110110b, DB 11110011b, DB 00001001b, DB 00001100b, DB 00000110b, DB 00000011b, DB 00001001b, DB 00001100b, DB 00000110b, DB 00000011b, DB 00001001b, DB 00001100b, DB 00000110b, DB 00000011b, DB 11111111b, ;FFh = Ende der Tabelle INCLUDE wait.asm END so, folgendes Problem: es funktioniert, aber wenn das auszugebene Muster mehr als 256 Zeilen/Schritte umfasst läuft es nicht bis zum Ende, sondern hört bei 256 auf und fängt dann neu an. (Hier nicht der Fall wollte nicht so ein langes Programm rein stellen.) 2.Das reguläre Ende der Tabelle ist dadurch gekennzeichnet, das alle Kanäle leuchten (DB 11111111b,), also gemeinsames Blinken unmöglich, da es dann neu beginnt. 3. Die pause lässt sich nur aunzureichend Abstufen, da sie nur in 50000-Schritten sich veränder lässt. Experimentell ermitellt:(call wait_50000) oder (call wait_100000 ) usw. Wie kann man das feiner abstufen? Wenn ich z.B. 60000 eingebe funktioniert das Programm nicht. 4. Ich habe in der Schaltung Jumper eingebaut, die vier der Inputs von at89c2051 nach - brücken können, nun würde ich gerne 4 Pausen vorgeben können und je nach Jumperstellung sollte mann eine Pause wählen können. Nun ja, fragen über Fragen. Zur Anwendung, Hintergrund: Das programm habe ich irgendwann irgendwo gefunden, ich habe von Assembler keine Ahnung und will auch nur diese eine Schaltung / Programm benutzen. Grund: Ich baue Modelle von Fahrgeschäften und Schaustellerbuden. Um diese nun vorbildgerecht zu beleuchten, brauch ich viel Lauflichtgeräte mit vielen verschieden Mustern, ihr wisst ja alle wie komplex das Lichtspiel im Orginal sein kann. Dazu ist das Obrige programm an sich nicht schlecht, da ich das gewünschte muster direkt einsetzen kann. Wer kann das Programm so weit umschreiben oder ein neues schreiben, das die oben genannten Punkte berücksichtigt werden. Oder wer weis, wer es wissen könnte wenn nicht ihr. Bei Erfolg Spende ich gerne eine Kleinigkeit in die Kaffeekasse des erfolgreichen Entwicklers, es ist sehr wichtig!!! Danke im Vorraus, Bastian Lampe www.modellkirmes-goslar.de
den µC kenne ich jetzt nicht im Detail, aber ich vermute mal das R0 ein 8-Bit Register ist und das läuft nunmal bei 255 über auf 0. Da das Abbruchkriterium der Schleife in den Daten liegt braucht nicht die indirekte Adressierung mit Offset, es sollte reichen den DPTR in der Schleife direkt zu inkrementieren.
Beim 8051 ist das DPTR-Register das einzige 16-Bit Register. Meine 8051er-Zeit ist zwar schon etwas her, aber ich würde nach 255 DBs einen neuen Index setzen, z.B. "Tabelle2:". In Pseudo-Assembler (der Keil konnte sowas IMHO nicht): > if A = #FFh THEN JMP init also quasi: if R0 = #FFh THEN MOV DPTR,#Tabelle2 Und dann beim Ende dieser Tabelle auf die nächste oder zurück auf den Anfang der ersten Tabelle. Vielleicht kommt 8051-Guru Peter ja noch...
@Turboforce Füge als letzten Datensatz #00000000 oder zweimal oder andere nicht vorkomende Bitkombination ein. In der Schleife inkrementierst Du einfach den DPTR (inc DPTR) und prüfst ab ob der letzte Datensatz, das Abbruchkreterium erfüllt und setze deinen DPTR wieder auf den Anfang.
Turboforce wrote: > so, folgendes Problem: es funktioniert, aber wenn das auszugebene Muster > mehr als 256 Zeilen/Schritte umfasst läuft es nicht bis zum Ende, > sondern hört bei 256 auf und fängt dann neu an. (Hier nicht der Fall > wollte nicht so ein langes Programm rein stellen.) Nimm einfach "inc dptr" statt "inc r0" > 3. Die pause lässt sich nur aunzureichend Abstufen, da sie nur in > 50000-Schritten sich veränder lässt. Experimentell ermitellt:(call > wait_50000) oder (call wait_100000 ) usw. > Wie kann man das feiner abstufen? Wenn ich z.B. 60000 eingebe > funktioniert das Programm nicht. Hellsehen kann ich nicht. Du must schon die Wait-Funktion mit posten > 4. Ich habe in der Schaltung Jumper eingebaut, die vier der Inputs von > at89c2051 nach - brücken können, nun würde ich gerne 4 Pausen vorgeben > können und je nach Jumperstellung sollte mann eine Pause wählen können. Mit 4 Jumpern kannst Du 16 verschiedene Pausen vorgeben, z.B.:
1 | get_delay: |
2 | mov a, p3 |
3 | anl a, #0Fh ;nur P3.3 - P3.0 |
4 | add a, acc ; * 2 |
5 | mov r7, a |
6 | mov dptr, #delay_tab |
7 | movc a, @a+dptr |
8 | xch a, r7 ; r7 = delay high byte |
9 | inc a |
10 | movc a, @a+dptr |
11 | mov r6, a ; r6 = delay low byte |
12 | ret |
13 | |
14 | delay_tab: |
15 | dw 1000 |
16 | dw 1400 |
17 | dw 2000 |
18 | dw 2800 |
19 | dw 4000 |
20 | dw 5600 |
21 | ... |
> Das programm habe ich irgendwann irgendwo gefunden, ich habe von > Assembler keine Ahnung Das ist schlecht. Peter
@Turboforce Poste doch den ganzen Code! An welchem Port sind die Dipschalter oder was auch immer für die Pauseeinstellung?
Hallo, erstmal Danke an alle, unerwartet gute Hilfe!!!! Dank euch habe ich folgende Probleme behoben: Programmlänge nicht meht auf 256 beschränkt, dank ""Nimm einfach "inc dptr" statt "inc r0""" von Peter D. Tabellenende variabel gekennzeichnet, je nach dem, welches Muster gerade nicht vorkommt. Dank dafür an dernixwois Das schlimmste ist damint schon mal erledigt!!!! DiDADankeschööön!!! Folgende Probleme bleiben: Das mit der Pause: 1. Die Jumper verbinden P3.2 , P3.3 , P3.4 und P3.5 je nach Auswahl mit minus. Die bisherige Wartesequenz wird per call wait_50000 aufgerufe, also verweist auf INCLUDE wait.asm. Was sich dahinter verbirgt ist mir schleierhaft. Kann man vielleicht anders ersetzen? Es sollte so sein, das es, wenn kein Jumper gesetzt ist es eine Grundgeschwindigkeit gibt, und je nach dem welcher Jumper gesetzt ist, die Geschwindigkeit steigt. Das was Peter D. vorschlug ist bestimmt schon richtig, ich habe es einfach an Steller von call wait_50000 eingefühgt, gab auch kein Fehler hat aber am Ende zu keiner Ausgabe geführt, alle Kanäle durchs reset kurz aufgeleuchtet und dan totale Finsternis. Was habe ich falsch gemacht, wo ich doch so viel Ahnung habe, was zugegeben wirklich schlecht ist, aber leider Realität. Wie gesagt, einmalige Angelegenheit. Der obrige Code ist soweit komplett bis auf die beiden INCLUDEs und das Muster ist natürlich beliebig. Also Dank nochmal bisher all denjenigen die sich beteiligt haben, ich freue mich auf weitere Ideen, Tipps, und Vorschläge, jeder Post ist für mich eine neue, interessante Erkenntnis. Bastian Lampe
Turboforce wrote: > Die bisherige Wartesequenz wird per call wait_50000 aufgerufe, also > verweist auf INCLUDE wait.asm. Was sich dahinter verbirgt ist mir > schleierhaft. Such einfach mal nach "wait.asm", die muß ja auf Deiner HD sein. Include xxx heißt nur: Datei xxx einbinden. > Das was Peter D. vorschlug ist bestimmt schon richtig, ich habe es > einfach an Steller von call wait_50000 eingefühgt, gab auch kein Fehler Ne, die Funktion lädt nur einen 16Bit-Wert nach R7,R6. Da sie auch DPTR verwendet, mußt Du sie am Anfang des Zyklus einbinden, bevor Du DPTR auf die Bitmustertabelle setzt. Die Delayfunktion muß nun den Wert aus R7,R6 laden für ihren Delayzähler. Peter
Hallo; erstmal im Anhang die bisherige Warte-Sequenz, hab ich jetzt verstanden, durch Call wait_50000 oder so wurde ein unterprogramm geöffnet, welchens so bezeichnet wird. Hatte gedacht, das durch die Zahleneingabe ein Wert ins Unterprogramm geschrieben wird der die Pausenlänge bestimmt und gewundert, warum das nicht mit allen Zahlen geht. OK, kapiert, und damit das erledigt. Nun das Aktuelle Problem: Ich habe den Code nun so transformiert: INCLUDE 89c2051.mc init: MOV DPTR,#Tabelle ;Adresse der Tabelle angeben MOV R0,#00h ;Schrittzähler auf 0 start: MOV A,R0 MOVC A,@a+dptr ;Tabellenplatz berechnen if A = #FFh THEN JMP init ;Wenn Tabelle zuende neuanfang MOV P1,A ;Muster Ausgeben call get_delay ;Pause INC dptr ;Schrittzähler erhöhen JMP start Tabelle: ;Muster DB 10000000b, DB 01000000b, DB 00100000b, DB 00010000b, DB 00001000b, DB 00000100b, DB 00000010b, DB 00000001b, DB 11111111b, ;FFh = Ende der Tabelle INCLUDE wait2.asm END Und die Der Code von wait2.asm get_delay: mov a, p3 anl a, #0Fh ;nur P3.3 - P3.0 add a, acc ; * 2 mov r7, a mov dptr, #delay_tab movc a, @a+dptr xch a, r7 ; r7 = delay high byte inc a movc a, @a+dptr mov r6, a ; r6 = delay low byte ret delay_tab: dw 1000 dw 1400 dw 2000 dw 2800 dw 4600 dw 5600 so wie ihn Peter vorschlug Aber das klappt nicht, egal wo ich call get_delay hinpacke, das Ergebnis ist stets ernüchternd obwohl es zuvor in der Simulation gut aussah. Entweder es leuchtet alles, oder so wie jetzt ein paar kanäle durchgehend. Bitte habt gedult mit mir, ich will doch nur, das es funktioniert. Danke Bastian Lampe
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.