📄 dtmf.asm
字号:
;**********************************************************
; Main Program
;**********************************************************
START
call init_disp
call cur_h1
STARTPLUS
; INIT PORTB OUTPUTS FROM EEPROM
MOVLW LOW OUT0
CALL EE_READ_BYTE
ANDLW 0X0F ; MASK THE LOW 4 BITS
MOVWF PORTB ; SET OUTPUTS
Bank1
MOVLW 0XF0
MOVWF TRISB ; PORT B 0-3 OUTPUTS
Bank0
BCF TIMEOUT ; KEEP THE TIMEOUT STOPPED
BCF BEEP ; SILENCE...
CLRF TIME0 ; INIT TIMEOUT COUNTER
CLRF TIME1
CLRF TIME2
BSF DONE ; DO NOT START DTMF DETECTOR....
; INIT ROUTINE
INIT
clrf PORTC ; CLEAR PORTC
movlw B'11110011' ;port C0=Input for now/out, C1=INPUT, C2,3 OUT
BANKSEL TRISC
movwf TRISC
BANKSEL T2CON
MOVLW B'00001100' ; X,1/2 postscale, timer 2 ON ~9.6khz sample rate
MOVWF T2CON
BANKSEL PR2
MOVLW 0XFF ; TIMER 2 PERIOD REGISTER
MOVWF PR2
BANKSEL PIR1
BCF PIR1,TMR2IF ; CLEAR TIMER 2 INT FLAG
BANKSEL PIE1
BSF PIE1,TMR2IE ; START INT FOR TIMER 2
BANKSEL INTCON
BSF INTCON,PEIE ; START PERIPHERAL INT
BSF INTCON,GIE ; START GLOBAL INT
BANKSEL CCP1CON
MOVLW B'00001100'
MOVWF CCP1CON ;PWM 1 ON
BANKSEL TRISC
BCF TRISC,2 ; RC2 = PWM 1 OUT
BANKSEL CCPR1L
MOVLW .128
MOVWF CCPR1L ; 50 DUTY CYCLE ~18KHZ
CLRF TEMP_VAL
CLRF TEMP_TIMES
CLRF COUNT ; NR CHAR FOR DISPLAY
CALL TESTPASS ; PRINT PASS
; TO STOP DTMF DETECTOR - BSF DONE
; TO START DTMF DETECTOR - CALL START_DTMF
CALL BEEPOK
CALL BEEPERR
;*********************************
; MAIN LOOP
;*********************************
; FIRSRT READ #PASS#, WHERE PASS HAS 10 DIGITS
MAINDTMF:
CALL START_DTMF
CALL CLRTIMEOUT
MAIN0:
BTFSC TIMEOUT
GOTO TIMEO1 ; TIMEOUT ERROR, NO SOUND, HANG UP LINE
; FIRST WAIT A DIGIT
BTFSS DONE
GOTO MAIN0
; WE GOT A DIGIT, COMPARE WITH #
MOVLW '#' ; WAIT #
XORWF RESULT1,W
BTFSS STATUS,Z
GOTO MAINDTMF ; DIGIT<>#, TRY AGAIN
; debug
call cur_h1
movf RESULT1,w
call send_c
; end debug
BSF PORTC,3 ; BEEP ON
CALL START_DTMF ; GET A NEW DIGIT
CALL CLRTIMEOUT ; START TIMEUOT
MOVLW LOW PSS0 ; POINTER RAM
MOVWF FSR
MOVLW .10 ; 10 DIGIT PASS
MOVWF EE_Byte ; COUNTER
MAIN1:
BTFSC TIMEOUT
GOTO TIMEO ; TIMEOUT ERROR, RESTART
; WAIT A DIGIT
BTFSS DONE
GOTO MAIN1
MOVF RESULT1,W
MOVWF INDF ; PUT DIGIT IN PSS0-9, RAM
;debug
call send_c
;end debug
DECF EE_Byte,F
BTFSC STATUS,Z
GOTO MAIN21 ; GOT 10 DIGITS
INCF FSR,F
CALL START_DTMF
CALL CLRTIMEOUT
GOTO MAIN1 ; WAIT FOR DIGIT 1..9
MAIN21:
CALL START_DTMF
CALL CLRTIMEOUT
MAIN2: ; WAIT #
BTFSC TIMEOUT
GOTO TIMEO ; TIMEOUT ERROR, RESTART
; WAIT A DIGIT
BTFSS DONE
GOTO MAIN2
MOVLW '#' ; COMPARE #
XORWF RESULT1,W
BTFSS STATUS,Z
GOTO MAINDTMF ; DIGIT<>#, RESTART
;debug
movf RESULT1,w
call send_c
;end debug
; COMPARE PASSWORD
MOVLW LOW PASS0
MOVWF EE_Byte ; EE_BYTE POINER EEPROM
MOVLW LOW PSS0
MOVWF FSR ; FSR POINER RAM
MOVLW .10
MOVWF scrA ; SCRA COUNTER
MAIN5:
MOVF EE_Byte,W ; W= EEPROM DIGIT
CALL EE_READ_BYTE
XORWF INDF,W
BTFSC STATUS,Z
GOTO MAIN3
; PASS BAD
CALL BEEPERR
GOTO MAINDTMF ; RESTART, PASSWORD BAD
MAIN3:
DECF scrA,F
BTFSC STATUS,Z
GOTO MAIN4 ; PASS OK, CONTINUE
INCF EE_Byte,F ; NEXT DIGIT
INCF FSR,F
GOTO MAIN5
MAIN4:
;CALL BEEPOK ; PASS OK
; READ 3 DIGITS IN PSS 0,1,2
CALL START_DTMF ; GET A NEW DIGIT
CALL CLRTIMEOUT ; START TIMEUOT
MOVLW LOW PSS0 ; POINTER RAM
MOVWF FSR
MOVLW .3 ; READ ONLY 3 DIGITS
MOVWF EE_Byte ; COUNTER
MAIN6:
BTFSC TIMEOUT
GOTO TIMEO ; TIMEOUT ERROR, RESTART
; WAIT A DIGIT
BTFSS DONE
GOTO MAIN6
MOVF RESULT1,W
MOVWF INDF ; PUT DIGIT IN PSS0-9, RAM
;debug
call send_c
;end debug
DECF EE_Byte,F
BTFSC STATUS,Z
GOTO MAIN7 ; GOT 10 DIGITS
INCF FSR,F
CALL START_DTMF
CALL CLRTIMEOUT
GOTO MAIN6 ; WAIT FOR DIGIT 1..9
MAIN7: ; GOT 3 DIGITS
; IF PSS 1,2 = ## THEN #PASS#1-4## = VERIFY
MOVLW '#'
XORWF PSS1,W
BTFSS STATUS,Z
GOTO NOVERIFY
MOVLW '#'
XORWF PSS2,W
BTFSS STATUS,Z
GOTO NOVERIFY
VERIFY: ; VERIFY COMMAND
;**********************************************************************
; CHECK PSS0 FOR 1-4 --> 31,32,33,34
MOVLW '1'
XORWF PSS0,W
BTFSC STATUS,Z
GOTO VERIFY1
MOVLW '2'
XORWF PSS0,W
BTFSC STATUS,Z
GOTO VERIFY1
MOVLW '3'
XORWF PSS0,W
BTFSC STATUS,Z
GOTO VERIFY1
MOVLW '4'
XORWF PSS0,W
BTFSC STATUS,Z
GOTO VERIFY1
GOTO TIMEO
VERIFY1: ; EXECUTE VERIFY COMMAND
MOVLW .1
MOVWF PSS1 ; PSS1 TEMP
MOVLW '0'
SUBWF PSS0, F ;SUBSTRACT PSS0-W = 0-3
VERIFY2:
DECF PSS0, F
BTFSC STATUS,Z
GOTO VERIFY3 ; READY
BCF STATUS,C
RLF PSS1,F
GOTO VERIFY2
VERIFY3:
MOVLW LOW OUT0
CALL EE_READ_BYTE ; RETRIEVE VALUES FROM EEPROM
ANDWF PSS1,W ; AND MASK
BTFSC STATUS,Z
GOTO VERIFYOFF
VERIFYON:
CALL BEEPOK ; OUTPUT = 1
GOTO MAINDTMF
VERIFYOFF:
CALL BEEPERR
GOTO MAINDTMF
NOVERIFY:
; GET PSS3,4
CALL START_DTMF ; GET A NEW DIGIT
CALL CLRTIMEOUT ; START TIMEUOT
MOVLW LOW PSS3 ; POINTER RAM
MOVWF FSR
MOVLW .2 ; READ ONLY 2 DIGITS
MOVWF EE_Byte ; COUNTER
MAIN8:
BTFSC TIMEOUT
GOTO TIMEO ; TIMEOUT ERROR, RESTART
; WAIT A DIGIT
BTFSS DONE
GOTO MAIN8
MOVF RESULT1,W
MOVWF INDF ; PUT DIGIT IN PSS0-9, RAM
;debug
call send_c
;end debug
DECF EE_Byte,F
BTFSC STATUS,Z
GOTO MAIN9 ; GOT 10 DIGITS
INCF FSR,F
CALL START_DTMF
CALL CLRTIMEOUT
GOTO MAIN8 ; WAIT FOR DIGIT 1..9
MAIN9: ; GOT PSS3,4
; IF PSS 3,4 = ## THEN #PASS#1-4#0-1## = SET
MOVLW '#'
XORWF PSS3,W
BTFSS STATUS,Z
GOTO NOSET
MOVLW '#'
XORWF PSS4,W
BTFSS STATUS,Z
GOTO NOSET
XSET: ; SET COMMAND
;**********************************************************************
; CHECK PSS1 FOR #
MOVLW '#'
XORWF PSS1,W
BTFSS STATUS,Z
GOTO TIMEO
; CHECK PSS0 FOR 1-4 --> 31,32,33,34
MOVLW '1'
XORWF PSS0,W
BTFSC STATUS,Z
GOTO XSET1
MOVLW '2'
XORWF PSS0,W
BTFSC STATUS,Z
GOTO XSET1
MOVLW '3'
XORWF PSS0,W
BTFSC STATUS,Z
GOTO XSET1
MOVLW '4'
XORWF PSS0,W
BTFSC STATUS,Z
GOTO XSET1
GOTO TIMEO
XSET1:
; CHECK PSS2 FOR 0-1 --> 30,31
MOVLW '0'
XORWF PSS2,W
BTFSC STATUS,Z
GOTO XSET2
MOVLW '1'
XORWF PSS2,W
BTFSC STATUS,Z
GOTO XSET2
GOTO TIMEO
XSET2: ; EXECUTE SET COMMAND
MOVLW .1
MOVWF PSS1 ; PSS1 TEMP
MOVLW '0'
SUBWF PSS0, F ;SUBSTRACT PSS0-W = 0-3
SET2:
DECF PSS0, F
BTFSC STATUS,Z
GOTO SET1 ; READY
BCF STATUS,C
RLF PSS1,F
GOTO SET2
SET1: ; PSS1 HAS THE DESIERED BIT SET
MOVLW '0'
SUBWF PSS2, F ;SUBSTRACT PSS2-W = 0-1
BTFSC STATUS,Z
GOTO SETRESET
SETSET:
MOVLW LOW OUT0
CALL EE_READ_BYTE ; RETRIEVE VALUES FROM EEPROM
IORWF PSS1,W ; OR MASK
MOVWF PORTB ; OUTPUT THE NEW VALUE
MOVWF EE_Byte
MOVLW LOW OUT0
CALL EE_WRITE_BYTE ; WRITE THE NEW VALUE TO EEPROM
CALL BEEPOK ; BEEP HAPPY...
GOTO MAINDTMF ; RESTART
SETRESET:
COMF PSS1,F ; COMPLEMENT MASK
MOVLW LOW OUT0
CALL EE_READ_BYTE ; RETRIEVE VALUES FROM EEPROM
ANDWF PSS1,W ; OR MASK
MOVWF PORTB ; OUTPUT THE NEW VALUE
MOVWF EE_Byte
MOVLW LOW OUT0
CALL EE_WRITE_BYTE ; WRITE THE NEW VALUE TO EEPROM
CALL BEEPOK ; BEEP HAPPY...
GOTO MAINDTMF ; RESTART
NOSET:
; CHECK FOR PASS CHANGE
; GET PSS5,10
CALL START_DTMF ; GET A NEW DIGIT
CALL CLRTIMEOUT ; START TIMEUOT
MOVLW LOW PSS5 ; POINTER RAM
MOVWF FSR
MOVLW .5 ; READ ONLY 5 DIGITS
MOVWF EE_Byte ; COUNTER
MAIN10:
BTFSC TIMEOUT
GOTO TIMEO ; TIMEOUT ERROR, RESTART
; WAIT A DIGIT
BTFSS DONE
GOTO MAIN10
MOVF RESULT1,W
MOVWF INDF ; PUT DIGIT IN PSS0-9, RAM
;debug
call send_c
;end debug
DECF EE_Byte,F
BTFSC STATUS,Z
GOTO MAIN11 ; GOT 10 DIGITS
INCF FSR,F
CALL START_DTMF
CALL CLRTIMEOUT
GOTO MAIN10 ; WAIT FOR DIGIT 1..9
MAIN11:
; WAIT FOR #
CALL START_DTMF
CALL CLRTIMEOUT
MAIN12: ; WAIT #
BTFSC TIMEOUT
GOTO TIMEO ; TIMEOUT ERROR, RESTART
; WAIT A DIGIT
BTFSS DONE
GOTO MAIN12
MOVLW '#' ; COMPARE #
XORWF RESULT1,W
BTFSS STATUS,Z
GOTO MAINDTMF ; DIGIT<>#, RESTART
; GET 10 DIGITS IN DIG_10...DIG1
CALL START_DTMF ; GET A NEW DIGIT
CALL CLRTIMEOUT ; START TIMEUOT
MOVLW LOW dig_10 ; POINTER RAM
MOVWF FSR
MOVLW .10 ; 10 DIGIT PASS
MOVWF EE_Byte ; COUNTER
MAIN13:
BTFSC TIMEOUT
GOTO TIMEO ; TIMEOUT ERROR, RESTART
; WAIT A DIGIT
BTFSS DONE
GOTO MAIN13
MOVF RESULT1,W
MOVWF INDF ; PUT DIGIT IN DIG_10..1, RAM
DECF EE_Byte,F
BTFSC STATUS,Z
GOTO MAIN14 ; GOT 10 DIGITS
INCF FSR,F
CALL START_DTMF
CALL CLRTIMEOUT
GOTO MAIN13 ; WAIT FOR DIGIT 1..9
MAIN14:
; WAIT FOR #
CALL START_DTMF
CALL CLRTIMEOUT
MAIN15: ; WAIT #
BTFSC TIMEOUT
GOTO TIMEO ; TIMEOUT ERROR, RESTART
; WAIT A DIGIT
BTFSS DONE
GOTO MAIN15
MOVLW '#' ; COMPARE #
XORWF RESULT1,W
BTFSS STATUS,Z
GOTO MAINDTMF ; DIGIT<>#, RESTART
CALL START_DTMF
CALL CLRTIMEOUT
MAIN151: ; WAIT #
BTFSC TIMEOUT
GOTO TIMEO ; TIMEOUT ERROR, RESTART
; WAIT A DIGIT
BTFSS DONE
GOTO MAIN151
MOVLW '#' ; COMPARE #
XORWF RESULT1,W
BTFSS STATUS,Z
GOTO MAINDTMF ; DIGIT<>#, RESTART
; COMPARE PSS0..9 WITH DIG_10..1
; COMPARE PASSWORD
MOVLW LOW dig_10
MOVWF EE_Byte ; EE_BYTE POINER DIG_10..1
MOVLW LOW PSS0
MOVWF FSR ; FSR POINER RAM PSS0..9
MOVLW .10
MOVWF scrA ; SCRA COUNTER
MAIN16:
MOVF FSR,W
MOVWF scrB ; STORE FSB TEMP
MOVF EE_Byte,W
MOVWF FSR ; POINTER TO DIG
MOVF INDF, W ; READ DIG
MOVWF scrC ; STORE TEMP DIG
MOVF scrB, W
MOVWF FSR ; RESTORE POINTER FOR PSS
MOVF scrC,W ; RESTORE DIG VALUE IN W
XORWF INDF,W ; COMPARE DIG/PSS
BTFSC STATUS,Z
GOTO MAIN17
; PASS BAD
CALL BEEPERR
GOTO MAINDTMF ; RESTART, PASSWORD BAD
MAIN17:
DECF scrA,F
BTFSC STATUS,Z
GOTO MAIN18 ; PASS OK, CONTINUE
INCF EE_Byte,F ; NEXT DIGIT
INCF FSR,F
GOTO MAIN16
MAIN18:
;NEW PASS OK, WRITE NEW PASS FROM PSS0..9 TO EEPROM PASS0..9
MOVLW LOW PSS0
MOVWF FSR ; FSR POINER RAM PSS0..9
MOVLW .10
MOVWF scrA ; SCRA COUNTER
MOVLW LOW PASS0
MOVWF scrB ; POINTER TO EEPROM
MAIN19:
MOVF INDF,W ; READ FROM RAM
MOVWF EE_Byte ; TO EE_Byte
MOVF scrB, W ; POINTER IN EEPROM
CALL EE_WRITE_BYTE ; WRITE THE BYTE
DECF scrA,F
BTFSC STATUS,Z
GOTO MAIN20 ; PASS OK, CONTINUE
INCF scrB,F ; NEXT DIGIT
INCF FSR,F
GOTO MAIN19
MAIN20:
;debug
call cur_h1
call TESTPASS
;end debug
CALL BEEPOK ; PASS CHANGED
GOTO MAINDTMF
;***************************************************************
TIMEO:
; TIMEOUT + TIMEOUT BEEP
BSF DONE ;STOP DTMF DECODER
CALL BEEPERR ; TIMEOUT BEEP, TWO LOW BEEPS
CALL BEEPPAUSE
CALL BEEPERR
TIMEO1:
BSF DONE ;STOP DTMF DECODER
BCF PORTC,3 ; BEEP OFF
GOTO MAINDTMF ;RESTART
; ****** END MAIN LOOP
;START DTMF DECODER
START_DTMF
BSF DONE ; STOP DTMF INT ROUTINE
MOVF FSR,W
MOVWF FSR_SAVE_DTMF ; SAVE FSR
MOVLW 0X2F ; start -1
MOVWF FSR
TEMPXX1
INCF FSR,F
CLRF INDF
MOVF FSR,W
XORLW 0X3F ; CLEAR RAM FROM 0X30-0X3F
BTFSS STATUS,Z
GOTO TEMPXX1
; table read pointer
CLRF TABLECOUNTER
CLRF RESULT1 ; CLEAR RESULT DIGIT
MOVF FSR_SAVE_DTMF, W
MOVWF FSR ; RESTORE FSR
BCF DONE ; CLEAR DONE, START DTMD INT ROUTINE
RETURN
; BEEP ON ERROR, DESTROY scrA!
BEEPERR:
MOVLW .16
GOTO BEEP1
; BEEP WHEN OK, DESTROY scrA!
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -