; Rauchmelder mit 3 Zusatzsensoren und USB
radix dec
list n=0
include "p16f1455.inc"
include "mymacros.i15"
; Hardware
;1 5P
;2 RA5 Zum Rauchmelder — ohne Pullup
;3 RA4 Kontroll-LED, Low = ein
;4 !MCLR Jumper
;5 RC5 RxD OneWire DS18B20
;6 RC4 !EN Ganssensor
;7 RC3 PWM2 9-V-Erzeugung für Rauchmelder
;8 RC2 AN6 Analogausgang Gassensor
;9 RC1 SDA I²C Pyrosensor
;10 RC0 SCL I²C Pyrosensor
;11 3P3 Kondensatorstütze für USB
;12 D- USB
;13 D+ USB
;14 00
; RAM-Variablen (Bank 0 durch USB belegt)
cblock 0xA0 ; Bank 1
ds18b20id0:8 ; Vier OneWire-IDs, je 64 bit
ds18b20id1:8
ds18b20id2:8
ds18b20id3:8
rep1:16
rep2:16
rep3:10
endc
cblock 0xF0 ; Non-Banked
cnt0 ; Innerer Schleifenzähler
cnt1 ; Äußerer Schleifenzähler
endc
; Platz für Urlader
org 0x200
; Initialisierung
goto onReset
return
return
return
retfie
include "webusb.i15"
onReset:
call usbInit ;Setzt Maximale CPU-Taktfrequenz: 12 MHz
; LED ein
banksel TRISA
movlwf 0x2B,TRISA ; Bit 4 löschen
; Kein Pullup zum Rauchmelder
; PWM2-Ausgang aktivieren und Wechselspannung ausgeben
movlwf 0x37,TRISC ; Bit 3 löschen
banksel T2CON ; Bank 0
movlwf 60-1,PR2 ; glatt 200 kHz generieren (da reichen 100 nF)
movlwf 0x4C,T2CON ; 8-bit-Timer2 starten mit 12 MHz, ÷60 = 200 kHz
banksel PWM2CON ; Bank 12
clrf PWM2DCL
movlwf 30,PWM2DCH ; Tastverhältnis 1:1
movlwf 0xC0,PWM2CON ; Ausgang aktivieren
; A/D-Wandler initialisieren
banksel FVRCON
movlwf 0xF3,FVRCON ; 4,096 V auf ADC, Temperatursensor aktivieren
banksel ADCON0
movlwf 0xF0,ADCON1
movlwf 0x01,ADCON0
; Reports initialisieren (wenigstens die Report-ID)
movlwf2 ds18b20id0,FSR0
movlw 80 ;gesamte Bank 1
call ZeroMemory
banksel rep1
movlwf 1,rep1
movlwf 2,rep2
movlwf 3,rep3
_loop call usbPoll ; HID + WebUSB realisieren
banksel ADCON0
btfsc ADCON0,ADGO
bra _loop
movlwf ADRES,FSR0
movlwf rep1+4,FSR1 ;je nach Kanal: Gassensor = AN6 oder Chiptemperatur
movlw 2
call memcpy
bra _loop
; Kopiert Daten von FSR0 nach FSR1 Länge W (1..256 Bytes)
; VR: cnt0 = 0, W = 0
memcpy movwf cnt0
mcl moviw FSR0++
movwi FSR1++
loop cnt0,mcl
retlw 0
;Löscht RAM ab FSR0 Länge W (1..256 Bytes)
;VR: cnt0 = 0
ZeroMemory
movwf cnt0
clrw
;Füllt RAM ab FSR0 Länge cnt0 mit Byte W
;VR: cnt0 = 0
memset movwi FSR0++
loop cnt0,memset
return
;Holt DS18B20-ID je nach Index W
;PE: W = Index (0..3), BSR = egal
;PA: FSR0 = Zeiger, BSR = unverändert
;VR: W = 8, cnt0 = 0
get_id_ptr
movwf cnt0 ;retten
movlwf ds18b20id0,FSR0
movfw cnt0
brz fo3 ;nicht versetzen
lo3: addfsr FSR0,8
loop cnt0,lo3
fo3: retlw 8
; Aufruf aus webusb.i51: W = Report-ID
; BSR = 0
onEp0SetReport
xorlw 2
brz w2
xorlw 3^2
skpz
retlw -1 ;Falsche Report-ID
call usbEp0Recv
skpnc
retlw -1
;Der Report enthält nur den gewünschten DS18B20-Index, nicht die DS18B20-Seriennummern
movfw E0_BUF+1
andlw ~3
skpnz
retlw -1 ;Diesen Index mag ich nicht
movlwf rep3+1,FSR1
movfw E0_BUF+1 ;von Bank 0
movwi FSR1++ ;nach Bank 1
call get_id_ptr ;Quellzeiger berechnen
call memcpy
retlw 0
w2:
call usbEp0Recv ; warten bis OUT-Daten angekommen sind (passt stets in FIFO)
skpnc
retlw -1
;TODO: Handle Report!
retlw 0
; Aufruf aus webusb.i51: W = Report-ID
onEp0GetReport
decfsz WREG,w
bra _nr1
;TEST
banksel LATA
movlw 1<<4
xorwf LATA,f ;LED schaltet um
movlwf2 rep1,FSR0
retlw 16 ; Datenlänge liefern
_nr1 decfsz WREG,w
bra _nr2
movlwf2 rep2,FSR0
retlw 16
_nr2 decfsz WREG,w
retlw -1
movlwf2 rep3,FSR0
retlw 10
end
Detected encoding: UTF-8 | 0
|