dtmf.asm
来自「电话远程控制家电系统单片机开发电话远程控制家电系统单片机开发」· 汇编 代码 · 共 2,240 行 · 第 1/4 页
ASM
2,240 行
BEEPOK:
MOVLW .4
BEEP1:
MOVWF TIME2 ; BEEP PITCH
MOVWF scrA
BANKSEL TRISC
BCF TRISC,0 ; PORTC 0 = OUT
BANKSEL PORTC ; BACK TO BANK 0
BSF BEEP ; START INT BEEP ROUTINE
BSF TIMEOUT ; STOP TIMEOUT ROUTINE
CLRF TIME0 ; INIT TIMEOUT COUNTER
MOVLW .25
MOVWF TIME1
BCF TIMEOUT ; START TIMEOUT
BEEPWAIT:
BTFSS TIMEOUT
GOTO BEEPWAIT
BCF BEEP ; STOP INT BEEP ROUTINE
BCF PORTC,0 ; SET OUTPUT TO 0 VOLTS
BANKSEL TRISC
BSF TRISC,0 ; PORTC 0 = INPUT / HIGH z
BANKSEL PORTC ; BACK TO BANK 0
RETURN
; BEEPPAUSE WAIT A LITTLE BIT....
BEEPPAUSE:
BSF TIMEOUT ; STOP TIMEOUT ROUTINE
CLRF TIME0 ; INIT TIMEOUT COUNTER
MOVLW .10
MOVWF TIME1
BCF TIMEOUT ; START TIMEOUT
BEEPWAIT1:
BTFSS TIMEOUT
GOTO BEEPWAIT1
RETURN
; CLEAR TIMEOUT TIMER
CLRTIMEOUT: ; CLEAR TIMEOUT TIMER ( ~6.7 SECONDS)
BCF TIMEOUT ; STOP INT TIMEOUT ROUTINE
CLRF TIME0 ; INIT TIMEOUT COUNTER
CLRF TIME1
BCF TIMEOUT ; START INT TIMEOUT ROUTINE
RETURN
; PRINT PASSWORD IN EEPROM
TESTPASS:
MOVLW .8
MOVWF EE_Byte
TESTPASS1:
MOVF EE_Byte,W
CALL EE_READ_BYTE
CALL send_c ; PRINT DIGIT
INCF EE_Byte,F
MOVLW 0X12 ; END OF PASS+1
XORWF EE_Byte, W
BTFSS STATUS, Z
GOTO TESTPASS1
CALL cur_h1
RETURN
;**********************
; UTILITY ROUTINES
;**********************
;
; 8/15/02
;
; display routines, 16F87X Q=20Mhz
; display IC HD44780A00 / 16X2
; Display connected to Port D
;
; PORTD0 DATA4
; PORTD1 DATA5
; PORTD2 DATA6
; PORTD3 DATA7
; DATA0-3 - GROUND
; PORTD4 RS
; PORTD5 E
; PORTD6 - NOT USED
; PORTD7 - NOT USED
;
;
;
; init_disp - initialize display
; cur_h1 - cursor home line 1
; cur_h2 - cursor home line 2
;
; movlw LOW text
; movwf comA
; movlw HIGH text
; movwf comB
; call prt_rom - print the text in Rom (comB:comA)
;
; binbcdU8 - convert 8 bit unsigned count_1 to dis_2,dis_1
; bcdascii8 - Convert bcd dis_2..1 in ASCII dis_4..1
; leadzero8 - delete leading zeroes from dig_4 - dig_2
; dispU8 - display 8 bit unsigned count_1 to dis_4..1, +1 stack level
; dispS8 - display 8 bit signed count_1 to dis_4..1, +1 stack level
; binbcdU32 - convert 32 bit unsigned count_4:3:2:1-->dig_5..1, 10 digits, dis_5 low nibble=MSD, +1 stack level
; bcdascii32 - Convert bcd dig_5..1 in ASCII dig_9..1
; leadzero32 - delete leading zeroes from dig_10 - dig_2
; prtram - print from RAM, string located at (IRP:W)
; send_c - send char in W
; send caracter in W + 100 uS delay
send_c: movwf comC
swapf comC, W
andlw 0xF
iorlw 0x10 ;RS=1
movwf PORTD ;E=0
nop
bsf PORTD,0x5;E=1
nop
nop
bcf PORTD,0x5;E=0
goto $+1
goto $+1 ;delay 1 uS
movf comC, W
andlw 0xF
iorlw 0x10 ;RS=1
movwf PORTD ;E=0
nop
bsf PORTD,0x5;E=1
nop
nop
bcf PORTD,0x5;E=0
; delay 100 uS
del_100: movlw 165 ; 165 = 100uS
movwf scrA
del_100A: decfsz scrA, F
goto del_100A
return
; send byte in W
send_b: movwf comC
swapf comC, W ; high nibble
andlw 0xF
movwf PORTD ;E=0
nop
bsf PORTD,0x5;E=1
nop
nop
bcf PORTD,0x5;E=0
goto $+1
goto $+1 ; delay 1uS
movf comC, W ; Low nibble
andlw 0xF
movwf PORTD ; E=0
nop
bsf PORTD,0x5; E=1
nop
nop
bcf PORTD,0x5; E=0
return
; send nibble, low w
send_n: movwf PORTD ; E=0
nop
bsf PORTD,0x5 ; E=1
nop
nop
bcf PORTD,0x5 ; E=0
return
; print the string located at (comB:comA) in program memory
prt_rom:
Bank2
prt_rom1: movf comA, W ;Write the
movwf EEADR ;address bytes
movf comB, W
movwf EEADRH
bsf STATUS, RP0 ;Bank3
bsf EECON1, EEPGD ;Point to program memory
bsf EECON1, RD ;start read operation
nop ;required two nop's
nop
bcf STATUS, RP0 ;Bank2
movf EEDATA, W ;char in W
andlw 0xFF ;compare 0
btfsc STATUS, Z
goto prt_rom2
Bank0
call send_c ; print char in w+100uS wait
incfsz comA, F
goto prt_rom
incf comB, F
goto prt_rom
prt_rom2:
Bank0
return
; cursor home line 1
cur_h1: movlw 0x80
cur_h11: call send_b
call del_100
return
; cursor home line 2
cur_h2: movlw 0xC0
goto cur_h11
; delay 1 ms
del_1m: movlw 0xA
; w=delayX100nS
del_1mx: movwf scrB
del_1mA: decfsz scrB, F
goto del_1mB
return
del_1mB: movlw 165
movwf scrA
del_1mC: decfsz scrA, F
goto del_1mC
goto del_1mA
prt_ram: ;print from RAM, string located at (IRP:W)
movwf FSR
prt_ram1: movlw 0
subwf INDF, w ; compare 0
btfsc STATUS, Z
return ; char = zero
movf INDF, W
call send_c
incf FSR, F
goto prt_ram1
leadzero8: ; delete leading zeroes from dig_4 - dig_2
BCF STATUS, IRP
movlw .3
movwf scrA
movlw LOW dig_4
goto leadzeroin
leadzero32: ; delete leading zeroes from dig_10 - dig_2
BCF STATUS, IRP
movlw .9
movwf scrA
movlw LOW dig_10
leadzeroin:
movwf FSR
leadz1: movlw 0x30 ; ascii zero
subwf INDF, w ; compare 0x30
btfss STATUS, Z
return ; first char <>zero
movlw 0x20 ; ascii space
movwf INDF
decf scrA, F
btfsc STATUS, Z ; exit if zero
return
incf FSR, F
goto leadz1
bcdascii32: ; Convert bcd dis_5..1 in ASCII dis_9..1
swapf dig_5, W
andlw 0x0F
addlw 0x30
movwf dig_10
movf dig_5, W
andlw 0x0F
addlw 0x30
movwf dig_9
swapf dig_4, W
andlw 0x0F
addlw 0x30
movwf dig_8
movf dig_4, W
andlw 0x0F
addlw 0x30
movwf dig_7
swapf dig_3, W
andlw 0x0F
addlw 0x30
movwf dig_6
movf dig_3, W
andlw 0x0F
addlw 0x30
movwf dig_5
bcdascii8: ; Convert bcd dis_2..1 in ASCII dis_4..1
swapf dig_2, W
andlw 0x0F
addlw 0x30
movwf dig_4
movf dig_2, W
andlw 0x0F
addlw 0x30
movwf dig_3
swapf dig_1, W
andlw 0x0F
addlw 0x30
movwf dig_2
movf dig_1, W
andlw 0x0F
addlw 0x30
movwf dig_1
return
dispS8: ; display 8 bit signed count_1 to dis_4..1, +1 stack level
btfss count_1,7
goto dispU8
; disp neg 8
comf count_1, F ; complement
incf count_1, F ; X(-1)
call binbcdU8 ; dis2..1 bcd
call bcdascii8 ; dis4..1 ascii
; leadzero and - delete leading zeroes from dig_4..2 and add the - sign
BCF STATUS, IRP
movlw .4
movwf scrA
movlw LOW dig_4
movwf FSR
leadzN1: movlw 0x30 ; ascii zero
subwf INDF, w ; compare 0x30
btfss STATUS, Z
goto leadzN2 ; first char <>zero, add -
movlw 0x20 ; ascii space
movwf INDF
decf scrA, F
btfsc STATUS, Z ; exit if zero
return
incf FSR, F
goto leadzN1
leadzN2: ; dec pointer and display "-"
decf FSR, F
movlw "-" ; ascii -
movwf INDF
return
return
dispU8: ; display 8 bit unsigned count_1 to dis_4..1, +1 stack level
call binbcdU8
call bcdascii8
call leadzero8
return
binbcdU8: ; convert 8 bit unsigned count_1 to dis_2,dis_1
bcf STATUS,C ; clear the carry bit
BCF STATUS, IRP ;Page zero or 1 for indirect
movlw 8
movwf scrA
clrf dig_1
clrf dig_2
loop8: rlf count_1,F
rlf dig_1, F
rlf dig_2, F
;
decfsz scrA, F
goto adjDEC8
RETLW 0
;
adjDEC8: movlw dig_1
movwf FSR
movlw 0x3
addwf INDF,W
movwf scrB
btfsc scrB,3 ; test if result > 7
movwf INDF
movlw 0x30
addwf INDF,W
movwf scrB
btfsc scrB,7 ; test if result > 7
movwf INDF ; save as MSD
;
movlw dig_2
movwf FSR
movlw 0x3
addwf INDF,W
movwf scrB
btfsc scrB,3 ; test if result > 7
movwf INDF
movlw 0x30
addwf INDF,W
movwf scrB
btfsc scrB,7 ; test if result > 7
movwf INDF ; save as MSD
goto loop8
;
binbcdU32: ; convert 32 bit unsigned count_4:3:2:1-->dig_5..1, 10 digits,
; dis_5 low nibble=MSD, +1 stack level
bcf STATUS,C ; clear the carry bit
BCF STATUS, IRP ;Page zero or 1 for indirect
movlw 32
movwf scrA
clrf dig_1
clrf dig_2
clrf dig_3
clrf dig_4
clrf dig_5
loop28: rlf count_1,F
rlf count_2,F
rlf count_3,F
rlf count_4,F
rlf dig_1, F
rlf dig_2, F
rlf dig_3, F
rlf dig_4, F
rlf dig_5, F
;
decfsz scrA, F
goto adjDEC
RETLW 0
;
adjDEC: movlw dig_1
movwf FSR
call adjBCD
;
movlw dig_2
movwf FSR
call adjBCD
;
movlw dig_3
movwf FSR
call adjBCD
;
movlw dig_4
movwf FSR
call adjBCD
;
movlw dig_5
movwf FSR
call adjBCD
goto loop28
adjBCD: movlw 0x3
addwf INDF,W
movwf scrB
btfsc scrB,3 ; test if result > 7
movwf INDF
movlw 0x30
addwf INDF,W
movwf scrB
btfsc scrB,7 ; test if result > 7
movwf INDF ; save as MSD
RETLW 0
; init display in 4 bit transfer mode
init_disp:
Bank0
clrf PORTD
Bank1
movlw B'11000000' ; port D<0..5>=out
movwf TRISD
Bank0
movlw 200 ; 20ms
call del_1mx
movlw 0x3
call send_n
movlw 50 ; 5ms
call del_1mx
movlw 0x3
call send_n
call del_100 ; 100uS
movlw 0x3
call send_n
call del_100
movlw 0x2
call send_n
call del_1m
movlw 0x28 ; function, 4 bit data, 2 line, 5X7
call send_b
call del_1m
movlw 0x6 ; Entry mode set, increment, no shift
call send_b
call del_100
movlw 0xE ; display on, cursor on, blink off
call send_b
call del_100
movlw 0x1 ; display clear
call send_b
movlw 30 ; 2 ms delay to clear the display
call del_1mx
return
linie1: DE "Display Test X",0
;****************************
;EEprom routines by Tony Kubek
DISABLE_IRQ MACRO
LOCAL STOP_INT
STOP_INT BCF INTCON,GIE ; disable global interrupt
BTFSC INTCON,GIE ; check if disabled
GOTO STOP_INT ; nope, try again
ENDM
;+++++
; ENABLE_IRQ enable global irq
ENABLE_IRQ MACRO
BSF INTCON,GIE ; enable global interrupt
ENDM
; ***********************************************************************
; EE_WRITE_BYTE - Routine to write a byte to ee ram
; Adress in W, byte MUST be in EE_Byte
EE_WRITE_BYTE
Bank2 ; select bank2
MOVWF EEADR ; setup adress
Bank0 ;
MOVF EE_Byte,W ; get byte
Bank2
MOVWF EEDATA ; setup byte to write
BSF STATUS,RP0 ; bank3 !!
BCF EECON1,EEPGD ; set to data ee ram
BSF EECON1,WREN ; enable writes
DISABLE_IRQ ; disable irq's
MOVLW H'55' ; required sequence !!
MOVWF EECON2
MOVLW H'AA'
MOVWF EECON2
BSF EECON1,WR ; begin write procedure
ENABLE_IRQ ; enable irq's again
BCF EECON1,WREN ; disable writes ( does not affect current write cycle )
Bank0 ; reset to bank0
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?