📄 dtmf.asm
字号:
retlw 252
retlw 255
retlw 241
retlw 212
retlw 173
retlw 128
retlw 82
retlw 43
retlw 14
retlw 0
retlw 3
retlw 22
retlw 55
retlw 97
retlw 143
retlw 187
retlw 223
retlw 247
retlw 255
retlw 247
retlw 223
retlw 187
retlw 143
retlw 97
retlw 55
retlw 22
retlw 3
retlw 0
retlw 14
retlw 43
retlw 82
retlw 127 ; End of this sine wave
; *****************************************************************************
; * sineaddress *
; * This subroutine is used to calculate actual address in the sinelookup *
; * table for two DTMF waveforms. It is only called by setdtmfbase. W *
; * is loaded with the key number and this routine returns the sinelookup *
; * address the sine waves. *
; * RAM used: W *
; * PROGRAM MEM: 25 Words *
; *****************************************************************************
sineaddress ; Look-up table for sine address
addwf PCL,F ; Add to PC to jump into table
keyoffset
k1 retlw sinerow1-sineoffset ; Offset for Row 1 sine wave
retlw sinecolumna-sineoffset ; Offset for Column A sine wave
k2 retlw sinerow1-sineoffset ; Offset for Row 1 sine wave
retlw sinecolumnb-sineoffset ; Offset for Column A sine wave
k3 retlw sinerow1-sineoffset ; Offset for Row 1 sine wave
retlw sinecolumnc-sineoffset ; Offset for Column A sine wave
k4 retlw sinerow2-sineoffset ; Offset for Row 2 sine wave
retlw sinecolumna-sineoffset ; Offset for Column A sine wave
k5 retlw sinerow2-sineoffset ; Offset for Row 2 sine wave
retlw sinecolumnb-sineoffset ; Offset for Column B sine wave
k6 retlw sinerow2-sineoffset ; Offset for Row 2 sine wave
retlw sinecolumnc-sineoffset ; Offset for Column B sine wave
k7 retlw sinerow3-sineoffset ; Offset for Row 3 sine wave
retlw sinecolumna-sineoffset ; Offset for Column B sine wave
k8 retlw sinerow3-sineoffset ; Offset for Row 3 sine wave
retlw sinecolumnb-sineoffset ; Offset for Column B sine wave
k9 retlw sinerow3-sineoffset ; Offset for Row 3 sine wave
retlw sinecolumnc-sineoffset ; Offset for Column C sine wave
k10 retlw sinerow4-sineoffset ; Offset for Row 4 sine wave
retlw sinecolumna-sineoffset ; Offset for Column C sine wave
k11 retlw sinerow4-sineoffset ; Offset for Row 4 sine wave
retlw sinecolumnb-sineoffset ; Offset for Column C sine wave
k12 retlw sinerow4-sineoffset ; Offset for Row 4 sine wave
retlw sinecolumnc-sineoffset ; Offset for Column C sine wave
key1=k1-keyoffset ; Calculation for sine addr for keypad 1
key2=k2-keyoffset ; Calculation for sine addr for keypad 2
key3=k3-keyoffset ; Calculation for sine addr for keypad 3
key4=k4-keyoffset ; Calculation for sine addr for keypad 4
key5=k5-keyoffset ; Calculation for sine addr for keypad 5
key6=k6-keyoffset ; Calculation for sine addr for keypad 6
key7=k7-keyoffset ; Calculation for sine addr for keypad 7
key8=k8-keyoffset ; Calculation for sine addr for keypad 8
key9=k9-keyoffset ; Calculation for sine addr for keypad 9
keystar=k10-keyoffset ; Calculation for sine addr for keypad *
key0=k11-keyoffset ; Calculation for sine addr for keypad 0
keypound=k12-keyoffset ; Calculation for sine addr for keypad #
; *****************************************************************************
; * senddtmf *
; * This subroutine is used to calculate the offset address for *
; * the two sine waves to be sent and initialize the WAVEABASE and WABEBBASE *
; * file registers. The key number (key0 - key9 or keystar or keypound) is *
; * loaded into W before this routine is called. Next, the DTMF for that *
; * key is sent to the R2R ladder through portB for 320 mS *
; * Example: *
; * movlw key1 *
; * call senddtmf *
; * RAM used: 8 bytes *
; * PROGRAM MEM: 37 Words *
; *****************************************************************************
senddtmf
movwf TEMP ; Initialize temp with key number
call sineaddress ; Get the address for sine wave a for this key
movwf WAVEABASE ; Initialize sine wave A base address
swapf WAVEABASE,F ; swap WAVEABASE so that Z bit is not effected
movwf POINTERA ; Initialize sine wave A pointer address
incf TEMP,W ; Now we get the second sine wave address...
call sineaddress ; Get the address for sine wave b for this key
movwf WAVEBBASE ; Initialize sine wave B base address
swapf WAVEBBASE,F ; swap WAVEBBASE so that Z bit is not effected
movwf POINTERB ; Initialize sine wave B pointer address
movlw 20h ; Place 32 decimal into W for loop counter
movwf SINECOUNTH ; Initialize loop counter to 20
loopsine2cyc
goto loopsine ; Waste two cycles to maintain 35 cycle loop count
loopsine
movf POINTERA,W ; Place sine wave address into W
call sinelookup ; Look-up first sine wave
movwf NEXTVALUE ; Place first sine wave into NEXTVALUE
incf POINTERA,F ; Move to the next place in the wave
xorlw ENDSINE ; Update Z bit
swapf WAVEABASE,W ; Restore to beginning of sine wave
btfsc STATUS,Z ; Skip if not at end of sine wave
movwf POINTERA ; Restore start address if at end of sine
movf POINTERB,W ; Place sine wave address into W
call sinelookup ; Look-up second sine wave
addwf NEXTVALUE,F ; Add second sine wave into NEXTVALUE
incf POINTERB,F ; Move to next place in the wave
xorlw ENDSINE ; Update Z bit
swapf WAVEBBASE,W ; Pointer of sine wave beginneing -> W
btfsc STATUS,Z ; Skip if not at end of sine wave
movwf POINTERB ; Restore start address if at end of sine
rrf NEXTVALUE,W ; Divide by 2, Place output into PORTB
movwf PORTB ; Update PORTB with new R2R value
goto waste2cyc ; Waste (2) cycles for 35 total
waste2cyc
decfsz SINECOUNT,F ; Skip if we are done
goto loopsine2cyc ; Do it again! (add 2 cycles as well)
decfsz SINECOUNTH,F ; Skip if we are done
goto loopsine ; Do it again!
retlw 0 ; Return from sine output
; *****************************************************************************
; * init *
; * This code is used to initialize the PIC. PORTB is set to zero and all *
; * pins are set to outputs *
; * RAM used: 0 bytes *
; * PROGRAM MEM: 3 Words *
; *****************************************************************************
init
clrf PORTB ; Init output latches for port B to 0
clrw ; Clear W register
tris PORTB ; Set all of PORT B to outputs
; *****************************************************************************
; * testallkeys *
; * This code is used to test all possible keys in the keypad. First each *
; * key address is loaded and then senddtmf is called. *
; * RAM used: 0 bytes *
; * PROGRAM MEM: 25 Words *
; *****************************************************************************
testallkeys
wait0
movlw key1 ; Place key "1" address into W
call senddtmf ; Transmit DTMF tone for this key
btfsc PORTA,0 ; Skip and send out next tone if button is pressed
goto wait0 ; No button press, keep current tone
btfss PORTA,0 ; Skip when button is released
goto $-1 ; Wait for button release
wait1
movlw key2 ; Place key "2" address into W
call senddtmf ; Transmit DTMF tone for this key
btfsc PORTA,0 ; Skip and send out next tone if button is pressed
goto wait1 ; No button press, keep current tone
btfss PORTA,0 ; Skip when button is released
goto $-1 ; Wait for button release
wait2
movlw key3 ; Place key "3" address into W
call senddtmf ; Transmit DTMF tone for this key
btfsc PORTA,0 ; Skip and send out next tone if button is pressed
goto wait2 ; No button press, keep current tone
btfss PORTA,0 ; Skip when button is released
goto $-1 ; Wait for button release
wait3
movlw key4 ; Place key "4" address into W
call senddtmf ; Transmit DTMF tone for this key
btfsc PORTA,0 ; Skip and send out next tone if button is pressed
goto wait3 ; No button press, keep current tone
btfss PORTA,0 ; Skip when button is released
goto $-1 ; Wait for button release
wait4
movlw key5 ; Place key "5" address into W
call senddtmf ; Transmit DTMF tone for this key
btfsc PORTA,0 ; Skip and send out next tone if button is pressed
goto wait4 ; No button press, keep current tone
btfss PORTA,0 ; Skip when button is released
goto $-1 ; Wait for button release
wait5
movlw key6 ; Place key "6" address into W
call senddtmf ; Transmit DTMF tone for this key
btfsc PORTA,0 ; Skip and send out next tone if button is pressed
goto wait5 ; No button press, keep current tone
btfss PORTA,0 ; Skip when button is released
goto $-1 ; Wait for button release
wait6
movlw key7 ; Place key "7" address into W
call senddtmf ; Transmit DTMF tone for this key
btfsc PORTA,0 ; Skip and send out next tone if button is pressed
goto wait6 ; No button press, keep current tone
btfss PORTA,0 ; Skip when button is released
goto $-1 ; Wait for button release
wait7
movlw key8 ; Place key "8" address into W
call senddtmf ; Transmit DTMF tone for this key
btfsc PORTA,0 ; Skip and send out next tone if button is pressed
goto wait7 ; No button press, keep current tone
btfss PORTA,0 ; Skip when button is released
goto $-1 ; Wait for button release
wait8
movlw key9 ; Place key "9" address into W
call senddtmf ; Transmit DTMF tone for this key
btfsc PORTA,0 ; Skip and send out next tone if button is pressed
goto wait8 ; No button press, keep current tone
btfss PORTA,0 ; Skip when button is released
goto $-1 ; Wait for button release
wait9
movlw keystar ; Place key "*" address into W
call senddtmf ; Transmit DTMF tone for this key
btfsc PORTA,0 ; Skip and send out next tone if button is pressed
goto wait9 ; No button press, keep current tone
btfss PORTA,0 ; Skip when button is released
goto $-1 ; Wait for button release
wait10
movlw key0 ; Place key "0" address into W
call senddtmf ; Transmit DTMF tone for this key
btfsc PORTA,0 ; Skip and send out next tone if button is pressed
goto wait10 ; No button press, keep current tone
btfss PORTA,0 ; Skip when button is released
goto $-1 ; Wait for button release
wait11
movlw keypound ; Place key "#" address into W
call senddtmf ; Transmit DTMF tone for this key
btfsc PORTA,0 ; Skip and send out next tone if button is pressed
goto wait11 ; No button press, keep current tone
btfss PORTA,0 ; Skip when button is released
goto $-1 ; Wait for button release
goto testallkeys ; jump back and do it again!
resetvector
ORG 1ffh ; The RESET vector of a 54 is at 1FFh
goto init ; Jump to initialion routine
END
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -