Hallo! Zuerst einmal muss ich sagen was ich habe: Ich habe ein Mikrocontroller System mit einen 12Mhz Mikrocntroller. Die Ausgabe der Stoppuhr erfolgt auf der BCD-7-Segment Anzeige (welche an Port 1 und 2 des Mikrocontrollers angeschlossen ist). Außerdem ist eine Schalterplatine an Port 0 angeschlossen für Zusatzfunktionen. Ich habe mittlerweile mit meinen Basis Kenntnissen folgendes Programm programmiert: --------------------------------------------------- $include (reg52.inc) Minutentaster bit P0.0 Stundentaster bit P0.1 org 0000h LJMP start ;Einsprungadresse Interrupt-Serviceroutine für Timer 0 org 000Bh LJMP isrTimer0 org 0100h start: CALL initRegister CALL initTimer0 loop: LJMP loop ;Endlosschleife initRegister: MOV R0,#0 ;bestimmt welche der Anzeigen aktiv ist MOV R1,#0 ;Zähler von o bis 249 -->4ms*250 = 1 Sec MOV R2,#0 ;Sekunden Einer MOV R3,#0 ;Sekunden Zehner MOV R4,#0 ;für Segment rechts Minuten Einer MOV R5,#0 ;für Segment Mitte rechts Minuten Zehner MOV R6,#0 ;für Segment Mitte links Stunden Einer MOV R7,#0 ;für Segment links Stunden Zehner RET initTimer0: SETB ET0 ;Freigabe Timer0. Bit im Reg IE, Reg.-Adresse A8h SETB EA ;Globale INT Freigabe. Bit im Reg IE MOV TMOD,#00000001b ;Timer0 konfiguieren, Modus1: 16bit Zaehler MOV TL0,#060h ;Timer0 vorladen MOV TH0,#0F0h ;65536 - 4000 = 61536 = F060h (4ms) SETB TR0 ;Start Timer0 RET ;Interrupt-Service-Routine für Timer0 isrTimer0: MOV TL0,#060h ;Timer0 erneut vorladen MOV TH0,#0F0h ;65536 - 4000 = 61536 = F060h (4ms) CALL neueUhrzeit ;neue Uhrzeit berechnen CALL ausgabe ;Ausgabe auf Anzeige RETI ;Ende der Interrupt-Service-Routine neueUhrzeit: INC R1 ; erhoehe Register 1 CJNE R1,#250d,weiter ;Springe nach weiter wenn der Inhalt von R1 ungleich 250d ist MOV R1,#0d ;Lade Register 1 mit dem Wert 0 JB Minutentaster,mSek ;Springe nach mSek wenn Sektaster 1 ist JB Stundentaster,mMin ;Springe nach mMin wenn Mintaster 1 ist INC R2 ; erhoehe Register 2 CJNE R2,#10d,weiter ;Springe nach weiter wenn der Inhalt von R2 ungleich 10d ist MOV R2,#0d ;Lade Register 2 mit dem Wert 0 INC R3 ; erhoehe Register 3 CJNE R3,#10d,weiter ;Springe nach weiter wenn der Inhalt von R3 ungleich 10d ist MOV R3,#0d ;Lade Register 3 mit dem Wert 0 mSek: INC R4 ; erhoehe Register 4 CJNE R4,#10d,weiter ;Springe nach weiter wenn der Inhalt von R4 ungleich 10d ist MOV R4,#0d ;Lade Register 4 mit dem Wert 0 INC R5 ; erhoehe Register 5 CJNE R5,#06d,weiter ;Springe nach weiter wenn der Inhalt von R5 ungleich 10d ist MOV R5,#0d ;Lade Register 5 mit dem Wert 0 mMin: INC R6 ; erhoehe Register 6 CJNE R6,#6d,m2 ;Springe nach m2 wenn der Inhalt von R6 ungleich 6d ist CJNE R7,#10d,m2 ;Springe nach m2 wenn der Inhalt von R7 ungleich 0d ist MOV R6,#0 ;Lade Register 6 mit dem Wert 0 MOV R7,#0 ;Lade Register 7 mit dem Wert 0 m2: CJNE R6,#10,weiter ;Springe nach weiter wenn der Inhalt von R6 ungleich 10 ist MOV R6,#9 ;Lade Register 6 mit dem Wert 9 INC R7 ; erhoehe Register 7 LJMP weiter ;aufrufen von weiter weiter: RET ;Rücksprung aus dem Unterprogramm ausgabe: INC R0 CJNE R0,#04,rechts MOV R0,#0 rechts: CJNE R0,#0,mire MOV A,R4 CALL BCD7Seg MOV P1,A MOV P2,#00001110b mire: CJNE R0,#1,mili MOV A,R5 CALL BCD7Seg MOV P1,A MOV P2,#00001101b mili: CJNE R0,#2,links MOV A,R6 CALL BCD7Seg MOV P1,A MOV P2,#00001011b links: CJNE R0,#3,m1 MOV A,R7 CALL BCD7Seg MOV P1,A MOV P2,#00000111b m1: RET ;; Wandelt vom BCD-Code in den 7-Segment-Code BCD7Seg: INC A MOVC A,@A+PC RET DB 3Fh, 06h, 5Bh, 4Fh, 66h, 6Dh, 7Dh, 07h, 7Fh, 6Fh END --------------------------------------------------------- Das Programm funktioniert soweit auch einwandfrei.... Ich möchte jetzt nur die Anzeige etwas umwandeln. Die Anzeige soll um ein Segment nach Rechts gerückt werden, das würde bedeuten: Segment Rechts: Hundertstel Zehner Segment Mitte Rechts: Sekunden Einer Segment Mitte Links: Sekunden Zehner Segment Links: Minuten Ich weiß nicht ob ich irgendwie gerade voll auf dem Schlauch stehe oder was los ist, aber egal was ich tue es funktioniert nicht! Achso und was ich noch Programmieren möchte ist ein Reset, vielleicht hat jemand von euch hierfür auch einen Vorschlag? Ich bin wirklich Anfänger mit Assembler und fände es gut wenn das Programm weiterhin so verständlich bleibt wie mein jetziges. Vielen Dank schoneinmal im Voraus für die schnelle Antwort!
Würdest du die Uhr im RAM realsieren (also nicht mit den Registern), könnte man durch ändern des Anzeige-Daten-Einstiegspointers die Anzeige einfach um eine Stelle (oder sogar noch mehrere) verschieben. Für das Reset musst du eigentlich nur eine weitere Tastenabfrage einbringen, die zu einer Stelle verzweigt, wo alle Register auf 0 gesetzt werden.
Und wie funktioniert das mit dem realisieren im RAM? Ich bin noch sehr Neu auf diesem Gebiet und habe mir mein Programm grade so zusammenbasteln können. Gibt es einen Befehl die ich alle Register auf einmal auf 0 setzen kann?
>Und wie funktioniert das mit dem realisieren im RAM? Weiß ich leider auch nicht. Da ich einerseits in C, andererseits überwiegend AVR programmieren. >Gibt es einen Befehl die ich alle Register auf einmal auf 0 setzen kann? Vermutlich nicht. Da wirst du einfach alle verwendeten Register der Reihe nach "clearen" müssen. Falls du Interesse am Lesen von Büchern hast: "Das Mikrocontroller Kochbuch" von Andreas Roth ist sowas wie die Bibel für 8051er-Controller.
Gleich vorweg: Ich verstehe nichts vom 8051 Assembler an sich. Aber: MOV R3,#0d ;Lade Register 3 mit dem Wert 0 mSek: INC R4 ; erhoehe Register 4 Kommentare wie diese kannst du dir sparen. Da steht im Kommentar genau dasselbe wie im eigentlichen Quelltext. Super, da wird 'Lade Register 3 mit dem Wert 0'. Das sehe ich auch (oder kann es erraten) wenn ich MOV R3, #0d lese. Die viel spannendere Frage ist doch: Was enthaelt den Register 3? Sind da Zwetschken, Anzahl an Äpfel, Minuten, Stunden, Monate oder was auch immer gespeichert? Diese Information brauch ich, um zu verstehen was da vor sich gehen soll. Selbiges hier (und im Rest vom Code) INC R4 ; erhoehe Register 4 Als echter Österreicher sag ich da: "No, na. Erniedrigen wird er wenn da schon INC steht". Warum wird da R4 erhöht? Was enthält denn R4 überhaupt? Das sind die Fragen die mich da bewegen.
Also so genau kann ich das jetzt auch nicht kommentieren, ich habe das Programm zusammen mit einem Freund geschrieben und ich bin eigentlich der der definitiv sehr wenig ahnung von dem ganzen hat... Aber vielleicht kann mir jemand ohne ausführliche Kommentare weiterhelfen?
Das stinkt doch wieder einmal zum Himmel: Erst: "Ich habe mittlerweile mit meinen Basis Kenntnissen folgendes Programm programmiert" Dann: "ich habe das Programm zusammen mit einem Freund geschrieben" Genau wie ich! Ich schreibe meine Programme auch immer zusammen mit meinen Freunden. Ich nehme an Dein "Freund" hat kein Internet.
> Achso und was ich noch Programmieren möchte ist ein Reset, > vielleicht hat jemand von euch hierfür auch einen Vorschlag? Fang mal damit an, das dürfte das Einfachere sein. Was brauchst Du? 1. Du brauchst einen Tastet oder Schalter. Den irgendwie musst du den Reset ja ausloesen. 2. Du musst die Zahlenwerte für Minuten, Sekunden, etc auf 0 setzen Zu Punkt 1: Da ich Deine Hardware nicht kenne, kann ich auch nicht sagen ob du einen Taster oder Schalter frei hast. Im Zweifel wirst du halt einen nachrüsten müssen. Da das bisherige Programm bereits Taster einliest, kannst du dich daran orientieren wie das geht und mal den neuen Taster auswerten. Zu Punkt 2: Alle Zahlenwerte auf 0 setzen. Das sollte nicht so schwer sein. Zumal Dein bisheriges Programm ja schon sowas enthält. Ich zitieren MOV R2,#0 ;Sekunden Einer MOV R3,#0 ;Sekunden Zehner MOV R4,#0 ;für Segment rechts Minuten Einer MOV R5,#0 ;für Segment Mitte rechts Minuten Zehner MOV R6,#0 ;für Segment Mitte links Stunden Einer MOV R7,#0 ;für Segment links Stunden Zehner das sieht doch schon genau so aus, wie das wonach du suchst.
@ Christian Rötzer Ich weiß nicht was du von mir denkst aber mein Freund hat wirklich kein Internet. Und dadurch das wir uns NOCH in den Semesterferien befinden sehe ich ihn auch nicht (da er in Urlaub ist) und ich möchte eben weiter Programmieren. Zur Info ich habe eine Schalterplatine und eine Tasterplatine zur Verfügung. Ich werde wahrscheinlich eher die Tasterplatine verwenden (ist günstiger für Start, Stopp, Reset, usw.). Danke für die bisherigen Antworten! Wenn jetzt noch jemand eine Möglichkeit hätte die ganze Stoppuhr in diesem normal verständlichen Code eine Anzeige nach rechts zu verschieben, wie es in meinen ersten Beitrag schon erwähnt wurde. Dann wäre ich glücklich!
Vielleicht ne Schweine-Methode, funktioniert aber wunderbar: Schreib dir eine zweite Ausgaberoutine, die im "Stopp-Uhr-Modus" statt der "Standard-Uhrzeit-Anzeige" angesprungen wird. Das wäre die schnellste Möglichkeit, zum Ziel zu kommen.
High Low Manfred, nach dem was ich sehe wird die Anzeige mit P1 und P2 angesteuert. An P1 liegen die Segmente und P2 macht die Stelle. Schau dir die Null in P2 an von Stelle zu Stelle. Siehst Du wie sie wandert ??? Genau damit kannst du die Anzeige verschieben. Bei 00001110b geht die letzte Stelle an und bei 00000111b geht die 1.Stelle an. 00001110 Minuten Einer 00001101 Minuten Zehner 00001011 Stunden Einer 00000111 Stunden Zehner Alle anderen sind immer High. ( oder 1 ). An P2 sind doch die Transistoren für die Anzeigen ???? Also nimm den richtigen Wert für die Stelle in P1 und mit P2 gibst Du an welche Anzeige aktiv sein soll. So denn
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.