| ??? 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 |
| Topic | Author | Date |
| 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 |



