; dtmfun.asm - tone decoder with relay control but no security code. ; reads output from an 8870 DTMF decoder and controls a bank of relays. ; Code sequences "*11#" through to "*18#" turn on the corresponding relay ; code sequence "*10#" tuns on all relays ; Code sequences "*01#" through to "*08#" turn off the corresponding relay ; Code sequence "*00#" turns off all relays ; Codes "*?9#" through "*?D#" are ignored. ; Note: This version has no security codes list p=16c84 include "p16c84.inc" __FUSES _CP_OFF & _XT_OSC & _WDT_OFF & _PWRTE_ON OPTREG equ 01 TRIS_A equ 05 TRIS_B equ 06 relays equ 10 mfcode equ 11 cntdown equ 12 timeout equ 13 slocnt1 equ 14 slocnt2 equ 15 org 0000 ;tell assembler to start at 000H init goto start org 0004 ;interrupt vector rtc_interrupt decfsz slocnt1,F ;decrement 1st prescaler goto rtc_int_1 decfsz slocnt2,F ;decrement 2nd prescaler goto rtc_int_1 bcf relays,4 ;turn relay 6 off bcf PORTB,4 rtc_int_1 decfsz cntdown,F ;count down and skip next if = 0 goto counting ;still counting if not reached zero bsf timeout,0 ;set timed out bit bcf INTCON,2 ;clear interrupt flag retfie ;return counting bcf timeout,0 ;clear timed out bit bcf INTCON,2 ;clear interrupt flag retfie ;return ; subroutines wait_strobe btfsc timeout,0 ;see if timed out goto set_z ;set Z flag if timeout ocurred btfss PORTA,4 ;see if Strobe is active on RA4 goto wait_strobe ;loop until it is movfw PORTA ;retreive the code from the 8870 movwf mfcode ;store it in mfcode bcf mfcode,4 ;ensure strobe isn't seen as data bcf STATUS,2 ;return with Z=0 if tone decoded return set_z bsf STATUS,2 ;return with Z=1 if timed out waiting return wait_no_strobe btfsc PORTA,4 ;see if strobe is active on RA4 goto wait_no_strobe ;loop until it isn't return start_timer movlw H'54' ;software prescaler for 7 seconds movwf cntdown return ; Start of setup and decode routines: start movlw B'00100000' ;select register page 1 movwf STATUS clrf TRIS_B ;set all port B pins to output mode movlw B'00011111' ;set all port A pins to input mode movwf TRIS_A movlw B'10000111' movwf OPTREG ;sets: pull-up on port B OFF ; RTCC counts internal clock ; prescaler connected to RTCC ; prescaler divides by 256 ; (other bits unimportant) clrw ;clear the working register movwf STATUS ;switch back to register page 0 clrf PORTB ;all outputs off clrf relays clrf timeout movlw B'10100000' movwf INTCON ;global and RTCC interrupts enabled decode call wait_no_strobe ;start running when no tone present clrf timeout ;set timeout condition until later call wait_strobe ;wait for a tone to be received movlw H'0B' ;0B is the code for DTMF "*" subwf mfcode,W ;set zero flag if "*" was received btfsc STATUS,2 ;skip next if it was not a "*" goto got_star goto decode ;look for another one got_star call start_timer ;start time-out timer call wait_no_strobe ;wait for third tone call wait_strobe btfsc STATUS,2 ;abort if timed out goto decode movlw H'01' subwf mfcode,W ;set zero flag if second tone was 1 btfsc STATUS,2 ;skip next if it was not a 1 goto got_1 movlw H'0A' subwf mfcode,W ;set zero flag if second tone was "0" btfsc STATUS,2 ;skip next if it was not a 0 goto got_2 goto get_# ;wait for # to end invalid sequence ; according to the next 2 tones but don't action it until a "#" is seen. got_1 call wait_no_strobe call wait_strobe ;wait for third tone btfsc STATUS,2 ;abort if timed out goto decode call wait_no_strobe ;wait for tone to finish movf mfcode,W ;pick up keyed digit addwf PCL,F ;jump ahead to vector goto decode ;5D (mf code 0000) goto got_11 goto got_12 goto got_13 goto got_14 goto got_15 goto got_16 goto got_17 goto got_18 goto decode goto got_10 goto decode ;* goto decode ;# goto decode ;5A goto decode ;5B goto decode ;5C (mf code 1111) got_10 movlw B'11111111' ;all outputs on movwf relays goto get_# got_11 bsf relays,0 ;set output 1 on goto get_# got_12 bsf relays,1 ;set output 2 on goto get_# got_13 bsf relays,3 ;set output 3 on goto get_# got_14 bsf relays,2 ;set output 4 on goto get_# got_15 bsf relays,5 ;set output 5 on goto get_# got_16 bsf relays,4 ;set output 6 on goto get_# got_17 bsf relays,6 ;set output 7 on goto get_# got_18 bsf relays,7 ;set output 8 on goto get_# ; to reach here, the tone sequence "*2" has been found, now decode request ; according to the next 2 tones but don't action it until a "#" is seen. got_2 call wait_no_strobe call wait_strobe ;wait for sixth tone btfsc STATUS,2 ;abort if timed out goto decode call wait_no_strobe ;wait for tone to finish movf mfcode,W ;pick up keyed digit addwf PCL,F ;jump ahead to vector goto decode ;5D (mf code 0000) goto got_01 goto got_02 goto got_03 goto got_04 goto got_05 goto got_06 goto got_07 goto got_08 goto decode goto got_00 goto decode ;* goto decode ;# goto decode ;5A goto decode ;5B goto decode ;5C (mf code 1111) got_00 movlw B'0000000' movwf relays ;set all outputs off goto get_# got_01 bcf relays,0 ;set output 1 off goto get_# got_02 bcf relays,1 ;set output 2 off goto get_# got_03 bcf relays,3 ;set output 3 off goto get_# got_04 bcf relays,2 ;set output 4 off goto get_# got_05 bcf relays,5 ;set output 5 Off goto get_# got_06 bcf relays,4 ;set output 6 Off goto get_# got_07 bcf relays,6 ;set output 7 Off goto get_# got_08 bcf relays,7 ;set output 8 Off goto get_# get_# call wait_strobe ;wait for 7th tone btfsc STATUS,2 ;abort if timed out goto decode movlw H'0C' ;0C is the DTMF code for "#" subwf mfcode,W ;if # received set Z flag btfsc STATUS,2 ;skip next if not a # goto got_# call wait_no_strobe goto get_# ;only # is valid, loop until found ;or timeout got_# call wait_no_strobe ;wait for the tone to finish movfw relays ;use the "relays" variable to set RB movwf PORTB goto decode ;all done, check for new sequence retlw 'v' retlw '2' retlw '.' retlw '1' retlw '.' retlw 'W' retlw 'W' retlw '2' retlw 'R' retlw ' ' retlw 'o' retlw 'c' retlw 't' retlw '2' retlw '0' retlw '0' retlw '0' end