;Simple Alarm System (Transmitter)
;Version 1.1 RC6
;(c)1997-2008
;Author: Kirill Yelizarov
; *** HOW TO MAKE ***
;1.Select desired processor in MPLAB
;2.Select IR receiver in _IR_REC
;3.Compile
;Possible processor selections:
;12C508, 12C508A, 12C509, 12C509A, 12CE518, 12CE519, 12F508, 12F509, 16F84, 16F84A
;PICs 16F84 and 16F84A are used for debug
;----------- S E L E C T --- Y O U R --- R E C E I V E R -----------
;Possible IR receiver selections:
_TBA_2800 EQU .1 ;_TBA_2800 - TBA 2800 (Micronas Intermetall GmbH http://www.intermetall.de)
_BRM_1020 EQU .2 ;_BRM_1020 - BRM-1020 (Bright LED Electronics Corp. http://www.brtled.com)
_TSOP_1738 EQU .3 ;_TSOP_1738 - TSOP-1738 (Vishay SemiconductorsGmbH http://www.vishay.com)
_TSOP_2156 EQU .4 ;_TSOP_2156 - TSOP-2156 (Vishay SemiconductorsGmbH http://www.vishay.com)
;
_IR_REC EQU _TBA_2800 ;IR receiver selection
;-------------------------------------------------------------------
;Debug
_DEBUG EQU .0 ;no debug, normal operation
;Debug levels for 16F84 and 16F84A only
;Some pins are used another way in debug mode
;Check code before using this option
;_DEBUG EQU .1 ;output single pulse for receiver calibration
;Processors
_12C508 EQU .1
_12C508A EQU .2
_12C509 EQU .3
_12C509A EQU .4
_12CE518 EQU .5
_12CE519 EQU .6
_16F84 EQU .7
_16F84A EQU .8
_12F508 EQU .9
_12F509 EQU .10
IFDEF __12C508
LIST P=PIC12C508
INCLUDE p12c508.inc
_PIC_CPU equ _12C508
_PIC_MEM equ 0x0a
ENDIF
IFDEF __12C508A
LIST P=PIC12C508A
INCLUDE p12c508a.inc
_PIC_CPU equ _12C508A
_PIC_MEM equ 0x0a
ENDIF
IFDEF __12C509
LIST P=PIC12C509
INCLUDE p12c509.inc
_PIC_CPU equ _12C509
_PIC_MEM equ 0x0a
ENDIF
IFDEF __12C509A
LIST P=PIC12C509A
INCLUDE p12c509a.inc
_PIC_CPU equ _12C509A
_PIC_MEM equ 0x0a
ENDIF
IFDEF __12CE518
LIST P=PIC12CE518
INCLUDE p12ce518.inc
_PIC_CPU equ _12CE518
_PIC_MEM equ 0x0a
ENDIF
IFDEF __12CE519
LIST P=PIC12CE519
INCLUDE p12ce519.inc
_PIC_CPU equ _12CE519
_PIC_MEM equ 0x0a
ENDIF
IFDEF __12F508
LIST P=PIC12F508
INCLUDE p12f508.inc
_PIC_CPU equ _12F508
_PIC_MEM equ 0x0a
ENDIF
IFDEF __12F509
LIST P=PIC12F509
INCLUDE p12f509.inc
_PIC_CPU equ _12F509
_PIC_MEM equ 0x0a
ENDIF
IFDEF __16F84
LIST P=PIC16F84
INCLUDE p16f84.inc
_PIC_CPU equ _16F84
_PIC_MEM equ 0x0c
ENDIF
IFDEF __16F84A
LIST P=PIC16F84A
INCLUDE p16f84a.inc
_PIC_CPU equ _16F84A
_PIC_MEM equ 0x0c
ENDIF
IFDEF _PIC_CPU
IFDEF _IR_REC
IF (_PIC_CPU==_12C508)||(_PIC_CPU==_12C508A)||(_PIC_CPU==_12C509)||(_PIC_CPU==_12C509A)||(_PIC_CPU==_12CE518)||(_PIC_CPU==_12CE519)||(_PIC_CPU==_12F508)||(_PIC_CPU==_12F509)
__CONFIG _IntRC_OSC & _WDT_OFF & _CP_OFF & _MCLRE_OFF
ENDIF
IF (_PIC_CPU==_16F84)||(_PIC_CPU==_16F84A)
__CONFIG _XT_OSC & _WDT_OFF & _CP_OFF & _PWRTE_OFF
ENDIF
INCLUDE "password.inc"
IF (_PIC_CPU==_12C508)||(_PIC_CPU==_12C508A)||(_PIC_CPU==_12C509)||(_PIC_CPU==_12C509A)||(_PIC_CPU==_12CE518)||(_PIC_CPU==_12CE519)||(_PIC_CPU==_12F508)||(_PIC_CPU==_12F509)
#define TESTBAT GPIO,0
#define IRLED GPIO,2 ;Infra Red LED pin
#define BATCHK GPIO,4
#define LED GPIO,5
#define BUTTONS GPIO
ENDIF
IF (_PIC_CPU==_16F84)||(_PIC_CPU==_16F84A)
#define IRLED PORTA,0 ;Infra Red LED pin
#define BATCHK PORTA,2
#define TESTBAT PORTA,3
#define LED PORTA,4
#define BUTTONS PORTB
ENDIF
;----- SFRs -----
CBLOCK _PIC_MEM
Counter
DelayCountLow
DelayCountHi
Com ;Command
Dig1 ;64 bit Password
Dig2
Dig3
Dig4
Dig5
Dig6
Dig7
Dig8
Dig9 ;command and CRC
ENDC
;----- CODE -----
org 0x00
goto Start
org 0x04
goto Start
org 0x40
Start:
clrf STATUS
IF (_PIC_CPU==_12C508)||(_PIC_CPU==_12C508A)||(_PIC_CPU==_12C509)||(_PIC_CPU==_12C509A)||(_PIC_CPU==_12CE518)||(_PIC_CPU==_12CE519)||(_PIC_CPU==_12F508)||(_PIC_CPU==_12F509)
movlw b'00000000' ;Enable weak pull-up on GP0, GP1 and GP3
option ;and wake up on pin change
movlw b'00011010' ;Set GP0,GP2,GP5 as output and the rest are inputs
tris BUTTONS
ENDIF
IF (_PIC_CPU==_16F84)||(_PIC_CPU==_16F84A)
movlw b'10000000'
movwf INTCON ;enable global interrupts
movlw b'00001000' ;Enable weak pull-up on PortB
bsf STATUS,RP0 ;select bank1
movwf OPTION_REG
movlw b'11100110'
movwf TRISA
movlw b'11111111'
movwf TRISB
bcf STATUS,RP0 ;select bank0
ENDIF
bsf LED
bcf IRLED
bcf TESTBAT
goto Transmit
;Delay for timing intervals
;Delay = W*3-1+5 us with 4MHz oscillator
Delay
movwf DelayCountLow
DelayStart:
decfsz DelayCountLow,F
goto DelayStart
retlw 0x00
;Delay for key de bounce
;Delay = W ms with 4 MHz oscillator
LongDelay
movwf DelayCountHi
clrf DelayCountLow
DelayLoop:
nop
incfsz DelayCountLow,F
goto DelayLoop
decfsz DelayCountHi,F
goto DelayLoop
retlw 0x00
Transmit:
IF (_DEBUG==.1)&&((_PIC_CPU==_16F84)||(_PIC_CPU==_16F84A))
goto _debug1_Next
ENDIF
comf BUTTONS,W ;read and invert BUTTONS contents
IF (_PIC_CPU==_12C508)||(_PIC_CPU==_12C508A)||(_PIC_CPU==_12C509)||(_PIC_CPU==_12C509A)||(_PIC_CPU==_12CE518)||(_PIC_CPU==_12CE519)||(_PIC_CPU==_12F508)||(_PIC_CPU==_12F509)
andlw b'00001010'
ENDIF
IF (_PIC_CPU==_16F84)||(_PIC_CPU==_16F84A)
andlw b'11110000'
ENDIF
btfsc STATUS,Z ;check if a button is pressed
goto _Sleep ;if not go to sleep
movwf Com ;assign command
movlw 0x1e
call LongDelay ;wait for 30 ms
comf BUTTONS,W ;read and invert BUTTONS again
IF (_PIC_CPU==_12C508)||(_PIC_CPU==_12C508A)||(_PIC_CPU==_12C509)||(_PIC_CPU==_12C509A)||(_PIC_CPU==_12CE518)||(_PIC_CPU==_12CE519)||(_PIC_CPU==_12F508)||(_PIC_CPU==_12F509)
andlw b'00001010'
ENDIF
IF (_PIC_CPU==_16F84)||(_PIC_CPU==_16F84A)
andlw b'11110000'
ENDIF
btfsc STATUS,Z ;check if a button is still pressed
goto _Sleep ;if not go to sleep
xorwf Com,W ;Is a button is still pressed and it is the same command
btfss STATUS,Z
goto _Sleep ;if not go to sleep
IF (_PIC_CPU==_12C508)||(_PIC_CPU==_12C508A)||(_PIC_CPU==_12C509)||(_PIC_CPU==_12C509A)||(_PIC_CPU==_12CE518)||(_PIC_CPU==_12CE519)||(_PIC_CPU==_12F508)||(_PIC_CPU==_12F509)
swapf Com,F ;place command in higher nibble
ENDIF
;Battery tester (low voltage flag set at 3,5V or less)
bsf TESTBAT ;activate battery tester
movlw .12
call Delay ;delay 12*3-1+5=40 us
btfss BATCHK ;check battery
bsf Com,4 ;set battery weak bit
bcf TESTBAT ;turn off battery tester
bcf LED
;Calculate CRC
movlw PASS1
movwf Dig1
movlw PASS2
movwf Dig2
movlw PASS3
movwf Dig3
movlw PASS4
movwf Dig4
movlw PASS5
movwf Dig5
movlw PASS6
movwf Dig6
movlw PASS7
movwf Dig7
movlw PASS8
movwf Dig8
movf Com,W
movwf Dig9
movlw .72
movwf Counter
movlw b'00110000' ;set poly (4bit CRC poly=10011)
NextBit:
bcf STATUS,C
rlf Dig9,F
rlf Dig8,F
rlf Dig7,F
rlf Dig6,F
rlf Dig5,F
rlf Dig4,F
rlf Dig3,F
rlf Dig2,F
rlf Dig1,F
btfsc STATUS,C
xorwf Dig1,F
decfsz Counter,F
goto NextBit
swapf Dig1,W
iorwf Com,W
movwf Dig9 ;add command nibble to CRC nibble
movlw PASS1
movwf Dig1
movlw PASS2
movwf Dig2
movlw PASS3
movwf Dig3
movlw PASS4
movwf Dig4
movlw PASS5
movwf Dig5
movlw PASS6
movwf Dig6
movlw PASS7
movwf Dig7
movlw PASS8
movwf Dig8
movlw .72
movwf Counter ;72 bits transmission
IF (_DEBUG==.1)&&((_PIC_CPU==_16F84)||(_PIC_CPU==_16F84A))
_debug1_Next:
ENDIF
;send start pulse ***************************
IF _IR_REC==_TBA_2800 ;No carrier. TTY mode. Pulse 30us. 1 pulse in a bit.
bsf IRLED
movlw .7
call Delay ;delay 8*3-1+5=28 us
bcf IRLED
nop
movlw .74
call Delay ;delay 74*3-1+5=226
ENDIF
IF _IR_REC==_BRM_1020 ;Carrier 38kHz (26us). NEC mode. Pulse 7us. 7 pulses in a bit.
VARIABLE i
i=0
WHILE i < .7
bsf IRLED
nop
nop
nop
nop
nop
nop
bcf IRLED
nop
movlw .4
call Delay ;delay 4*3-1+5=16 us
i = i+1
ENDW
movlw .23
call Delay ;delay 23*3-1+5=73
ENDIF
IF _IR_REC==_TSOP_1738 ;Carrier 38kHz (26us). NEC mode. Pulse 7us. 8 pulses in a bit.
VARIABLE i
i=0
WHILE i < .8
bsf IRLED
nop
nop
nop
nop
nop
nop
bcf IRLED
nop
movlw .4
call Delay ;delay 4*3-1+5=16 us
i = i+.1
ENDW
nop
movlw .14
call Delay ;delay 14*3-1+5=46
ENDIF
IF _IR_REC==_TSOP_2156 ;Carrier 56kHz (18us). NEC mode. Pulse 5us. 7 pulses in a bit.
VARIABLE i
i=0
WHILE i < .7
bsf IRLED
nop
nop
nop
nop
bcf IRLED
nop
nop
movlw .2
call Delay ;delay 2*3-1+5=10 us
i = i+.1
ENDW
nop
movlw .39
call Delay ;delay 39*3-1+5=113
ENDIF
nop
movlw .254
call Delay ;delay 82*3-1+5=766 us
IF (_DEBUG==.1)&&((_PIC_CPU==_16F84)||(_PIC_CPU==_16F84A))
movlw 0xff
call LongDelay ;wait for 255 ms
goto _debug1_Next
ENDIF
NextDig:
;send next pulse *********************************************
IF _IR_REC==_TBA_2800 ;No carrier. TTY mode. Pulse 30us. 1 pulse in a bit.
bsf IRLED
movlw .7
call Delay ;delay 8*3-1+5=28 us
bcf IRLED
nop
movlw .74
call Delay ;delay 74*3-1+5=226
ENDIF
IF _IR_REC==_BRM_1020 ;Carrier 38kHz (26us). NEC mode. Pulse 7us. 7 pulses in a bit.
VARIABLE i
i=0
WHILE i < .7
bsf IRLED
nop
nop
nop
nop
nop
nop
bcf IRLED
nop
movlw .4
call Delay ;delay 4*3-1+5=16 us
i = i+1
ENDW
movlw .23
call Delay ;delay 23*3-1+5=73
ENDIF
IF _IR_REC==_TSOP_1738 ;Carrier 38kHz (26us). NEC mode. Pulse 7us. 8 pulses in a bit.
VARIABLE i
i=0
WHILE i < .8
bsf IRLED
nop
nop
nop
nop
nop
nop
bcf IRLED
nop
movlw .4
call Delay ;delay 4*3-1+5=16 us
i = i+.1
ENDW
nop
movlw .14
call Delay ;delay 14*3-1+5=46
ENDIF
IF _IR_REC==_TSOP_2156 ;Carrier 56kHz (18us). NEC mode. Pulse 5us. 7 pulses in a bit.
VARIABLE i
i=0
WHILE i < .7
bsf IRLED
nop
nop
nop
nop
bcf IRLED
nop
nop
movlw .2
call Delay ;delay 2*3-1+5=10 us
i = i+.1
ENDW
nop
movlw .39
call Delay ;delay 39*3-1+5=113
ENDIF
bcf STATUS,C
rlf Dig9,F
rlf Dig8,F
rlf Dig7,F
rlf Dig6,F
rlf Dig5,F
rlf Dig4,F
rlf Dig3,F
rlf Dig2,F ;rotate 64 bits to get the next bit
rlf Dig1,F ;to transmit and place it into STATUS,C
btfss STATUS,C ;if STATUS,C is low
goto Send0 ;then delay between bits is 256 us else delay is 512 us
movlw .84
call Delay ;delay 84*3-1+5=256 us
Send0:
nop
movlw .78
call Delay ;delay 78*3-1+5=238 us
decfsz Counter,F ;last bit is not reached
goto NextDig ;proceed to next bit
nop
;send last pulse ***********************************************
IF _IR_REC==_TBA_2800 ;No carrier. TTY mode. Pulse 30us. 1 pulse in a bit.
bsf IRLED
movlw .7
call Delay ;delay 8*3-1+5=28 us
bcf IRLED
nop
movlw .74
call Delay ;delay 74*3-1+5=226
ENDIF
IF _IR_REC==_BRM_1020 ;Carrier 38kHz (26us). NEC mode. Pulse 7us. 7 pulses in a bit.
VARIABLE i
i=0
WHILE i < .7
bsf IRLED
nop
nop
nop
nop
nop
nop
bcf IRLED
nop
movlw .4
call Delay ;delay 4*3-1+5=16 us
i = i+1
ENDW
movlw .23
call Delay ;delay 23*3-1+5=73
ENDIF
IF _IR_REC==_TSOP_1738 ;Carrier 38kHz (26us). NEC mode. Pulse 7us. 8 pulses in a bit.
VARIABLE i
i=0
WHILE i < .8
bsf IRLED
nop
nop
nop
nop
nop
nop
bcf IRLED
nop
movlw .4
call Delay ;delay 4*3-1+5=16 us
i = i+.1
ENDW
nop
movlw .14
call Delay ;delay 14*3-1+5=46
ENDIF
IF _IR_REC==_TSOP_2156 ;Carrier 56kHz (18us). NEC mode. Pulse 5us. 7 pulses in a bit.
VARIABLE i
i=0
WHILE i < .7
bsf IRLED
nop
nop
nop
nop
bcf IRLED
nop
nop
movlw .2
call Delay ;delay 2*3-1+5=10 us
i = i+.1
ENDW
nop
movlw .39
call Delay ;delay 39*3-1+5=113
ENDIF
bsf LED
_Sleep:
IF (_PIC_CPU==_16F84)||(_PIC_CPU==_16F84A)
movf BUTTONS,W ;read PORTB to clear interrupt condition
movlw b'10001000'
movwf INTCON ;enable global interrupts and RB port change and flags
ENDIF
sleep ;go to sleep
goto _Sleep
IF (_PIC_CPU==_12C508)||(_PIC_CPU==_12C508A)||(_PIC_CPU==_12CE518)||(_PIC_CPU==_12F508)
org 0x1ff
movlw b'01110000' ;set OSCCAL
ENDIF
IF (_PIC_CPU==_12C509)||(_PIC_CPU==_12C509A)||(_PIC_CPU==_12CE519)||(_PIC_CPU==_12F509)
org 0x3ff
movlw b'01110000' ;set OSCCAL
ENDIF
ELSE
Error "IR Receiver not selected. Check code"
ENDIF
ELSE
Error "Wrong PIC selected. Select [Configure]->[Select Device...]"
ENDIF
end