'************************************************************** ' Ansteuerung des Timer Moduls als Wecker '************************************************************** 'Quarzfrequenz: 12 MHz ' Die dazugehörige Schaltung und weitere Informationen zum Wecker finden ' Sie bei www.batronix.com unter den Bauanleitungen. INCLUDE 89c2051.mc Verwendung_der_Register_R0_bis_R7,Registerbank_0: ' R0 = 1. Anzeige von links, für 10er Stunden ' R1 = 2. Anzeige von links, für 1er Stunden ' R2 = 3. Anzeige von links, für 10er Minuten ' R3 = 4. Anzeige von links, für 1er Minuten ' R4 = Sekundenzähler ' R5 = Zählt die Anzahl der Interrupts von Timer 0 ' (Ein Interrupt alle 50 mS, 20 Interrupts entsprechen einer Sekunde) ' R6 = Zählt die Anzahl der Durchläufe bei betätigtem Taster ' (Schnelldurchlauf beim Einstellen der Zeit) ' R7 = Allgemeines Zählregister für die Pausenroutine Verwendung_der_Register_R0_bis_R7,Registerbank_1: ' R0 = Weckzeit, 10er Stunden ' R1 = Weckzeit, 1er Stunden ' R2 = Weckzeit, 10er Minuten ' R3 = Weckzeit, 1er Minuten Verwendung_des_Port1_(Alle_Low-Aktiv): ' P1.0 Transistor Basis zur Ansteuerung der ersten 7.Segment Anzeige (Low=Aktiv) ' P1.1 Transistor Basis zur Ansteuerung der zweiten 7.Segment Anzeige (Low=Aktiv) ' P1.2 Transistor Basis zur Ansteuerung der dritten 7.Segment Anzeige (Low=Aktiv) ' P1.3 Transistor Basis zur Ansteuerung der vierten 7.Segment Anzeige (Low=Aktiv) ' P1.4 Alarmausgang ' P1.5 Weckzeit ' P1.6 Einstellung der Stunde ' P1.7 Einstellung der Minute Verwendung_des_Port3: ' P3.0 Segment a ' P3.1 Segment b ' P3.2 Segment c ' P3.3 Segment d ' P3.4 Segment e ' P3.5 Segment f ' P3.7 Segment g Zeitrealisierung: ' Der Timer 0 zählt nach dem Starten immer bis zum Überlauf hoch und löst mit ' dem Überlaufen einen Interrupt aus. Mit Auslösen des Interrupt's springt der ' Programmzähler auf die Adresse (000Bh). ' Der Wert des Timer's wird mit jedem Maschinentakt (1/12 Oszillatortakt) ' um einen erhöht. Um eine Zeitbasis von 50 mS zu errreichen, wird der Timer ' auf den Wert 3CB0h voreingestellt. Bis zum Überlauf müssen nun 10000h-3CB0h ' = C350h = 50000 Maschinentakte erfolgen. Da bei einer Oszillatorfrequenz ' von 12 MHz der Maschinentakt 1 uS lang ist, beträgt die Zeit bis ' zum Überlauf 50mS. ' Da die Einsprungzeit eines Interrupts aber zwischen 3 und 8 Maschinentakte ' liegen kann, muss die bereits vergangene Zeit zur Voreinstellung addiert ' werden. Der Timer zählt auch nach dem Auslösen eines Interrupts einfach ' weiter, daher steht die seit der Interruptauslösung vergangene Zeit im ' Timer Low Byte. Zusätzlich werden noch 5 Takte für die Abarbeitung von ' PUSH A / MOV A,TL0 / ADD A,#B3h / MOV TL0,A addiert: LJMP Initialisierung 'Überspringe Interruptroutine nach einem Reset (000Bh): 'Einsprungadresse Interrupt Timer 0 PUSH A 'Akkuinhalt auf dem Stack sichern 'Realisierung der 50mS Zeitbasis: MOV A,TL0 ADD A,#B5h 'A = TL0 = Zeit seit Überlauf + Grundeinstellung B0 + 5) MOV TL0,A MOV TH0,#3Ch 'Grundeinstellung Timer 0 High Byte 'Routine zum "Hochzählen" der Uhrzeit: CLR D3h 'Registerbank 0 aktiv INC R5 'Register 5 speichert die Zahl der Interrupts CJNE R5,#20,Zurück 'Wenn bereits 20 Interrupts, dann: MOV R5,#00 'Interruptzähler auf 0 INC R4 'Sekundenzähler = Sekundenzähler +1 CJNE R4,#60,Zurück 'Wenn bereits 60 Sekunden um sind, dann MOV R4,#0 'Sekundenzähler auf 0 INC R3 '1er Minute = 1er Minute +1 MOV 34h,#0 'Alarm Deaktivierung zurücksetzen CJNE R3,#10,Zurück 'Wenn 1er Minute = 10, dann MOV R3,#0 '1er Minute = 0 INC R2 '10er Minute = 10er Minute +1 CJNE R2,#6,Zurück 'Wenn 10er Minute = 6, dann MOV R2,#0 '10er Minute = 0 INC R1 '1er Stunde = 1er Stunde +1 CJNE R1,#10,C_24 'Wenn 1er Stunde = 10, dann MOV R1,#0 '1er Stunde = 0 INC R0 '10er Stunde = 10er Stunde +1 LJMP Zurück C_24: 'Bei erreichen von 24 Uhr: CJNE R1,#4,Zurück 'Wenn 1er Stunde = 4, dann CJNE R0,#2,Zurück 'Wenn 10er Stunde = 2, dann MOV R0,#0 '10er Stunde = 0 MOV R1,#0 '1er Stunde = 0 Zurück: JB P1.5,Zurück2 'Wenn Weckzeit-Taster betätigt, dann SETB D3h 'Registerbank 1 aktiv, Weckzeit einstellen Zurück2: POP A 'Akkuinhalt wieder herstellen RETI 'Zurück aus der Interruptbehandlung ins Programm '************************************************ INITIALISIERUNG: MOV Port1,#FFh 'Basen der Transistoren auf High (aus) MOV Port3,#00h 'Treibersignale auf Low (aus) MOV SP,#10h 'Stackpointer hinter die Registerbank 1 MOV R4,#00h 'Sekundenzähler MOV R5,#00h 'Anzahl der Interrupts von Timer 0 'Einstellen der Initialisierungs Weckzeit auf 12:00: SETB D3h 'Registerbank 1 aktiv (Weckzeit): MOV R0,#0 '1. Anzeige von links, für 10er Stunden MOV R1,#0 '2. Anzeige von links, für Stunden MOV R2,#0 '3. Anzeige von links, für 10er Minuten MOV R3,#1 '4. Anzeige von links, für Minuten MOV 34h, #0 'Alarm deaktiviert 'Einstellen der Initialisierungs Uhrzeit auf 00:00: CLR D3h 'Registerbank 0 aktiv (Uhrzeit): MOV R0,#0 '1. Anzeige von links, für 10er Stunden MOV R1,#0 '2. Anzeige von links, für Stunden MOV R2,#0 '3. Anzeige von links, für 10er Minuten MOV R3,#0 '4. Anzeige von links, für Minuten 'Grundeinstellung des Timer 0 und der dazugehörigen Interrupts: MOV TMOD,#01h 'Timer 0 Modus = 1 MOV TH0,#3Ch 'High Byte vom Timer 0 setzen MOV TL0,#B0h 'Low Byte vom Timer 0 setzen SETB EA 'Interruptbehandlung aktivieren SETB ET0 'Interrupt für Timer 0 aktivieren SETB TR0 'Timer 0 Start '************************************************ Timer_einstellen: CLR D3h 'Registerbank 0 aktiv, Uhrzeit einstellen JB P1.5,Uhrzeit_einstellen SETB D3h 'Registerbank 1 aktiv, Weckzeit einstellen Uhrzeit_einstellen: JNB P1.6,Stunde JB P1.7,Weiter CJNE R3,#9,Kein_Überlauf 'Wenn 1er Minute = 9, dann MOV R3,#0 '1er Minute = 0 INC R2 '10er Minute = 10er Minute +1 CJNE R2,#6,Warte_Taste_Los 'Wenn 10er Minute = 6 dann MOV R2,#0 '10er Minute = 0 Stunde: INC R1 '1er Stunde = 1er Stunde +1 CJNE R1,#10,Check_24_2 'Wenn 1er Stunde = 10 dann MOV R1,#0 '1er Stunde = 0 INC R0 '10er Stunde = 10er Stunde +1 Check_24_2: 'Bei erreichen von 24 Uhr: CJNE R0,#2,Warte_Taste_Los 'Wenn 10er Stunde = 2, dann CJNE R1,#4,Warte_Taste_Los 'Wenn 10er Stunde = 2, dann MOV R0,#00h '10er Stunde = 0 MOV R1,#00h '1er Stunde = 0 LJMP Warte_Taste_Los Kein_Überlauf: INC R3 Warte_Taste_Los: LCALL Refresh MOV C,P1.6 ORL C,P1.7 JC Max_Ein_Taster 'Wenn beide Taster betätigt sind, lösche R0-R3 MOV R0,#00h MOV R1,#00h MOV R2,#00h MOV R3,#00h Max_Ein_Taster: DJNZ R6,WTL 'Schnelldurchlauf, wenn R6 zu Null wird. MOV R6,#10h 'Dabei wird nicht mehr auf das Loslassen LJMP Weiter 'des Tasters gewartet. WTL: JNB P1.6,Warte_Taste_Los JNB P1.7,Warte_Taste_Los MOV R6,#FFh 'Der Taster wurde losgelassen, setze R6 'wieder auf den Maximalwert (FF) Weiter: LCALL Refresh '***Vergleiche Uhrzeit mit Weckzeit:*** CLR ET0 'Interrupt für Timer 0 deaktivieren SETB D3h 'Registerbank 1 aktiv (Weckzeit) MOV 30h,R0 MOV 31h,R1 MOV 32h,R2 MOV 33h,R3 SETB ET0 'Interrupt für Timer 0 aktivieren CLR D3h 'Registerbank 0 aktiv (Uhrzeit) MOV A,R0 CJNE A,30h,Timer_einstellen MOV A,R1 CJNE A,31h,Timer_einstellen MOV A,R2 CJNE A,32h,Timer_einstellen MOV A,R3 CJNE A,33h,Timer_einstellen Weck_Alarm: MOV A, 34h CJNE A, #00, AlarmIstDeaktiviert CLR P1.4 'Setze Alarmausgang auf Low (aktiv) LCALL Refresh 'Refresh Anzeige JB P1.5,Weck_Alarm 'Wiederhole bis Alarmtaster an P1.5 betätigt MOV 34h, #01 'Alarm deaktiviert SETB P1.4 'Setze Alarmausgang auf High (deaktiv) AlarmIstDeaktiviert: LJMP Timer_einstellen '************************************************ Refresh: MOV DPTR,#0180h 'Datenpointer = Anfang der Hex Tabelle JB P1.5,Refresh_Uhrzeit SETB D3h 'Registerbank 1 aktiv (Refresh Weckzeit) Refresh_Uhrzeit: MOV A,R0 MOVC A,@A+DPTR 'Lese Wert aus der Hex Tabelle LCALL Anzeige_0 MOV A,R1 MOVC A,@A+DPTR 'Lese Wert aus der Hex Tabelle LCALL Anzeige_1 MOV A,R2 MOVC A,@A+DPTR 'Lese Wert aus der Hex Tabelle LCALL Anzeige_2 MOV A,R3 MOVC A,@A+DPTR 'Lese Wert aus der Hex Tabelle LCALL Anzeige_3 RET '************************************************ Anzeige_0: MOV Port3,A CLR P1.0 LCALL Pause_1mS SETB P1.0 RET Anzeige_1: MOV Port3,A CLR P1.1 LCALL Pause_1mS SETB P1.1 RET Anzeige_2: MOV Port3,A CLR P1.2 LCALL Pause_1mS SETB P1.2 RET Anzeige_3: MOV Port3,A CLR P1.3 LCALL Pause_1mS SETB P1.3 RET '************************************************ Pause_1mS: 'Pause von ca. 1 mS MOV R7,#250 Schleife: NOP NOP DJNZ R7,Schleife NOP RET '************************************************ (0180h): 'Datentabelle für die Anzeige der Ziffern 0-9: DB 3Fh,06h,9Bh,8Fh,A6h,ADh,BDh,07h,BFh,AFh