📄 dtmf.s03
字号:
; The following code uses both timers in an 80c31 to generate
; DTMF tones, and signalling tones such as BUSY, RING-BACK, etc.
; This file also contains the connections for a very crude 2 bit
; per tone A\D converter wich uses 4 bits of P1 and a low pass filter.
; Compensation for twist isn't included but could be handled by
; playing with the hi and low tone dac values and the summing amp
; input resistors.
;
; If this code is used in any application I only request that
; credit be given to me:
; Bert Rinne
; Advanced Logic Systems Inc.
; 13 Twin Meadows Dr.
; Hudson N.H. 03051
; (C) 1993
;
; Note: This code was written for the Archemedes assembler
; but modification to other's sould be easy since I've
; avoided MACRO's to ease the change
;
; Use in good health
;
; *** Another method of tone generation is documented in the
; 'YUCK' Zilog Z8 microcontrollers book circa 1991 using the
; Super8. It is a waveform synthesis model using a 8Khz sampled
; data system with 1 timer and an 8 bit dac. If anyone should
; adapt the technique to the '51/'31 family please post the
; code on this BBS in return for the info.
;
; Bert Rinne 12/93
;
ASEG ;this denotes absolute assembly addresses
; next 2 lines are for simulation using EMILY
; org 0 ;commented out for the 31 monitor used
; jmp test
org 0bh
jb INT_FLAGS.1,TICK0
jmp T0INT ;generate waveforms
TICK0:
jmp TICTOC0 ;10mS ony timer
org 001bh
jmp T1INT
INT_FLAGS equ 020h ;interrupt routine flags
SIGNAL_LOW equ 021h ;2 bytes for signal fLOW timer
SIGNAL_HIGH equ 023h ;2 bytes for signal fHIGH timer
fHIGH equ 025h
fLOW equ 026h
CNT_10mS equ 027h
Reg0 equ 0
org 03000h ;temp address
;================================
; the following code loads the dialing array
; with the values needed for dtmf tone generation
; ENTER: <ACC> = dtmf or signal tone number
; ie. 0123456789 ABCD
; or * = 0eH # = 0fH
; dial tone = 080h
; ring back = 081h
; busy = 082h
;
; first parse 0-9, ABCD, *#, from signal group
LOAD_DTMF:
clr INT_FLAGS.1 ;flag dtmf timer mode
anl IE,#11110101b ;timer ints. off
anl TCON,#10101111b ;stop timers
jbc acc.7,SIGNAL ;Go if signal
mov TMOD,#022h ;T0 = T1 = 8 bit Auto-reload
anl a,#0fh ;strip any trash
rl a ;* 2
rl a ;* 4 total
mov b,a ;save a copy
mov dptr,#TONE_TBL ;point at table
movc a,@a+dptr ;get fLOW
mov TL1,a ;set T1 low
mov TH1,a ;set reload latch
inc dptr ;to next entry
mov a,b ;get index
movc a,@a+dptr ;get fHIGH
mov TL0,a ;set T0 low
mov TH0,a ;and the latch
inc dptr ;bump to 10 mS count
mov a,b ;the index
movc a,@a+dptr ;get count
mov CNT_10mS,a ;put 10mS count in place
setb INT_FLAGS.0 ;flag ISR 0
orl IE,#00001010b ;enable T0 and T1 intr's
ret ;bye
;
; If we come here it's from the signal group
; so we use the 16 bit timer modes
;
; see if it's dial tone
SIGNAL:
mov TMOD,#11H ;set 16 bit timer modes
jnz not_dial_tone ;go if not dial tone
; if here it's dial tone
mov dptr,#F440+2 ;440 Hz
mov TL0,DPL
mov TH0,DPH
mov SIGNAL_HIGH+1,DPL
mov SIGNAL_HIGH,DPH
mov dptr,#F350+2 ;350 Hz
mov TL1,DPL
mov TH1,DPH
mov SIGNAL_LOW+1,DPL
mov SIGNAL_LOW,DPH
mov CNT_10mS,#28 ;10 mS for count
clr INT_FLAGS.0 ;fag 16 bit timer ops
orl IE,#00001010b ;enable T1 and T2 intr's
ret
; not dial tone so see if it's ring-back
not_dial_tone:
dec a ;see if it's ring back
jnz not_ring_back ;fork if not
mov dptr,#F480+2 ;adjust for intr latency
mov TL0,DPL
mov TH0,DPH
mov SIGNAL_HIGH+1,DPL
mov SIGNAL_HIGH,DPH
mov dptr,#F440+2 ;440 Hz
mov TL1,DPL
mov TH1,DPH
mov SIGNAL_LOW+1,DPL
mov SIGNAL_LOW,DPH
mov CNT_10mS,#36 ;count for 10 mS
clr INT_FLAGS.0 ;fag 16 bit timer ops
orl IE,#00001010b ;enable T1 and T2 intr's
ret
; not ring-back so assume it's busy
not_ring_back:
mov dptr,#F620+2 ;620 Hz
mov TL0,DPL
mov TH0,DPH
mov SIGNAL_HIGH+1,DPL
mov SIGNAL_HIGH,DPH
mov dptr,#F480+2 ;480 Hz
mov TL1,DPL
mov TH1,DPH
mov SIGNAL_LOW+1,DPL
mov SIGNAL_LOW,DPH
mov CNT_10mS,#39 ;count for 10 mS
clr INT_FLAGS.0 ;fag 16 bit timer ops
orl IE,#00001010b ;enable T1 and T2 intr's
ret
;
; HARDWARE CONFIGURATION ____/\/\/\___
;--------, | |
; 8031 | 47k +-----][----|
; P1.0 |-----/\/\/\------, | |
; | 12k +--/\/\/\--, | \ |
; P1.1 |-----/\/\/\------' | | | \ |
; | +---][---+---|- \_|____||___
; | 47k | | / ||
; P1.2 |-----/\/\/\------, | ,--|+ /
; | 12k |--/\/\/\--' | |/
; P1.3 |-----/\/\/\------' |
;--------' +2.5V
;
; the dac uses 3 bits per channel internal to the mpu and
; counts as follows 000 001 010 011 100 101 110 111
; using bit 2 as the sign and complementing bits 0 & 1 we
; get 000 001 010 011 111 110 101 100 and
; output 00 01 10 11 11 10 01 00
; The above was coupled to a 100mw amp and used to dial the phone
; via acoustical coupling (held phone near speaker) with no errors.
;
; Funky DAC courtesy of Don Lancaster's wonderful book -
; The CMOS Cookbook, Howard Sams Inc.
;
; DIALING TONES (dtmf)
;
; 1209 1336 1477 1633
;
; 697 1 2 3 A
;
; 770 4 5 6 B
;
; 852 7 8 9 C
;
; 941 * 0 # D
;
; Using the formula f = -(((osc/12)/bits-per-cycle)/desired-freq.)
;
; thus at 11.059 MHz clock and 8 bits per cycle:
;
; desired timer value actual freq
; 697 = -165 698.2
; 770 = -150 768
; 852 = -135 853.3
; 941 = -122 944
;
; 1209 = -95 1212.6
; 1336 = -86 1339.5
; 1477 = -78 1476.9
; 1633 = -71 1622.5
F697 equ LOW(-165)
F770 equ LOW(-150)
F852 equ LOW(-135)
F941 equ LOW(-122)
;
F1209 equ LOW(-95)
F1336 equ LOW(-86)
F1477 equ LOW(-78)
F1633 equ LOW(-71)
;
; Tone time on >40 mS Bell spec minimum so we
; Tone time off >40 mS will use 100mS on/70 mS off
;
; SIGNAL TONES
; NOTE *** the signal tone values are adjusted by LOAD_DTMF:
; to compensate for latency time while re-loading the timers.
; The latency time is 2 us. and is critical for
; valid signal tone frequencies.
;
;
; Dial tone 350 440 steady tone -13dBm
; ring-back 440 480 2 sec on/ 4 sec off -19dBm
; busy 480 620 .5 sec on/.5 sec off -24dBm
; NOTE: *******
; Although the following are not implemented, they are valid
; signal tones:
;
; Reorder: 480 620 .25 sec on/.25 sec off -24dBm
;
; Partial dial tone
; 480 steady tone -17dBm
;
; Auto credit call prompting:
; 941 1477 940 mSEC -10dBm/freq.
; followed by 440 350 exponentially decaying from -10dBm
; @ a time constant of 200mSec.
;
; Reference: Mitel Semiconductor Data book circa '86-'87.
; "Credit must be given where due."
;
; Pulse dialing can be accomplished very easily using the timers
; and if you're reading this you can figure it out.
;
; desired timer value actual freq
; 350 -329 350
; 440 -262 439.7
; 480 -240 480
; 620 -186 619
F350 equ -329
F440 equ -262
F480 equ -240
F620 equ -186
TONE_TBL:
; 0
db F941 ;fLOW = 941
db F1336 ;fHIGH = 1336
db 76 ;76 * fLOW intrs = 10mS
db 0
; 1
db F697 ;fLOW = 697
db F1209 ;fHIGH = 1209
db 56 ;56 * fLOW intrs = 10 mS
db 0
; 2
db F697 ;fLOW = 697
db F1336 ;fHIGH = 1336
db 56
db 0
; 3
db F697 ;fLOW = 697
db F1477 ;fHIGH = 1477
db 56
db 0
; 4
db F770 ;fLOW = 770
db F1209 ;fHIGH = 1209
db 62
db 0
; 5
db F770 ;fLOW = 770
db F1336 ;fHIGH = 1336
db 62
db 0
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -