Hola acá les dejo una rutinita para el control del integradito generador de DTMF, ya hay una dando vueltas por la red, en la cual me basé, pero tiene varios errores y varias cosas que no hacen falta.
antes de llamar a la subrutina dtmf se debe cargar el valor del dígito a transmitir en W.
en este ejemplo utilicé rb4 como terminal de clock y rb3 como dato, tiene además este integrado un terminal de cs (chip select) en lógica negada, osea que cuando está en uno el integrado se apaga y cuando está en cero se enciende.
En mi caso no lo utilicé ya que detiene el tono enviandole un 31 en decimal, aparte el control por el CS genera un clack! bastante molesto, espero que les sirva, saludos.
movlw .5 ;en este caso envía el 5
call dtmf ;llama a la subrutina
call retardo_60ms ;llama a la sub de retardo
;para que suene unos 60ms
movlw .31 ;con este número detiene la salida del tono
;puede ser cualquier número que termine con 5 unos...
call dtmf ;lo envía
call retardo_40ms ;suponiendo que enviamos otro dígito
;tiene que haber un tiempo con silencio
;entre dígito y dígito.
.
.
.
.
.
dtmf movwf digito ;carga el número a enviar en dígito
movlw d'5' ;carga el contador en 5
movwf contador ;va a contar cinco veces
bsf portb,rb4 ;se asegura que el pulso del clock esté en uno, en este caso es rb4
dtmf_bucle bsf portb,rb3 ;saca el dato a transmitir por rb3
btfss digito,0 ;si el bit a transmitir es uno lo deja como está
bcf portb,rb3 ;si no lo pone en cero
bcf portb,rb4 ;flanco de bajada del clock, transmite el bit
nop ;el tiempo de retardo es 5 uS
nop ;para una frecuencia de 100khz aprox.
nop
nop
bsf portb,rb4 ;sube el pulso de reloj
rrf digito,1 ;va rotando el bit a transmitir
bcf status,c ;limpia el carry
decfsz contador,1 ;si llegó a cero el contador, sale del bucle
goto dtmf_bucle ;vuelve al bucle
return ;retorna al programa