Das Elektronik-Portal
 

Programmierung PIC16F84 Timerverlängerung

Volker1234
Neuling
Avatar
Geschlecht: keine Angabe
Beiträge: 1
Dabei seit: 08 / 2005
Karma: 0
Betreff:

Programmierung PIC16F84 Timerverlängerung

 · 
Gepostet: 10.08.2005 - 12:25 Uhr  ·  #1
Hallo,
ich nutze eine PIC16F84 zur Steuerung meiner Schaltung.
Durch diese Schaltung möchte ich zeitverzögert einen kleinen PC
ausschalten. Dieser Ausschaltimpuls soll noch 30min von der Schaltung
erzeugt werden.(jetzt 255 Sek.=maximale Zeit).
Dann wird ein Shutdownprogramm auf dem PC gestartet (gibt es jetzt
schin) mir geht es darum den Timer für die 255Sek. zu verlängern (auf
1800 Sekunden) hat jemande dazu eine Idee.
Vielen Dank für eure Hilfe.
Gruss Volker
Hier das Programm:
;********************************************************************
;
; program : DMC0204h.asm
; function: Automatische Powerdownschaltung für Rechner in einem Bus
;
; Rev. : Jörg Haustein
; Volker Wehrmann
;
;
; version history
; Ursprung Bus-JH.asm
; V0.1beta 19.03.2002
; V1.0 23.03.2002 (Testlauf i.O. Alle Funktionen erfüllt), kurze Zeitabläufe zum Testen
; 02.04.2002 Änderung Zuordnung der Ausgänge im INC File
; 04.04.2002 Shutdown kommt perm. mit Zündung, geht aus wenn shutdownphase eingeleitet wird
; 04.04.2002 Ausgänge für Shutdown und Halt getauscht, so dass DSR(CTS) Zuordnung paßt
; DMC1403 14.03.2003 Eingang RTS für Relais (Display AN/Aus) hinzugefügt (DyFiMotiveController V1)
; DMC02043 02.04.2003 Abfangen eines flatternden RTS Eingang in der Bootpase des Motherboards
; 02.04.2004 Ändern der Wartezeit von 30 auf 125 Sekunden bis Shutdownphase beginnt
; DMC30min 10.08.2005 Ändern der Wartezeit von 125 auf 1800 Sekunden bis Shutdownphase beginnt
; Vorführsystem Bamberg
;
;
;Programmbeschreibung:
; Ausgänge: Relais für Stromversorgung Rechner
; Ausgang "Halt"
; Ausgang "Tuer"
; Ausgang Debug LED;
; Eingänge: Zündung an
; Halt Taster
; Tuer Taster
;
; Anforderungen;
; Nach dem Einschalten des Prozessors soll zunächst lediglich das Signal "Zündung" abgefragt werden.
; Erscheint dieses Signal, wird das Relais eingeschaltet. Der Rechner fährt hoch. In diesem Zustand
; wird das Signal Tuer und Halt abgefragt und 1:1 an den entsprechenden Ausgängen angezeigt. Wird die Zündung
; nun für länger als eine bestimmte Zeit ausgeschaltet (mehere Minuten) wird ein Herunterfahren des Rechners eingeleitet.
; Vor Ablauf dieser Verzögerung kann durch Einschalten der Zündung ein Herunterfahren verhindert werden.
; Wird die Zeit (Zündung aus) jedoch überschritten, gibt es kein zurück mehr. Die Tasten Halt und Tuer werden nicht
; mehr abgefragt und der Zustand am Ausgang ist '0'. Der Ausgang "SHUTDOWN" wird gesetzt und signalisiert dem Rechner
; den gewünschten Abschaltvorgang. Nach einer festgelegten Zeit, in der Computer sicher heruntergefahren sein sollte,
; wird das Relais (und das Shutdownsignal) abgeschaltet. Der Rechner ist somit stromlos. Jetzt läuft eine weitere Verzögerung
; ab (ca. 1 Minute). Damit ist gewährleistet, das der Strom sicher für einige Zeit abgeschaltet war. Danach wartet das Programm
; wieder auf das Signal Zündung.
;
; Kurzbeschreibung des Programms:
;
; Haupbestandteil des Programms ist die Interruptroutine, die durch einen Timerüberlauf (INTCON) etwa alle 30ms angesprochen
; wird. In dieser Routine werden die Eingänge abgefragt und das Register "IRQ_TIMER" incrementiert. Erreicht dieser "Timner"
; einen bestimmten Wert wird das Blinkflag "getoggelt" und ein weiterer Zähler "IRQ_TIMER2" um 1 erhöht. "IRQ_TIMER" bestimmt
; die Blinkfrequenz der Debug LED und wie oft "IRQ_TIMER2" erhöht wird. "IRQ_TIMER2" wird an meheren Stellen im Programm
; abgefragt. Die Verzögerungen errechnen sich also aus der "Blinkfrequenz" * Zählerstand von "IRQ_TIMER2".
;
; Nach dem Einschalten und nach einem Ansprechen der integrierten WDT initialisiert sich das Programm und landet in "MAIN"
; In "Main" wird die Debug LED in Abhängigkeit von "IRQ_TIMER" ein- und ausgeschaltet und das Vorhandensein der Zündung
; abgefragt. Wenn die Zündung einmal eingeschaltet wurde springt das Programm in "BUS_AN". Das Relais wird dort eingeschaltet
; und der "MERKER1" gesetzt. Von nun an werden auch die Tasten "Halt" und Tuer" abgefragt und der Zählerstand "IRQ_TIMER2"
; kontrolliert. Bleibt die Zündung eingeschaltet wird dieser Zähler ständig zu Null gesetzt und alles bleibt wie es ist.
; Bleibt das Zündungssignal weg wird die Routine "BUS_AN" nicht mehr angesprungen und der Zähler nicht mehr zurückgesetzt.
;
; Erreicht der Zähler einen bestimmten Wert wird die Rouitine "POWERDOWN" angesprungen. Die Debug LED blinkt jetzt nicht
; mehr und die Signal Tuer und Halt erlischen. Das Signal "SHUTDOWN" wird hight. Die zweite Verzögerung zum Rechner herunter-
; fahren wird genauso realisiert wie zuvor beschrieben. Danach werden alle Signale (also auch das 24V Relais) abgeschaltet.
; und der Merker1 gelöscht. Jetzt kommt wieder eine Verzögerung (gleiche Realisierung) damit der Rechner auf alle Fälle
; eine Zeit ausgeschaltet war. Dann geht es mit dem Hauptprogramm weiter (MAIN).
;
; Sollte dieses Programm einmal abstürzen schlägt bereits nach etwa 30ms der WDT Timer zu (dieser wird im Programm regelmäßig
; zurückgesetzt) und das Programm initialisiert sich wieder.
; Da auch die Eingänge in der Interruptroutine nur alle ca. 30ms abgefragt werden, wird ein Tasterprellen sicher verhindert.
;

;********************************************************************
; PIC16C84 is the target processor
;********************************************************************

LIST P=PIC16F84

; include the port and register definition file from MPASM
; and selfdefined registers and procedures

#include p16f84.inc
#include dmc02043.inc

; configure PIC
; WDT = on, quarz oscillator, power on reset, no code protection

__CONFIG _WDT_ON & _XT_OSC & _PWRTE_ON & _CP_OFF

;********************************************************************
; running program at label start, be sure for reset vector!
;********************************************************************

org 0
goto START
org 4
goto IRQ_PROC_1

; space for other interrupt calls

;********************************************************************
; interrupt vector routine
;********************************************************************

IRQ_PROC_1
;
; save the work and statusregisters before
movwf tempWORK
movf STATUS, W
movwf tempSTATUS

btfsc INTCON,INTF ;Wurde der Interrupt von RB0 ausgelöst?
nop ;noch frei für RB0 Interrupt...
bcf T_SPEZIAL,7 ;Tastenflag löschen
movf PORTA,W ;Port A ins Workregister
movwf tempTASTEN ;und ab in Register 'tempTasten'
andlw B'00001111' ;nicht existierende Tasten ausblenden
xorlw B'00001111' ;xor mit 7 alle Tasten frei (Pull UP)
btfss STATUS,Z ;Zeroflag abfragen
bsf T_SPEZIAL,7 ;Tastenflag setzen

incf IRQ_TIMER,F
movf IRQ_TIMER,W
sublw D'15' ;!! Hier Blinkfrequenz einstellen !!
btfsc STATUS,C ;Überlauf?
goto irq_ex ;Wenn nicht... ...raus hier!


incf IRQ_TIMER2,F ;"Timer2" alle 'n' Sekunden hochzählen.
incf IRQ_TIMER3,F ;"Timer3" alle ´n´ Sekunden hochzählen******************************
clrf IRQ_TIMER ;Timer zurücksetzen
btfsc BLINK_FLAG ;Blinkflag gesetzt?
goto $+3 ;Nein! Dann aus...
bsf BLINK_FLAG ;Blinkflag on
goto $+2
bcf BLINK_FLAG ;Blinkflag off

; restore the previous status and workregister
irq_ex: bcf INTCON,INTF ;RB0 Überlaufflag löschen
bcf INTCON,T0IF ;Timer 0 Überlaufflag löschen
movf tempSTATUS, W
movwf STATUS
movf tempWORK, W

; return to program from interrupt

retfie

;********************************************************************
; INITIALIZE: initialize the program, set input, output ports,
;********************************************************************

INITIALIZE
;
clrf PORTB ;Port B alle auf 0
clrf T_SPEZIAL
clrf IRQ_TIMER
clrf IRQ_TIMER2 ;Beide Zähler zurücksetzen
SEL_BANK1 ;Umschalten auf Bank 1
movlw SET_PORT_A ;Init Port A
movwf TRISA
movlw SET_PORT_B ;Init Port A
movwf TRISB
movlw SET_OPTION_REG ;Init Optionregister
movwf OPTION_REG
SEL_BANK0 ;zurück zu Bank 0
movlw SET_IRQ ;Init Interuptregister
movwf INTCON
return


;********************************************************************
; START: start the program here after reset or WDT
;
; if the program starts, because of a WDT (watchdog) call,
; then
; initialize the program,
; if not (power on reset, then do
; the same... (Auf alle Fälle kennt diese
; Routine den Unterschied!)
;********************************************************************
START btfsc IRQ_WDT
goto NO_WDT

YES_WDT: call INITIALIZE
goto MAIN

NO_WDT: call INITIALIZE
goto MAIN

;********************************************************************
; MAIN: main program part, asks for keys
;********************************************************************

MAIN
;
btfss MERKER1 ;wurde die Zündung schon eingeschaltet ?
bcf MERKER2 ;nein, dann Merker löschen

btfss MERKER1 ;wurde die Zündung schon mal eingeschaltet?
clrf IRQ_TIMER3 ;nein, dann Timer löschen

btfsc BLINK_FLAG ;Nur zur Kontrolle! Kann weg!
bsf PORTB,7
btfss BLINK_FLAG
bcf PORTB,7 ;** Kontrollende **

clrwdt ;Watchdog beruhigen.

btfss KEY_24V ;Zündung an?
call BUS_AN ;Ja!

btfss MERKER1 ;(Wurde die Zündung schon mal eingeschaltet?)
goto MAIN ;wenn nicht > weiter auf Zündung warten!


movf IRQ_TIMER2,W
sublw D'1800' ;Kontrollieren ob Zündung lange genug aus...= Verzögerung bis Shutdownphase
btfss STATUS,C ;Überlauf?
goto POWERDOWN ;Zeit ist um, jetzt gibt's kein Zurück.


btfsc MERKER1 ;wenn Zündung an
bsf SHUTDOWN ;... wird das shutdownsignal gesetzt--> d.h Rechner wird nicht runtergefahren

btfsc KEY_HALT ;Wenn Taste "Halt" gedrückt wird...
bcf HALT ;...wird das Signal durchgereicht.
btfss KEY_HALT ;Keine Taste...
bsf HALT ;...kein Signal

btfsc KEY_TUER ;Wenn Türsignal kommt...
bcf TUER ;...wird das Signal durchgereicht.
btfss KEY_TUER ;Wenn nicht...
bsf TUER ;...dann nicht.





btfsc MERKER2
call DISPLAY_ONREAL



btfsc MERKER2 ;ääääääääääääääääääääääääääääääääääääääääääääääääääääääääääääääääääääääääääääääääääääää
goto MAIN

movf IRQ_TIMER3,W ;**************************************************************************************
sublw D'60' ;
btfss STATUS,C ;Überlauf?
call DISPLAY_ON ;Zeit ist um, jetzt ist das RTS-Signal gültig.*****************************************



goto MAIN ;Do it forever... (accept WDT)


DISPLAY_ON bsf MERKER2
return

DISPLAY_ONREAL btfsc RTS
bcf Display
btfss RTS
bsf Display
return



;*** Solange der Bus an ist, wird der Timer zurückgesetzt und das Relais gibt Dampf.

BUS_AN clrf IRQ_TIMER2 ;"Timer" löschen
bsf MERKER1 ;Merken das Zündung eingeschaltet wurde
bsf RELAIS ;Relais einschalten.
return

;*** Routine für Pwoerdown.

POWERDOWN bcf MERKER2

bcf SHUTDOWN ;Shutdownsignal geben
bcf HALT ;Halt Signal aus
bcf TUER ;Tuer Signal aus

bcf Display ;Display aus****************************************************************

clrf IRQ_TIMER2 ;"Timer" löschen

clrwdt ;Watchdog beruhigen.
movf IRQ_TIMER2,W
sublw D'45' ;Warten bis Rechner heruntergefahren ist...= Abschaltverzögerung für Hardware
btfsc STATUS,C ;Überlauf?
goto $-4 ;...wenn nicht Timer weiter abfragen.
bcf RELAIS ;Strom abschalten, Rechner aus.
bcf SHUTDOWN ;Shutdownsignal wieder abschalten

clrf IRQ_TIMER2 ;"Timer" löschen

clrwdt ;Watchdog beruhigen.
movf IRQ_TIMER2,W
sublw D'3' ;Wiederanlaufsperre. Rchner ist mindestens x Sekunden aus...
btfsc STATUS,C ;Überlauf?
goto $-4 ;...wenn nicht Timer weiter abfragen.
clrf IRQ_TIMER2 ;"Timer" löschen
bcf MERKER1 ;Merker 1 zurücksetzen ("Zündungsmerker")

goto MAIN ;Zurück ins Hauptprogramm und gucken ob Zündung wieder an...

end

;********************************************************************
; end of program
;********************************************************************
Gewählte Zitate für Mehrfachzitierung:   0

Tags für dieses Thema

Programmierung, PIC16F84, Timerverlängerung