;************************************************************************************************************** ; ; -=[ KFZ-Innenlichtdimmer v3 ]=- V1.04e 26.04.2004 ; ; (C) by CoolChip ; ;************************************************************************************************************** ; ; Taktfrequenz: 20MHz ; ; Pinbelegung ; ----------------------------------------------------------------------------- ; PORTA: 0 * ; 1 OUT LED ; 2 * ; 3 * ; 4 * ; 5 * ; 6 OSC2 ; 7 OSC1 ; ; PORTB: 0 IN Anlasser an(1) - aus(0) ; 1 * ; 2 * ; 3 PWM *LICHT* ; 4 IN Schloss_auf aktiv(1) - nope(0) ; 5 IN Schloss_zu aktiv(1) - nope(0) ; 6 IN SU Schlüssel steckt(1) - abgezogen(0) ; 7 IN Tür auf(1) - zu(0) ; ;************************************************************************************************************** ; Befehle für COMPILER oder BURNER ; processor 16f628 #include ERRORLEVEL -302 ;SUPPRESS BANK SELECTION MESSAGES ; ; Boden off, Code Protection off, Data Protectioon off, Power-on-Timer on, ; Watchdog off, Low-Power-Programming off, Master Cear off, HS-Oscillator ; __CONFIG _BODEN_OFF & _CP_OFF & _DATA_CP_OFF & _PWRTE_ON & _WDT_OFF & _LVP_OFF & _MCLRE_OFF & _HS_OSC ; ;************************************************************************************************************** ; Variablen festlegen 20h ... 7Fh ; loops equ 0x20 ; Zähler für Warteschleife loops2 equ 0x21 ; Zähler für untere Warteschleife xflags equ 0x22 ; Platz für zusätzliche Flags pb_save equ 0x23 ; letzter Zustand von PortB licht_zeit equ 0x24 ; Zähler für Licht_an Timer todo equ 0x25 ; Was machen nach Interrupt? ; 0 := nix ; 1 := andimmen [normal] ; 2 := ausdimmen [normal] ; 3 := andimmen [schnell] ; 4 := ausdimmen [schnell] ; 5 := andimmen [normal] [timer] ; 6 := ausdimmen [normal] [f_flash] ; 7 := [timer] ; 8 := Motor an, Tür offen W_save equ 0x70 ; Backup für Akku Status_save equ 0x71 ; Backup für Status-Bits ; Flag bits (FLAGS) ; #define motor xflags, 0 ; Motorzustand-Flag #define led PORTA, 1 ; LED Ausgang ; ;************************************************************************************************************** ; Sprung zum Programmanfang org 0x0000 goto init ;************************************************************************************************************** ; Interruptroutine org 0x0004 movwf W_save ; erstmal Backup machen swapf STATUS,W bcf STATUS, RP0 ; Bank0 movwf Status_save ; --------------------------I-N-T-R-O--------------------------- ; Überprüfung auf Störung call pause50 ; Störungswartezeit (entprellen) ; *** PortB & Anlasser Interrupt *** btfsc INTCON, INTF ; RB0_Int gesetzt? goto anlasser_int btfsc INTCON, RBIF ; PortB_Int gesetzt? goto portb_int anlasser_int btfss PORTB, 0 goto int_noaction bsf motor btfss PORTB, 7 movlw d'4' ; schnell ausdimmen btfsc PORTB, 7 movlw d'8' ; Motor an, Tür offen movwf todo goto int_ende portb_int movfw pb_save xorwf PORTB, w btfsc STATUS, Z ; Hat sich was geändert goto int_noaction ; Nein movwf pb_save btfsc pb_save, 4 ; Schloss auf? goto lock_open_routine btfsc pb_save, 5 ; Schloss zu? goto lock_close_routine btfsc pb_save, 6 ; SU? goto key_out_routine btfsc pb_save, 7 ; Türänderung? goto door_rumble goto int_noaction ; Fehler !?! lock_open_routine btfss PORTB, 4 goto int_noaction btfss motor movlw d'5' ; Motor aus btfsc motor goto int_noaction ; Motor an goto portb_end lock_close_routine btfss PORTB, 5 goto int_noaction btfss motor movlw d'6' ; Motor aus btfsc motor goto int_noaction ; Motor an goto portb_end key_out_routine btfsc PORTB, 6 goto int_noaction btfss motor goto int_noaction ; Motor war aus bcf motor ; Motor war an movlw d'5' goto portb_end door_rumble btfsc PORTB, 7 goto door_open goto door_close door_open btfss motor movlw d'1' ; Motor aus btfsc motor movlw d'3' ; Motor an goto portb_end door_close btfss motor movlw d'7' ; Motor aus btfsc motor movlw d'4' ; Motor an goto portb_end portb_end movwf todo ; todo speichern goto int_ende ; ... und raus ; --------------------------O-U-T-R-O--------------------------- int_noaction movfw PORTB movwf pb_save bcf INTCON, INTF ; RB0_Int löschen bcf INTCON, RBIF ; PortB_Int löschen swapf Status_save, w ; Backup einspielen ;) movwf STATUS swapf W_save,f swapf W_save,w retfie int_ende movfw PORTB movwf pb_save bcf INTCON, INTF ; RB0_Int löschen bcf INTCON, RBIF ; PortB_Int löschen swapf Status_save, w ; Backup einspielen ;) movwf STATUS swapf W_save,f swapf W_save,w bsf INTCON, GIE ; Global Int enable goto main ; ;************************************************************************************************************** ; Initialisierung ; ;************************************************************************************************************** init ; ** Ports vorbereiten ** ; PIC16F628 alle Comparatoreingänge auf Digital umschalten bsf CMCON, CM0 bsf CMCON, CM1 bsf CMCON, CM2 ; ** Port für LED vorbereiten ** bsf STATUS, RP0 ; Bank1 movlw B'11111101' ; 0 = Output movwf TRISA bcf STATUS, RP0 ; Bank0 clrf PORTA ; PortA = 0 ; ** PWM vorbereiten ** ; Frequenz auf 78,12 kHz einstellen bsf STATUS,RP0 ; Bank1 movlw d'63' movwf PR2 ; 78,12 kHz bcf STATUS,RP0 ; Bank0 ; Tastverhältnis auf 0% einstellen movlw d'0' movwf CCPR1L ; 0% ; PWM MODE mit CCP1 initialisieren clrf CCP1CON ; CCP1-Modus aus bsf CCP1CON,CCP1M3 ; CCP1-Modus PWM-Mode bsf CCP1CON,CCP1M2 ; RC2/CCP1 Hauptschalter an bsf STATUS,RP0 ; Bank1 bcf TRISB, 3 ; TRISB<3> clear enables Output bcf STATUS,RP0 ; Bank0 ; ** Timer vorbereiten ** ; Vorteiler 1:1 und Timer2 einschalten bcf T2CON,T2CKPS0 ; Vorteiler 1:1 bcf T2CON,T2CKPS1 bsf T2CON,TMR2ON ; Timer2 ein ; ** Sonstige Register/Flags löschen/laden ** movfw PORTB ; PortB auslesen und movwf pb_save ; in pb_save speichern clrf todo bcf motor ; Motorstatusbit auf 0 ; ** Interrupts vorbereiten ** bsf STATUS, RP0 ; Bank 1 bsf OPTION_REG, INTEDG ; RB0 Interrupt bei positiver Flanke bcf STATUS, RP0 ; Bank 0 bsf INTCON, INTE ; RB0 Interrupt erlauben bsf INTCON, RBIE ; PortB Interrupt erlauben ; ** einzelne Interrupts löschen und Global einschalten ** bcf INTCON, INTF ; RB0_Int löschen ; movf PORTB, w ; Man muss das erst lesen bevor man RBIF löschen kann bcf INTCON, RBIF ; PortB_Int löschen bsf INTCON, GIE ; Global Int enable ; ** ENDE der Initalisierung call pause250 ; kleine Pause call pause250 ; ;************************************************************************************************************** ; HAUPTPROGRAMM ; ;************************************************************************************************************** main movlw d'1' ; andimmen [normal] subwf todo, w btfsc STATUS, Z ; Zero Flag an? goto dimm_an movlw d'3' ; andimmen [schnell] subwf todo, w btfsc STATUS, Z ; Zero Flag an? goto dimm_fan movlw d'2' ; ausdimmen [normal] subwf todo, w btfsc STATUS, Z ; Zero Flag an? goto dimm_aus movlw d'4' ; ausdimmen [schnell] subwf todo, w btfsc STATUS, Z ; Zero Flag an? goto dimm_faus movlw d'7' ; [timer] subwf todo, w btfsc STATUS, Z ; Zero Flag an? goto ltimer movlw d'5' ; andimmen [timer] subwf todo, w btfsc STATUS, Z ; Zero Flag an? goto dimm_an movlw d'6' ; ausdimmen [f_flash] subwf todo, w btfsc STATUS, Z ; Zero Flag an? goto dimm_aus movlw d'8' ; ausdimmen [schnell bis 20] subwf todo, w btfsc STATUS, Z ; Zero Flag an? goto tuer_error bsf led call pause50 bcf led call pause50 goto main ; ;************************************************************************************************************** ; Dimmer-Routinen ; ;************************************************************************************************************** ; Andimmen dimm_an movlw d'64' subwf CCPR1L, w btfsc STATUS, Z ; Zero Flag an? goto dimm_end ; Ja incf CCPR1L, f ; PWM um 1 erhöhen call pause40 goto dimm_an ; Schnell Andimmen dimm_fan movlw d'64' subwf CCPR1L, w btfsc STATUS, Z ; Zero Flag an? goto dimm_end ; Ja incf CCPR1L, f ; PWM um 1 erhöhen call pause10 goto dimm_fan ; Ausdimmen dimm_aus movlw d'0' subwf CCPR1L, w btfsc STATUS, Z ; Zero Flag an? goto dimm_end ; Ja decf CCPR1L, f ; PWM um 1 verkleinern call pause40 goto dimm_aus ; Schnell Ausdimmen dimm_faus movlw d'0' subwf CCPR1L, w btfsc STATUS, Z ; Zero Flag an? goto dimm_end ; Ja decf CCPR1L, f ; PWM um 1 verkleinern call pause10 goto dimm_faus ; Fertig! todo auf 0 und zurück dimm_end ;timer? movlw d'5' ; ausdimmen [timer] subwf todo, w btfsc STATUS, Z ; Zero Flag an? goto ltimer ;fflash? movlw d'6' ; ausdimmen [f_flash] subwf todo, w btfsc STATUS, Z ; Zero Flag an? goto frank_flash clrf todo goto main ; ;************************************************************************************************************** ; Frankreich-Blinker ; ;************************************************************************************************************** frank_flash call pause250 call pause250 call pause250 call f_flash call f_flash call f_flash clrf todo goto main f_flash ; Kurz aufblitzen clrf CCPR1L ; Lampe aus movlw d'64' ; Lampe an movwf CCPR1L bsf led call pause50 ; Pause call pause50 clrf CCPR1L ; Lampe aus bcf led ; Kurze Pause call pause50 ; Auf die Hälfte hochdimmen ff_andimm movlw d'4' addwf CCPR1L, f ; PWM einstellen call pause50 movlw d'32' subwf CCPR1L, w btfss STATUS, Z ; Zero Flag an? goto ff_andimm ; Nein! bsf led ; Kurze Pause call pause50 ; Wieder abdimmen ff_abdimm movlw d'4' subwf CCPR1L, f ; PWM einstellen call pause50 btfss STATUS, Z ; Zero Flag an? goto ff_abdimm ; Nein! bcf led return ; ;************************************************************************************************************** ; lTimer - Countdown bis das Licht wieder aus geht ; ;************************************************************************************************************** ltimer movf CCPR1L, f btfsc STATUS, Z ; Licht schon aus? goto dimm_end ; Ja enddimm ; Vollständig andimmen movlw d'64' subwf CCPR1L, w btfsc STATUS, Z ; Zero Flag an? goto start_timer ; Ja incf CCPR1L, f ; PWM um 1 erhöhen call pause40 goto enddimm start_timer ; Countdown starten bcf led movlw D'13' ; 13 sec. bleibt das Licht an movwf licht_zeit warten call pause250 call pause250 call pause250 call pause250 bsf led call pause50 bcf led decfsz licht_zeit, f ; Zeit vorbei? goto warten ; nein, noch nicht! movlw d'2' ; normal ausdimmen movwf todo goto main ; ;************************************************************************************************************** ; Tür auf, Motor an ; ;************************************************************************************************************** tuer_error movlw d'20' ; Herunterdimmen bis 20 subwf CCPR1L, w btfsc STATUS, Z ; Zero Flag an? goto t_error_end ; Ja decf CCPR1L, f ; PWM um 1 verkleinern call pause10 goto tuer_error t_error_end clrf todo goto main ; ;************************************************************************************************************** ; Pause-Routine ; ;************************************************************************************************************** ; Pause von 250 ms pause250 movlw D'250' movwf loops call wai return ; Pause von 100 ms pause100 movlw D'100' movwf loops call wai return ; Pause von 50 ms pause50 movlw D'50' movwf loops call wai return ; Pause von 40 ms pause40 movlw D'40' movwf loops call wai return ; Pause von 10 ms pause10 movlw D'10' movwf loops call wai return ; Warteschleife für 1 ms wai movlw D'249' ; Zeitkonstante für 1 ms movwf loops2 wai2 nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop decfsz loops2, f ; 1 ms vorbei? goto wai2 ; nein, noch nicht decfsz loops, f ; xxx ms vorbei? goto wai ; nein, noch nicht return ; das Warten hat ein Ende ; ;************************************************************************************************************** ; ENDE ; ;************************************************************************************************************** org 0x2100 de "KFZ-Innenlichtdimmer v3 (c)2004 by coolchip.de " ende end