Email: Password: Remember Me | Create Account (Free)

Back to Subject List

Old thread has been locked -- no new posts accepted in this thread
???
03/27/03 21:27
Read: times


 
#42395 - Not possible 89c52 cannot do this
Responding to: ???'s previous message
Hello my friend,
try to realize the fact that as you also said that DTMF is a electrical sum of frequencies when a digit is pushed so a controller cannot be used for this purpose..although i found something for you which may be 1% of help ,



i got this long time ago from philiphs semi conductor website but its a tone generation not tone detection...

so face the fact you have to use transciver or DTMF decorder...


; 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 AD 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
; 6
db F770 ;fLOW = 770
db F1477 ;fHIGH = 1477
db 62
db 0
; 7
db F852 ;fLOW = 852
db F1209 ;fHIGH = 1209
db 68
db 0
; 8
db F852 ;fLOW = 852 (853)
db F1336 ;fHIGH = 1336 (1340)
db 68
db 0
; 9
db F852 ;fLOW = 852 (853)
db F1477 ;fHIGH = 1477 (1477)
db 68
db 0
; A
db F697 ;fLOW = 697 (698)
db F1633 ;fHIGH = 1633 (1622)
db 56
db 0

; B
db F770 ;fLOW = 770 (768)
db F1633 ;fHIGH = 1633 (1622)
db 62
db 0
; C
db F852 ;fLOW = 852 (853)
db F1633 ;fHIGH = 1633 (1622)
db 68
db 0
; D
db F941 ;fLOW = 941 (944)
db F1633 ;fHIGH = 1633 (1622)
db 76
db 0
; *
db F941 ;fLOW = 941 (944)
db F1209 ;fHIGH = 1209 (1213)
db 76
db 0
; #
db F941 ;fLOW = 941 (944)
db F1477 ;fHIGH = 1477 (1477)
db 76
db 0



org 04000h

test:
orl P1,#00001001b ;1/2 scale
mov SP,#050H ;init stack
setb EA ;enable interrupts
mov a,#80h ;do dial-tone
call LOAD_DTMF ;set it up
orl TCON,#01010000b ;turn on the timers

mov dptr,#200 ;wait 2 seconds
call TONE_WAIT
anl TCON,#10101111b ;turn off the timers

; the following is non-optimal but easy to understand
; This will output the Amaze BBS number, after you get things
; working audio couple the DTMF into your phone to dial SIGNETICS
; AMAZE. It does work. I've done it!!

mov a,#1
call SEND_DTMF

mov a,#8
call SEND_DTMF

mov a,#0
call SEND_DTMF

mov a,#0
call SEND_DTMF

mov a,#4
call SEND_DTMF

mov a,#5
call SEND_DTMF

mov a,#1
call SEND_DTMF

mov a,#6
call SEND_DTMF

mov a,#6
call SEND_DTMF

mov a,#4
call SEND_DTMF

mov a,#4
call SEND_DTMF

; try busy
busyl:
mov dptr,#200 ;quiet for 2 sec's.
call QUIET_WAIT

mov r3,#10
busyll:
mov a,#82h ;do busy
call LOAD_DTMF ;set it up
mov r7,CNT_10mS ;get 10mS count value
orl TCON,#01010000b ;turn on the timers
mov dptr,#50 ;wait 500 mS
call TONE_WAIT
anl TCON,#10101111b ;timers off
anl IE,#11110101b ;timer intr's off

mov dptr,#50
call QUIET_WAIT
djnz r3,busyll

mov dptr,#200
call QUIET_WAIT

ringl:
mov dptr,#100 ;silent line for 1 second
call QUIET_WAIT

mov r3,#7 ;do 7 busy cycles
ringll:
mov a,#81h ;do ring-back
call LOAD_DTMF ;set it up
mov r7,CNT_10mS ;get 10mS count value
orl TCON,#01010000b ;turn on the timers
mov dptr,#200 ;wait 2 seconds
call TONE_WAIT
anl TCON,#10101111b ;timers off
anl IE,#11110101b ;timer intr's off

mov dptr,#400 ;4 seconds off
call QUIET_WAIT
djnz r3,ringll ;send busy cycle till r3=0

mov dptr,#200 ;2 second off
call QUIET_WAIT

ljmp test

;===============
; send a dtmf tone for the char in <ACC>

SEND_DTMF:
call LOAD_DTMF ;init timers for this tone

TONE_OUT:
mov r7,CNT_10mS ;get 10mS count value
orl TCON,#01010000b ;turn on the timers
mov dptr,#10 ;wait 100 mS
call TONE_WAIT ;send tone while waiting
anl TCON,#10101111b ;timers off
anl IE,#11110101b ;timer intr's off

mov a,P1 ;fetch funny DAC port
anl a,#0f0h ;preserve non-DAC bits
orl a,#00001001b ;set DAC to mid scale
mov P1,a ;ship it
mov dptr,#7 ;wait 70 mS
call QUIET_WAIT ;no tone out
ret

;===============
; The following waits for the number of
; 10 mS tics contained in dptr
; ENTRY: dptr = (time/10mS)

QUIET_WAIT:
mov a,P1 ;fetch funny DAC port
anl a,#0f0h ;preserve non-DAC bits
orl a,#00001001b ;set DAC to mid scale
mov P1,a ;ship it
setb INT_FLAGS.1 ;fag tictoc intr.
anl IE,#11110101b ;timer intr's off
anl TCON,#10101111b ;timers off
mov TMOD,#022h ;8 bit auto-reload
mov TL0,#LOW(-200)
mov TH0,#LOW(-200) ;app. 217 uS
setb ET0 ;enable T0 intr
setb TR0 ;T0 on
mov r7,#46 ;46 * 217 uS = 9.98 mS
Q_loop1:
mov CNT_10mS,r7 ;set-up count
Q_loop2:
mov a,CNT_10mS ;get flag
jnz Q_loop2 ;go till 10 mS done?

call dec_dptr ;1 less 10 mS tick
mov a,dpl ;do 16 bit
orl a,dph ;compare = 0
jnz Q_loop1 ;go till no ticks left

anl IE,#11110101b ;timer intr's off
anl TCON,#10101111b ;timers off
clr INT_FLAGS.1 ;release tictoc intr.
ret ;done

;====================
TONE_WAIT:
mov a,CNT_10mS ;wait for 10 mS tick
jnz TONE_WAIT ;go till we have it

mov CNT_10mS,r7 ;re-init tick time
call dec_dptr ;1 tick is gone
mov a,dpl
orl a,dph ;dptr = 0 ?
jnz TONE_WAIT ;go till all ticks gone

ret

;=====================
dec_dptr:
xch a,dpl
jnz dec_dptr2

dec dph
dec_dptr2:
dec a
xch a,dpl
ret

;=====================
; The following is the tick-tock interrupt
; routine. No waveforms are generated only
; CNT_10mS is decremented for use as a timer.

TICTOC0:
dec CNT_10mS
reti

;=====================
; the following are the timer intr routines
; various functions are performed based on the
; state of the INT_FLAGS

T0INT:
push acc
jb INT_FLAGS.0,T0INTD ;auto-reoad if dtmf

mov a,TL0
add a,SIGNAL_HIGH+1 ;adjust for intr latency
mov TL0,a
mov a,TH0
addc a,SIGNAL_HIGH
mov TH0,a
T0INTD:
inc fHIGH
sjmp Tintmrg

T1INT:
push acc
jb INT_FLAGS.0,T1INTD ;skip next if dtmf

mov a,TL1
add a,SIGNAL_LOW+1
mov TL1,a
mov a,TH1
addc a,SIGNAL_LOW
mov TH1,a
T1INTD:
inc fLOW
dec CNT_10mS ;hit 10 mS timer

Tintmrg :
push Reg0
mov a,fLOW
jnb acc.2,$+5

xrl a,#3

anl a,#3
mov r0,a

mov a,fHIGH
jnb acc.2,$+5

xrl a,#3
anl a,#3
rl a
rl a
orl a,r0
mov P1,a
pop Reg0
pop acc
reti

end



List of 13 messages in thread
TopicAuthorDate
Controller for Tone Dialing detection ?            01/01/70 00:00      
   RE: Controller for Tone Dialing detection ?            01/01/70 00:00      
      Not possible 89c52 cannot do this            01/01/70 00:00      
   one more            01/01/70 00:00      
   RE: Controller for Tone Dialing detection ?            01/01/70 00:00      
   What about generating Dial Tone, Busy ?            01/01/70 00:00      
   RE: Controller for Tone Dialing detection ?            01/01/70 00:00      
      RE: Controller for Tone Dialing detection ?            01/01/70 00:00      
         RE: Controller for Tone Dialing detection ?            01/01/70 00:00      
   RE: Controller for Tone Dialing detection ?            01/01/70 00:00      
   RE: Controller for Tone Dialing detection ?            01/01/70 00:00      
      RE: Controller for Tone Dialing detection ?            01/01/70 00:00      
         RE: What's next, Waqar:            01/01/70 00:00      

Back to Subject List