digicomk
Joined: 29 Aug 2007 Posts: 3
|
Single Pin DTMF Tone Generation |
Posted: Thu Aug 30, 2007 11:15 am |
|
|
You can use any pin, just connect a 10K resistor series and a 0.1uF cap to ground. Now the news...
The good news is you can generate all 16 standard DTMF tones, you can use any PIC, you can change the pin and freq. if you change the times acordingly.
The bad news is the code is assembly PARALLAX version. Those of you having TECH-TOOLS tools can run the code right away.Others can go to www.tech-tools.com and get information about how to translate it.
Maybe somebody make a translation to native MICROCHIP and post it here. I can't promise to do it for a cople of month. Another issue, due to the forum's editor or my lack of skills with it, I'm not able to copy the code with the original labels tabs and spaces. You should figure out and make your own typing. Sooorry.
Here is the code
Code: |
; DTMF
include 'c:\pictools\16f873a.inc'
fuses _hs_osc&_wdt_off
fuses _cp_all&_lvp_off
; org 20h
al = 20h
ah = 21h
bl = 22h
bh = 23h
cl = 24h
ch = 25h
dl = 26h
dh = 27h
bitmask = 28h
tristate = 29h
outstate = 2ah
temp = 2ch
pwm = 2dh
number_ptr = 2eh
temp2 = 2fh
lookup_number jmp pc+w
; retw 12,13,80h
; retw 2,2,2,2,2,2,2,2,2,2,2,2,2,80h
; retw 9,9,0,1,9,1,6,7,2,5,1,7,8,9,80h
; retw 9,9,0,1,9,1,6,7,2,1,8,2,1,7,80h
; retw 5,6,6,3,2,3,1,80h
;; retw 5,8,3,9,80h
; retw 1,4,7,10,2,5,8,0,3,6,9,11,12,13,14,15,80h
; retw 9,3,1,6,6,1,8,8,5,80h
retw 6,5,3,7,4,2,4,80h
; retw 8,8,9,8,4,9,80h
; retw 5,6,3,2,5,6,8,80h
; retw 0,1,1,3,5,8,0,5,6,6,3,2,3,1,11,80h
; retw 7,2,1,8,2,1,7,80h
; retw 9,7,2,0,9,7,0,0ffh
;
;
; Frequency formula: c = Freq/(4000000/4/66/8/256) = Freq/7.40
; | | | | | | |
; constant --| | | | | | |
; target frequency ------ | | | | | |
; cpu clock frequency ---------------| | | | |
; 4:1 instruction rate --------------------| | | |
; cycles/loop ----------------------| | |
; samples/sinewave -------------------------| |
; c/256 rate ----------------------------|
;
r1 = 94 ;697 Hz
r2 = 104 ;770 Hz
r3 = 115 ;852 Hz
r4 = 127 ;941 Hz
c1 = 163 ;1209 Hz
c2 = 181 ;1336 Hz
c3 = 200 ;1477 Hz
c4 = 221 ;1632 Hz
lookup_freqs jmp pc+w ;lookup row and col frequencies
retw r4,c2 ;0
retw r1,c1 ;1
retw r1,c2 ;2
retw r1,c3 ;3
retw r2,c1 ;4
retw r2,c2 ;5
retw r2,c3 ;6
retw r3,c1 ;7
retw r3,c2 ;8
retw r3,c3 ;9
retw r4,c1 ;*
retw r4,c3 ;#
retw r1,c4 ;A
retw r2,c4 ;B
retw r3,c4 ;C
retw r4,c4 ;D
lookup_sine jmp pc+w
retw 3,5,6,5,3,1,0,1
lookup_pwm jmp pc+w
retw 000000b
retw 100000b
retw 010000b
retw 100100b
retw 010100b
retw 101010b
retw 011010b
retw 110110b
retw 011101b
retw 111011b
retw 011111b
retw 111111b
retw 111111b
start clr intcon
mov !ra,#30h
mov !rb,#04
mov !rc,#0ffh
clr ra
clr rb
clr rc
setb rp0
mov adcon1,#07
clrb rp0
mov !option,#44h
mov bitmask,#00000100b
mov tristate,#00000000b
mov outstate,#00000000b
mov !rb,tristate
wait jb ra.1,wait
clr number_ptr
:loop mov w,number_ptr
inc number_ptr
call lookup_number
mov dh,w
jb dh.7,:done
clc
rl dh
mov w,dh
call lookup_freqs
mov al,w
mov w,++dh
call lookup_freqs
mov ah,w
call dtmf_output
mov dh,#035h
:slow djnz dl,:slow
djnz dh,:slow
jmp :loop
:done jnb ra.1,:done
jmp start
;
;
; DTMF output
;
; in: al=tone1, ah=tone2
; uses: bl,bh,cl,ch,dl,dh
;
dtmf_output mov dh,#230
clr bl
clr bh
clr fsr
clr cl
clr ch
:loop add bl,al ;2 ;update tone1
snc ;1
inc cl ;1
clrb cl.3 ;1
mov w,outstate ;1 ;output bit3
snb pwm.3 ;1
or w,bitmask ;1
mov rb,w ;1
add bh,ah ;2 ;update tone2
snc ;1
inc ch ;1
clrb ch.3 ;1
inc fsr ;1 ;inc time
snz ;1
inc dh ;1
mov w,outstate ;1 ;output bit2
snb pwm.2 ;1
or w,bitmask ;1
mov rb,w ;1
mov w,cl ;1 ;lookup sine1
call lookup_sine ;6
mov temp,w ;1
mov w,outstate ;1 ;output bit1
snb pwm.1 ;1
or w,bitmask ;1
mov rb,w ;1
mov w,ch ;1 ;lookup sine2
call lookup_sine ;6
add temp,w ;1
mov w,outstate ;1 ;output bit0
snb pwm.0 ;1
or w,bitmask ;1
mov rb,w ;1
mov w,temp ;1 ;lookup pwm
call lookup_pwm ;6
mov pwm,w ;1
mov w,outstate ;1 ;output bit5 (1/2 bit)
snb pwm.5 ;1
or w,bitmask ;1
mov rb,w ;1
jmp $+1 ;2
mov w,outstate ;1 ;output bit4
snb pwm.4 ;1
or w,bitmask ;1
mov rb,w ;1
movsz w,++dh ;1 ;loop if not done
jmp :loop ;2 ;66us/loop
mov rb,outstate ;call set_low
ret
|
|
|