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
 
 | 	 
  | 
			 
		  |