list p=16f73 ;*********************************************************************************************************************** ; Pinbelegung: ; ; PortA: ; 0 Relais ; 1 ; 2 ; 3 ; 4 ; 5 ; ; PortB: ; 0 ; 1 Q2 ; 2 Dezimalpunkt ; 3 ; 4 A ; 5 D ; 6 C ; 7 B ; ; PortC: ; 0 Links ; 1 Minus ; 2 Okay ; 3 Plus ; 4 Rechts ; 5 Q1 ; 6 Q4 ; 7 Q3 ; ; ;*********************************************************************************************************************** ; #include "p16f73.inc" ; Include-Dateien Laden ; __CONFIG _PWRTE_ON & _WDT_OFF & _HS_OSC ; über 3,5 MHz ; ;*********************************************************************************************************************** ; Registerdeklaration loops equ 0x20 ; Zähler für Warteschleife loops2 equ 0x21 ; Zähler für Warteschleife w_temp equ 0x22 ; Backup Akkuregister (W-Register) status_temp equ 0x23 ; Backup Statusregister pclath_temp equ 0x24 ziffer1 equ 0x25 ; Aktuellen Wert 1. Ziffer (links) ziffer2 equ 0x26 ; Aktuellen Wert 2. Ziffer ziffer3 equ 0x27 ; Aktuellen Wert 3. Ziffer ziffer4 equ 0x28 ; Aktuellen Wert 4. Ziffer (rechts) Digit equ 0x29 ; Auswahl des ISR-PARTS ar equ 0x2A ; Zwischenspeicher für "Counten" Timer2 equ 0x2B ; Schleife für Sekundentakt STARTEN equ 0x2C ; Hilfsbyte um Counter zu starten ;*********************************************************************************************************************** ; Start des Programms org 0x00 goto INIT ;*********************************************************************************************************************** ; Start des Interupt-Service-Routine org 0x04 intvec bcf INTCON, GIE ; disable Interupt movwf w_temp swapf STATUS, W clrf STATUS movwf status_temp movfw PCLATH movwf pclath_temp clrf PCLATH movlw D'131' ; 256-125=131 ((1MHz : 32 ): 125 = 250 Hz) movwf TMR0 Int_serv bcf PORTC, 5 ; Ziffer 1 aus bcf PORTB, 1 ; Ziffer 2 aus bcf PORTC, 7 ; Ziffer 3 aus bcf PORTC, 6 ; Ziffer 4 aus decf Digit,f ; Ziffernzähler verringern btfsc STATUS, Z goto Int_0 ; Z-Flag=1 ergo Digit=0 movfw Digit movwf ar decf ar, f btfsc STATUS, Z goto Int_1 ; Digit=1 (Ziffer 1) decf ar, f btfsc STATUS, Z goto Int_2 ; Digit=2 (Ziffer 2) decf ar, f btfsc STATUS, Z goto Int_3 ; Digit=3 (Ziffer 3) goto Int_4 ; Digit=4 (Ziffer 4) Int_0 movlw 5 movwf Digit btfss STARTEN, 0 ; Bit0 = 1 > "Counten", SONST NICHT goto Int_end decf Timer2, f ; von 32 bis 0 zählen btfss STATUS, Z goto Int_end ; Timer2 <> 0 movlw 32 movwf Timer2 movlw d'1' subwf ziffer4, f ; 1 Sekunden vertiefen btfsc STATUS, C goto Int_end ; 1 Sekunden <> 10 movlw d'9' movwf ziffer4 movlw d'1' subwf ziffer3, f ; 1 Sekunden vertiefen btfsc STATUS, C goto Int_end ; 1 Sekunden <> 10 movlw d'5' movwf ziffer3 movlw d'1' subwf ziffer2, f ; 1 Sekunden vertiefen btfsc STATUS, C goto Int_end ; 1 Sekunden <> 10 movlw d'9' movwf ziffer2 ; 1 Minuten <> 6 movlw d'1' subwf ziffer1, f ; 1 Sekunden vertiefen btfsc STATUS, C goto Int_end ; 1 Sekunden <> 10 movlw d'5' movwf ziffer1 goto Int_end Int_1 movfw ziffer1 ; Wert der 1. Ziffer call Segmente movwf PORTB ; Segmente einschalten bsf PORTC, 5 ; 1. Ziffer einschalten goto Int_end Int_2 movfw ziffer2 ; Wert der 2. Ziffer call Segmente movwf PORTB ; Segmente einschalten bsf PORTB, 1 ; 2. Ziffer einschalten goto Int_end Int_3 movfw ziffer3 ; Wert der 3. Ziffer call Segmente movwf PORTB ; Segmente einschalten bsf PORTC, 7 ; 3. Ziffer einschalten goto Int_end Int_4 movfw ziffer4 ; Wert der 4. Ziffer call Segmente movwf PORTB ; Segmente einschalten bsf PORTC, 6 ; 4. Ziffer einschalten goto Int_end Int_end movfw pclath_temp movwf PCLATH swapf status_temp,W movwf STATUS swapf w_temp,F swapf w_temp,W bcf INTCON, T0IF ; Interupt-Flag löschen bsf INTCON, GIE ; enable Interupt retfie ;*********************************************************************************************************************** ; Initialisierung des PIC INIT bsf STATUS, RP0 ; auf Bank 1 umschalten movlw 0x06 ; PortA auf Digital schalten movwf ADCON1 movlw B'00000000' ; RA alle output movwf TRISA movlw B'00000000' ; RB alle output movwf TRISB movlw B'00011111' ; RC0 bis RC4 input, RC5 bis RC7 output movwf TRISC movlw B'10000100' ; internen Takt zählen, Vorteiler zum Timer0: 32:1 movwf OPTION_REG movlw D'131' ; 250 Hz-Timer-Interupt einstellen bcf STATUS, RP0 ; auf Bank 0 zurückschalten movwf TMR0 movlw 5 movwf Digit movlw 32 movwf Timer2 clrf PORTA ; Port A löschen clrf PORTB ; Port B löschen clrf PORTC ; Port C löschen clrf ziffer1 ; Register Ziffer1 löschen clrf ziffer2 ; Register Ziffer2 löschen clrf ziffer3 ; Register Ziffer3 löschen clrf ziffer4 ; Register Ziffer4 löschen clrf STARTEN ; Hilfsregister löschen bsf INTCON, T0IE ; Timer0 interupt erlauben bsf INTCON, GIE ; Interupt erlauben ;*********************************************************************************************************************** ; Schleife für Ziffer 1 RECHTS_LINKS_1 btfsc PORTC, 2 ; Taster OK = 1 > goto ZAEHLEN goto ZEAHLEN btfsc PORTC, 4 ; Taster Rechts = 1 > call Rechts_1 call RECHTS_1 btfsc PORTC, 0 ; Taster Links = 1 > call Links_1 call LINKS_1 PLUS_MINUS_1 btfsc PORTC, 3 ; Taster Plus = 1 > call Plus_1 call PLUS_1 btfsc PORTC, 1 ; Taster Minus = 1 > call Minus_1 call MINUS_1 goto RECHTS_LINKS_1 ; Schleife für 1. Ziffer von vorn PLUS_1 call Wait ; Taster enprellen incf ziffer1, F ; erhöhe ziffer1 um 1 movlw d'6' ; schreibe 6 nach W subwf ziffer1, W ; ziehe von ziffer1 W (6) ab btfsc STATUS, Z clrf ziffer1 ; ergab die subtraktion 0 schreibe 0 nach ziffer1 return ; ergab die subtraktion >/< 0 belasse ziffer1 MINUS_1 call Wait ; Taster enprellen movlw d'1' ; schreibe 1 nach W subwf ziffer1, F ; ziehe von ziffer1 W (1) ab movlw d'5' ; schreibe 5 nach W btfss STATUS, C movwf ziffer1 ; ergab die subtraktion < 0 schreibe 5 nach ziffer1 return ; ergab die subtraktion >= 0 belasse ziffer1 RECHTS_1 call Wait ; Taster enprellen goto RECHTS_LINKS_2 ; aus Schleife 1. Ziffer in Schleife 2. Ziffer wechseln LINKS_1 call Wait ; Taster enprellen goto RECHTS_LINKS_4 ; aus Schleife 1. Ziffer in Schleife 4. Ziffer wechseln ;*********************************************************************************************************************** ; Schleife für Ziffer 2 RECHTS_LINKS_2 btfsc PORTC, 2 ; Taster OK = 1 > goto ZAEHLEN goto ZEAHLEN btfsc PORTC, 4 ; Taster Rechts = 1 > call Rechts_2 call RECHTS_2 btfsc PORTC, 0 ; Taster Links = 1 > call Links_2 call LINKS_2 PLUS_MINUS_2 btfsc PORTC, 3 ; Taster Plus = 1 > call Plus_2 call PLUS_2 btfsc PORTC, 1 ; Taster Minus = 1 > call Minus_2 call MINUS_2 goto RECHTS_LINKS_2 ; Schleife für 2. Ziffer von vorn PLUS_2 call Wait ; Taster enprellen incf ziffer2, F ; erhöhe ziffer2 um 1 movlw d'10' ; schreibe 10 nach W subwf ziffer2, W ; ziehe von ziffer2 W (10) ab btfsc STATUS, Z clrf ziffer2 ; ergab die subtraktion 0 schreibe 0 nach ziffer2 return ; ergab die subtraktion >/< 0 belasse ziffer2 MINUS_2 call Wait ; Taster enprellen movlw d'1' ; schreibe 1 nach W subwf ziffer2, F ; ziehe von ziffer2 W (1) ab movlw d'9' ; schreibe 9 nach W btfss STATUS, C movwf ziffer2 ; ergab die subtraktion < 0 schreibe 9 nach ziffer2 return ; ergab die subtraktion >= 0 belasse ziffer2 RECHTS_2 call Wait ; Taster enprellen goto RECHTS_LINKS_3 ; aus Schleife 2. Ziffer in Schleife 3. Ziffer wechseln LINKS_2 call Wait ; Taster enprellen goto RECHTS_LINKS_1 ; aus Schleife 2. Ziffer in Schleife 1. Ziffer wechseln ;*********************************************************************************************************************** ; Schleife für Ziffer 3 RECHTS_LINKS_3 btfsc PORTC, 2 ; Taster OK = 1 > goto ZAEHLEN goto ZEAHLEN btfsc PORTC, 4 ; Taster Rechts = 1 > call Rechts_3 call RECHTS_3 btfsc PORTC, 0 ; Taster Links = 1 > call Links_3 call LINKS_3 PLUS_MINUS_3 btfsc PORTC, 3 ; Taster Plus = 1 > call Plus_3 call PLUS_3 btfsc PORTC, 1 ; Taster Minus = 1 > call Minus_3 call MINUS_3 goto RECHTS_LINKS_3 ; Schleife für 3. Ziffer von vorn PLUS_ call Wait ; Taster enprellen incf ziffer3, F ; erhöhe ziffer3 um 1 movlw d'6' ; schreibe 6 nach W subwf ziffer3, W ; ziehe von ziffer3 W (6) ab btfsc STATUS, Z clrf ziffer3 ; ergab die subtraktion 0 schreibe 0 nach ziffer3 return ; ergab die subtraktion >/< 0 belasse ziffer3 MINUS_3 call Wait ; Taster enprellen movlw d'1' ; schreibe 1 nach W subwf ziffer3, F ; ziehe von ziffer3 W (1) ab movlw d'5' ; schreibe 5 nach W btfss STATUS, C movwf ziffer3 ; ergab die subtraktion < 0 schreibe 5 nach ziffer3 return ; ergab die subtraktion >= 0 belasse ziffer3 RECHTS_3 call Wait ; Taster enprellen goto RECHTS_LINKS_4 ; aus Schleife 3. Ziffer in Schleife 4. Ziffer wechseln LINKS_3 call Wait ; Taster enprellen goto RECHTS_LINKS_2 ; aus Schleife 3. Ziffer in Schleife 2. Ziffer wechseln ;*********************************************************************************************************************** ; Schleife für Ziffer 4 RECHTS_LINKS_4 btfsc PORTC, 2 ; Taster OK = 1 > goto ZAEHLEN goto ZEAHLEN btfsc PORTC, 4 ; Taster Rechts = 1 > call Rechts_4 call RECHTS_4 btfsc PORTC, 0 ; Taster Links = 1 > call Links_4 call LINKS_4 PLUS_MINUS_4 btfsc PORTC, 3 ; Taster Plus = 1 > call Plus_4 call PLUS_4 btfsc PORTC, 1 ; Taster Minus = 1 > call Minus_4 call MINUS_4 goto RECHTS_LINKS_4 ; Schleife für 4. Ziffer von vorn PLUS_4 call Wait ; Taster enprellen incf ziffer4, F ; erhöhe ziffer4 um 1 movlw d'10' ; schreibe 10 nach W subwf ziffer4, W ; ziehe von ziffer4 W (10) ab btfsc STATUS, Z clrf ziffer4 ; ergab die subtraktion 0 schreibe 0 nach ziffer4 return ; ergab die subtraktion >/< 0 belasse ziffer4 MINUS_4 call Wait ; Taster enprellen movlw d'1' ; schreibe 1 nach W subwf ziffer4, F ; ziehe von ziffer4 W (1) ab movlw d'9' ; schreibe 9 nach W btfss STATUS, C movwf ziffer4 ; ergab die subtraktion < 0 schreibe 9 nach ziffer4 return ; ergab die subtraktion >= 0 belasse ziffer4 RECHTS_4 call Wait ; Taster enprellen goto RECHTS_LINKS_1 ; aus Schleife 4. Ziffer in Schleife 1. Ziffer wechseln LINKS_4 call Wait ; Taster enprellen goto RECHTS_LINKS_3 ; aus Schleife 4. Ziffer in Schleife 3. Ziffer wechseln ;*********************************************************************************************************************** ; Schleife während "Count-Zeit" ZEAHLEN call Wait ; OK-Taster entprellen bsf PORTA, 0 ; Relais einschalten bsf STARTEN, 0 ; Counter (indirekt) einschalten ZAEHLEN2 incf ziffer1, W ; ziffer1 um 1 erhöhen movwf ZZZZ ; Wert in ZZZZ zwischenspeichern decfsz ZZZZ, F ; von ZZZZ 1 abziehen goto ZAEHLEN2 ; ist das Ergebnis <> 0 von vorn überprüfen, ; sonst weiter zu ziffer2 incf ziffer2, W ; ziffer2 um 1 erhöhen movwf ZZZZ ; Wert in ZZZZ zwischenspeichern decfsz ZZZZ, F ; von ZZZZ 1 abziehen goto ZAEHLEN2 ; ist das Ergebnis <> 0 von vorn überprüfen, ; sonst weiter zu ziffer3 incf ziffer3, W ; ziffer3 um 1 erhöhen movwf ZZZZ ; Wert in ZZZZ zwischenspeichern decfsz ZZZZ, F ; von ZZZZ 1 abziehen goto ZAEHLEN2 ; ist das Ergebnis <> 0 von vorn überprüfen, ; sonst weiter zu ziffer4 incf ziffer4, W ; ziffer4 um 1 erhöhen movwf ZZZZ ; Wert in ZZZZ zwischenspeichern decfsz ZZZZ, F ; von ZZZZ 1 abziehen goto ZAEHLEN2 ; ist das Ergebnis <> 0 von vorn überprüfen: ; sonst weiter zu Relais abschalten und Counter stoppen bcf PORTA, 0 ; Relais ausschalten bcf STARTEN, 0 ; Counter stoppen goto RECHTS_LINKS_1 ; Zurück zur Schleife für Ziffer 1 ;*********************************************************************************************************************** ; BCD-Tabelle Segmente addwf PCL, f retlw B'00000000' ; 0 retlw B'00010000' ; 1 retlw B'10000000' ; 2 retlw B'10010000' ; 3 retlw B'01000000' ; 4 retlw B'01010000' ; 5 retlw B'11000000' ; 6 retlw B'11010000' ; 7 retlw B'00100000' ; 8 retlw B'00110000' ; 9 ;*********************************************************************************************************************** ; Tasterentprellung Wait movlw D'200' ; 200 ms Pause movwf loops Wai movlw .110 ; Zeitkonstante für 1ms movwf loops2 Wai2 nop nop nop nop nop nop decfsz loops2, F ; 1 ms vorbei? goto Wai2 ; nein, noch nicht decfsz loops, F ; 250 ms vorbei? goto Wai ; nein, noch nicht retlw 0 ; das Warten hat ein Ende end