; Licht-Verlängerung-Empfänger
;Hardware: PIC12F508 in Funkschaltsteckdose „EverFlourish EMW202R-1“
; ╔════╗╔════╗
; 5P 1╢ 5P ╚╝ 00 ╟8 00
;R1 Adressjumper 2╢ GP5 GP0 ╟7 Relais (H-aktiv)
;R3 Adressjumper 3╢ GP4 GP1 ╟6 Funkempfänger CMI2210L (H-aktiv)
; frei 4╢ MCLR GP2 ╟5 Kontrollausgang (LED, H-aktiv)
; ╚══════════╝
;Der eingebaute Controller erfüllt nicht die Randbedingung,
;als retriggerbares Monoflop agieren zu müssen: Neuprogrammierung.
;Der pinkompatible PIC12F629 bietet überall Pullups, nicht nur an GP0+1.
;Der pinkompatible PIC12F1501 bietet Low-Voltage-Programmierung.
;Der eingebaute Controller konnte nicht elektronisch identifiziert werden.
;Adressjumper GP5/R1 GP4/R3 Mittleres Byte Adresse aus GP5:4
;Steckdose 1 H L/2kΩ 0x15 2
;Steckdose 2 L/2kΩ H 0x45 1
;Steckdose 3 H H 0x51 3
;(Nummer 4) L L 0x54 0
;220130 erstellt
;220225 erprobt (als Nummer 3)
;220313 erprobt (als Nummer 2), Bugfix Tabelle 1↔2
radix dec
list n=0,st=off
nolist
include "p12f508.inc"
list
__idlocs (2022-1980)*512+2*32+16 ; FAT-Datum: Jahr, Monat,Tag
__config _IntRC_OSC ; Interner Oszillator 4 MHz = 1 MIPS
cblock 0x10
bitct ; Bitzähler 0..24
bitsh:3 ; 3 Bytes = 24 Bits
tic ; Timer0-Capture
ticr ; Timer0-Capture bei steigender Flanke
ontime:2 ; 2 Bytes = 16 Bits Überlaufzähler Timer0: 2 Minuten
t0 ; temporär
codeh ; Mittleres Byte des Ein- und Ausschaltkodes
endc
code1 equ 0x154557 ; Einschaltkode Steckdose 2
code0 equ 0x154554 ; Ausschaltkode Steckdose 2
VTS equ 4 ; TMR0-Vorteiler (16) als Schiebewert
org 0
movwf OSCCAL
;Adressjumper einlesen: Da GP4+5 kein Pullup haben,
;diese Ports kurz auf H programmieren und H (Ladung) bzw. L (Jumper) einlesen.
;Danach die auf H liegenden Eingänge als Ausgang und die mit L auf Eingang
;programmieren
movlw 0x3A
movwf GPIO ; Relais aus
movlw 0x0A
tris GPIO ; Ausgang aktivieren; GP5:4 kurz auf H
movlw 0x3A
tris GPIO ; GP5:4 als Eingang
nop
movfw GPIO ; GP5:4 einlesen
movwf t0
andlw 0x30
iorlw 0x3A ; 0 -> Eingang, 1 -> Ausgang
tris GPIO
call get_codeh
movwf codeh
;Mit Bitzeiten von 1,3 ms muss der Timer0 mit Vorteiler ≥8 betrieben werden.
;Hier 16 für Messzeiten bis 4 ms.
movlw 0x80|(VTS-1) ; Timer0 Vorteiler 16, Pullup an GP1 aktivieren
option
_vorn bcf GPIO,2
clrf bitct
_wrise call ckTO ; aktualisiert <tic>
btfss GPIO,1
goto _wrise
;Die steigende Flanke muss, außer bei bitct==0, 1,3 ms nach der vorhergehenden Flanke kommen
movfw ticr
subwf tic,w
movwf t0 ; t0 = vergangene Ticks, typ. 1200>>4
addwf ticr,f ; ticr = tic: Speichern
movfw bitct
bz _wfall
movlw 1000>>VTS ; 1 ms = 0x3E
subwf t0,w ; w = Δt-1ms
bnc _vorn ; zu kurz
movlw 1600>>VTS ; 1,6 ms = 0x64
subwf t0,w
bc _vorn ; zu lang
_wfall call ckTO ; aktualisiert <tic>
btfsc GPIO,1
goto _wfall
; Die fallende Flanke entscheidet über die Bitwertigkeit
movfw ticr
subwf tic,w
movwf t0 ; t0 = vergangene Ticks, typ. 300>>4 oder 900>>4
movlw 200>>VTS ; 0,2 ms = 0x0C
subwf t0,w
bnc _vorn ; zu kurz
movlw 1500>>VTS ; 1,5 ms = 0x5D
subwf t0,w
bc _vorn ; zu lang
movlw 650>>VTS ; 0,65 ms = 0x28
subwf t0,w ; C = Bit (richtige Polarität)
movfw bitct
xorlw 24 ; verändert C nicht!
bz _stopb
incf bitct,f ; Nicht über 24 hinaus inkrementieren
_sh0 rlf bitsh,f
rlf bitsh+1,f
rlf bitsh+2,f ; Bit einschieben
goto _wrise ; nächstes Bit abwarten
_stopb
bsf GPIO,2 ; Code /irgendeiner/ Fernbedienung empfangen
bc _sh0 ; 1-Bit weiter einschieben
; Angekommenes Telegramm mit Ein- und Ausschaltkode vergleichen,
; die XOR-Befehle belassen allesamt C auf 0
movfw bitsh+2
xorlw upper(code1)
bnz _sh0 ; Falscher Kode, 0-Bit einschieben
movfw bitsh+1
xorwf codeh,w ; Mittleres Byte, je nach Jumper
bnz _sh0 ; Falscher Kode, 0-Bit einschieben
movfw bitsh
xorlw low(code1)
bz _ein ; Richtiger Einschalt-Kode
xorlw low(code1^code0)
bnz _sh0 ; Falscher Kode, 0-Bit einschieben
bcf GPIO,0 ; Richtiger Ausschalt-Kode: Relais aus
goto _vorn
_ein
bsf GPIO,0 ; Relais einschalten
movlw high(120000000>>VTS) ; 0x70
movwf ontime
movlw upper(120000000>>VTS) ; 120 s = 2 Minuten = 0x72
movwf ontime+1 ; Ausschalt-Timer starten
goto _vorn
ckTO movfw tic
subwf TMR0,w ; w = vergangene Ticks
addwf tic,f ; tic = TMR0 und C bei Überlauf
skpc
retlw 0 ; kein Timer0-Überlauf stattgefunden
clrwdt ; Timer0: 4 ms, Watchdog: 16 ms
btfss GPIO,0 ; Relais ein?
retlw 1 ; keine Zeitmessung aktiv
decf ontime,f
skpnz
decf ontime+1,f
skpnz
bcf GPIO,0 ; Relais per Timeout ausschalten
retlw 2 ; Zeitüberschreitung für Licht aufgetreten
get_codeh
swapf t0,w
andlw 3
addwf PCL,f
dt 0x54,0x45,0x15,0x51
end
Detected encoding: UTF-8 | 0
|