Hallo ihr! Ich brauche ganz dringend eure Hilfe. Ich bin noch Anfänger im Programmieren mit dem 8051 Mikrocontroller und habe hier mal einen Versuch gestartet. Ich habe ein Stoppuhrprogramm geschrieben welches auf einer BCD 7 Segment Anzeige ausgegeben wird. Die BCD-7-Segment Anzeige ist an Port 1 und 2 angeschlossen, eine Tasterplatine ist an Port 0 angeschlossen... Der Mikrocontroller hat 12 Mhz. Was nun mein Problem ist: Ich benötige einen Befehl oder ein Programmteil welches das ganze Stoppuhrprogramm startet und einen Befehl zum Stoppen. Außerdem möchte ich einen Reset einbauen! Das Programm sollte wenn möglich nicht allzu arg verändert werden, d.h. das Programm soll weiterhin mit Interrupt laufen. Da dies eines der wenigen Dinge ist die ich verstehe.... Nun das Programm: $include (reg52.inc) Minutentaster bit P0.0 Stundentaster bit P0.1 Starttaster bit P0.2 Resettaster bit P0.3 org 0000h LJMP start ;Einsprungadresse Interrupt-Serviceroutine für Timer 0 org 000Bh LJMP isrTimer0 org 0100h startabfrage: JB Starttaster,start ;Stoppuhrprogramm starten wenn Taster gedrückt LJMP startabfrage start: CALL initRegister CALL initTimer0 loop: JB Resettaster,springer springer:LJMP initRegister 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 Danke für schnelle Antworten!
wie ich die Sache sehe, sollte der Starttaster nichts anderes tun als SETB TR0 beim 1. Betätigen und CLR TR0 beim 2. Betätigen. Damit läuft der Timer erst beim drücken los. Wie ne echte Uhr. Und stoppt beim 2. Drücken, wie ne...... Beim Init muß dann aber SETB TR0 raus !!! OK so oder falsch verstanden ??
Also die Idee ist glaube ich gut, aber wie setze ich das ganze um???? Also vor allem die einbindung der Abfrage der Taster wäre interessant!
wie wärs wenn du in dein Hauptprogramm folgendes einbaust: org 0100h endlos: JNB Starttaster,n1 CALL initRegister CALL neueUhrzeit CLR merkerStop JB Starttaster,endlos LJMP endlos n1: CALL initRegister CALL initTimer0 JNB stopTaster,endlos SETB merkerStop Oder funktioniert das nicht? Kann mich da jemand berichtigen?
Taster zB an P1.0 Setb p1.0 oder mov P1,#ff oä. um den Port als Eingang zu haben dann entweder pollen oder flankentriggern zB. Pollen abfrage: mov a,p1 jb a.0,abfrage jetzt weiter da taste gedrückt Hilfsflag schon 1 ?? Ja > dann SetB Tr0; Hilfsflag nullen nein > setb Taster ( Hilfsflag ) zB.: warten für 20ms oä. wegen prellen und nochmal Taster abfragen ob gedrückt jmp abfrage oder Du nimmst Flankengetriggerten Interrupt EXT0 EXT1 gleiches Prinzip ABER..... Du mußt die Taster entprellen !!!! Soft oder Hardwareseitig. Keine Ahnung wie genau die Uhr sein soll. Im Einfachsten Fall ein FF am Taster.
@Jochen es vergeht einiges an Zeit bis alles initialisiert ist und der Timer läuft. !!!Die fehlt nachher !!!!
Ich glaube ich stehe vor immer mehr Probleme... Gäbe es eine Möglichkeit das nicht allzuviel Zeit vergeht beim initialisieren? Und wo müsse ich dann diese Abfrage von oben einbauen?
mach den Init als erstes fertig komplett mit timerwerten und starte den Timer erst (Setb Tr0) erst bei Tastenerkennung !!!
Ich bin mal frech: http://www.hanneslux.de/avr/stopuhr/index.html Aber vielleicht hilft es ja... ...
Ich möchte mit C eine machen. Kann mir jemand helfen? im vorraus Danke;)
Geh Dein Programm nochmal schritt für schritt logisch durch und korrigiere es, bevor Du es hier dann noch einmal postest: z.B.: loop: JB Resettaster,springer springer:LJMP initRegister macht keinen Sinn! : Wenn Resettaster dann verzweige nach springer, wenn nicht, dann macht er auch bei springer weiter. Außerdem solltest Du Deine Unterprogramme noch einmal untersuchen: Wenn Du mit CALL in ein UPRO verzweigst, mußt Du mit RET wieder raus. Wenn Du mit JMP reinspringst, darfst Du NICHT mit RET wieder raus. Vor dem ersten CALL mußt Du unbedingt den Stack initialisieren - oder Dir zumindest Gedanken machen, auf welchem Wert er gerade steht und in welche Richtung er sich bewegt. Gruß, Markus_8051
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.