Source file: /~heha/basteln/Auto/Kram/Traktorstrahl.zip/ts.a12

;„Traktorstrahl“: Batterieschonende Lichtsteuerung für Fahrerhaus eines Traktors
;Hardware: PIC10F200/202/204/206 (SOT23-6) in einfacher Schaltung
;			 ╔════╗╔════╗
;Türkontakt nach Masse	1╢ GP0╚╝GP3 ╟6	frei
;		00	2╢ 00	 5P ╟5	5P
;(frei für Zündung)	3╢ GP1	GP2 ╟4	PWM-Ausgang zum LED-Treiber
;			 ╚══════════╝
; Zeiten in Sekunden
#define TIMEOUT 30
#define RAMPDOWN 8
	radix	dec
	list	n=0,st=off
	nolist
	include	"p10f206.inc"
	list

	__idlocs (2022-1980)*512+4*32+12	; FAT-Datum: Jahr, Monat,Tag
	__config _IntRC_OSC	; Interner Oszillator 4 MHz = 1 MIPS
	cblock	0x10
to1:2
pins
	endc
	
	org	0
	movwf	OSCCAL
; Jedes Reset (auch Watchdog) setzt TRIS (nicht GPIO) zurück.
; Dadurch kurze Aus-Nadel alle 18 ms
	movlw	8+2+1
	tris	GPIO		; GP2 als Ausgang, alles andere bleibt Eingang
	movlw	0x84		; Timer0 Vorteiler 32, Pullup an GP0 aktivieren
	option
; Reset-Ursache: Watchdog-Timeout (nominell 18 ms)
	btfss	STATUS,4
	 goto	_watchdog
; Reset-Ursache: PowerOn:
	bcf	CMCON0,3	; Komparator ausschalten(!!)

; Erst mal einschalten, für 30 s
_full_on:
	bsf	GPIO,2		; Ausgang auf High
	movfw	GPIO		; Pegel der Inputpins einlesen
	movwf	pins		; abspeichern
	movlw	low(TIMEOUT*1000/18)
	movwf	to1
	movlw	high(TIMEOUT*1000/18)
	movwf	to1+1		; Software-Timer neu starten
	sleep

_watchdog:
	call	pinchange
	bnz	_full_on
	btfss	GPIO,2		; Wenn ein, Timeout-Zähler runterzählen
	 sleep			; Wenn aus, bleibt alles aus
	movlw	-1
	addwf	to1,f		; C gelöscht wenn 0 => 0xFF (= Überlauf), sonst C gesetzt
	skpc
	 addwf	to1+1,f		; High-Teil dekrementieren
	skpnc
	 sleep
; Zähler zählt von 0 nach 0xFFFF: Zeit die Lichter auszumachen

; Eine Hardware-PWM steht nicht zur Verfügung, daher per Software.
; Der Timer wird alle 32 µs getaktet und läuft alle 8 ms über, ergibt 122 Hz
; <to1+1> beinhaltet den Timer-Compare zum Ausschalten; Einschalten bei Null
; Von einem TMR0-Test zum nächsten dürfen nicht mehr als 32 Takte vergehen!
_l0:	movfw	to1+1
	xorwf	TMR0,w
	bnz	_l0		; warten bis Timer == [to1+1]
	bcf	GPIO,2		; Aus bei Erreichen von [to1+1]
	movlw	-(65536*8192/(RAMPDOWN*1000000))
	addwf	to1,f
	movlw	0
	skpc
	 movlw	-1		; 0 oder (bei Überlauf) 1 subtrahieren
	addwf	to1+1,f		; und auf 0 testen
	skpnz
	 sleep			; Wenn 0 erreicht, nicht weitermachen
_l1:	movfw	TMR0
	bnz	_l1		; warten bis Timer == 0
	bsf	GPIO,2		; Ein bei Erreichen von 0
	clrwdt			; Alle 8 ms: Hier darf der Watchdog nicht zuschlagen
	call	pinchange
	bnz	_full_on	; Bei Pegelwechsel während Rampe von vorn anfangen
	goto	_l0

pinchange	;liefert Z==1 für /kein/ Pegelwechsel (an GP0 und GP1)
	movfw	GPIO		; Portpins lesen, damit Pinchange funktioniert (PDF Seite 43)
	xorwf	pins,w		; Änderungen?
	andlw	3		; Nur GP0 und GP1 beachten
	retlw	0
	
	end
Detected encoding: UTF-80