;**********************************************************************
; Filename: Walkie talkie alarm.asm *
; Date: 08.4.12 *
; File Version: *
; Author: Steve *
; PIC: 12F675 *
;**********************************************************************
; PINOUT: *
; 1, +5V *
; 2, TTL output to walkie talkie (GP5) *
; 3, Analog in from sensor (AN3)(GP4) *
; 4, MCLR - was GP3 MUST BE PULLED UP -poxy ICD3 won't let you use it *
; 5, GP3 (unused) *
; 6, Analog in from sensor (AN1)(GP1) *
; 7, Analog in from sensor (AN0)(GP0) *
; 8, GND *
;**********************************************************************
list p=12f675 ; list directive to define processor
#include <P12F675.inc> ; processor specific variable definitions
; errorlevel -302 ; suppress message 302 from list file
__CONFIG _CP_OFF & _CPD_OFF & _BODEN_OFF & _MCLRE_ON & _WDT_OFF & _PWRTE_ON & _INTRC_OSC_NOCLKOUT
;***** VARIABLE DEFINITIONS
#define poswindow d'10'
one_mS_loop EQU 0x21
n_mS_loop EQU 0x22
flags EQU 0x25
counter EQU 0x26
temp EQU 0x28
max_A EQU 0x2A
max_B EQU 0x2B
max_C EQU 0x2C
;**********************************************************************
ORG 0x000 ; processor reset vector
goto Init ; go to beginning of program
;****************************************************************
Init:
bsf STATUS,RP0 ; set file register bank to 1
movlw B'111111' ; IP 0,1,2,3,4,5
movwf TRISIO ;
call 0x3FF ; retrieve factory calibration value
movwf OSCCAL ; update register with factory cal value
movlw B'00001111' ; Pulups on,n/a,internal clock,n/a,WDT has prescaler,/128
movwf OPTION_REG ;
clrf INTCON ;interupts off
movlw b'1000000'
movwf PIE1 ;Perif interupts off - Just EEdone interupt on
clrf VRCON ;Vref Off (power off the comparator voltage, saves power)
clrf WPU ;
movlw B'00000111' ; n/a...,comparitor off
movwf CMCON
movlw B'01011011' ;n/a,clock/8,GPIO 3,1,0 analog
movwf ANSEL
bcf STATUS,RP0 ; set file register bank to 0
movlw B'00000001' ;left justified ADC OP, ref vdd, Ch0 selected.
movwf ADCON0
clrf GPIO ;Clear Port
movlw 0x07
movwf CMCON ;Comparator Off
movlw .250 ;300ms
call the_wait
movlw .150 ;300ms
call the_wait
movlw .150 ;300ms
call the_wait
movlw .150 ;300ms
call the_wait ;just a power up delay to let sensors settle down
call set_thresholds ;get stored values from EEPROM
;*******************************************************************
; MAIN
;*******************************************************************
main:
btfsc GPIO,2 ;learn button pressed?
goto learn_mode
CH0:
bcf ADCON0,2
bcf ADCON0,3 ;ch0
movlw 2
call the_wait ;let input settle
bsf ADCON0,1 ;start ADC conversion
btfsc ADCON0,1 ;done yet?
goto $-1 ; no - jump back a line
movfw max_A ;get threshold value
subwf ADRESH,W ;check if value greater than max
btfsc STATUS,C ;if subtraction result was less than 0...
bsf flags,0 ;set a flag to say alarm should be triggered
CH1:
bsf ADCON0,2
bcf ADCON0,3 ;ch1
movlw 2
call the_wait
bsf ADCON0,1
btfsc ADCON0,1
goto $-1
movfw max_B
subwf ADRESH,W ;check if value greater than max
btfsc STATUS,C
bsf flags,0
CH3:
bsf ADCON0,2
bsf ADCON0,3 ;ch3
movlw 2
call the_wait
bsf ADCON0,1
btfsc ADCON0,1
goto $-1
movfw max_C
subwf ADRESH,W ;check if value greater than max
btfsc STATUS,C
bsf flags,0
btfss flags,0 ;will add de-bouncing here in due course
goto main
alarm:
clrf GPIO
nop ;make sure that the output will be low when enabled
bsf STATUS,RP0 ; set file register bank to 1
movlw B'011111' ; IO5 is output
movwf TRISIO ; i.e. press the call button on the walkie talkie
bcf STATUS,RP0
movlw .250 ;250ms
call the_wait
movlw .250 ;250ms
call the_wait
movlw .250 ;250ms
call the_wait
movlw .250 ;250ms
call the_wait
bsf STATUS,RP0 ; set file register bank to 1
movlw B'111111' ; IO5 is input
movwf TRISIO ; i.e release the call button on the walkie talkie
bcf STATUS,RP0
call the_wait
movlw .250 ;250ms
goto main
the_wait:
movwf n_mS_loop ;simple delay looks at W and delays W uS
mid_wait_loop:
movlw b'11111001'
movwf one_mS_loop
inner_wait_loop:
nop
decfsz one_mS_loop,f
goto inner_wait_loop
decfsz n_mS_loop,f
goto mid_wait_loop
return
learn_mode:
movlw .20
call the_wait
bcf ADCON0,2
bcf ADCON0,3 ;Select ch0
movlw 2
call the_wait
bsf ADCON0,1 ;get an ADC reading
btfsc ADCON0,1
goto $-1
movf ADRESH,W ;stick it in W
bsf STATUS,RP0
movwf EEDATA ;put it ready to write to EEPROM
movlw d'00'
movwf EEADR ;in address 00
call WriteEEPROM ;call routine to write to EEPROM
movlw .20
call the_wait
bsf ADCON0,2
bcf ADCON0,3 ;ch1
movlw 2
call the_wait
bsf ADCON0,1
btfsc ADCON0,1
goto $-1
movf ADRESH,W
bsf STATUS,RP0
movwf EEDATA
movlw d'01'
movwf EEADR
call WriteEEPROM
movlw .20
call the_wait
bsf ADCON0,2
bsf ADCON0,3 ;ch3
movlw 2
call the_wait
bsf ADCON0,1
btfsc ADCON0,1
goto $-1
movf ADRESH,W
bsf STATUS,RP0
movwf EEDATA
movlw d'02'
movwf EEADR
call WriteEEPROM
movlw .40
call the_wait
movlw .240
call the_wait
goto Init ;all done, restart again
set_thresholds:
;A nominal in 00, B nominal in 01
bsf STATUS,RP0
movlw d'00'
movwf EEADR ;EEPROM address 00
call ReadEEPROM ;read the stored value
movwf temp
addlw poswindow ;add safety margin set at top of this code
movwf max_A ;store as threshold for channel A (channel 0)
movlw d'01'
movwf EEADR
call ReadEEPROM
movwf temp
addlw poswindow
movwf max_B
movlw d'02'
movwf EEADR
call ReadEEPROM
movwf temp
addlw poswindow
movwf max_C
return
ReadEEPROM: ;EEADR has address, data goes into W
bsf STATUS,RP0
wait_read:
btfsc EECON1,WR ; wait for end of previous write
goto wait_read
movwf EEADR ; select address
bsf EECON1,RD ; initiate READ
movf EEDATA,W ; transfer Byte to W
bcf STATUS,RP0
return
WriteEEPROM: ;EEDATA is data, EEADR is address
bsf STATUS,RP0
wait_write:
btfsc EECON1,WR ; wait for end of previous write
goto wait_write
bsf EECON1,WREN
movlw 0x55
movwf EECON2 ; Write 55h
movlw 0xAA
movwf EECON2 ; Write AAh
bsf EECON1,WR ; Set WR bit
bcf EECON1,WREN
bcf STATUS,RP0
return
;any comments h.ps.steve@gmail.com
end