Hola, JULIO38, como te dije anteriormente no uso PICBASIC, lo que si te digo que parece bastante dificil que este circuito sea estable, como me lo muestras, aca en Argentina el HT9200 serial cuesta u$s 0,73 por lo que yo no justifico gastar una linea de programa e generar tonos con el micro, me parece raro que en España donde tu estas no lo consigas, pero bueno todo es posible.
Como solucion a tu problema, puedes usar tal vez la rutina que hay en
www.microchip.com, que funciona en cualquier microcontrolador PIC, pero usa 7 pines del micro, y esta en ASM, cualquier compilador permite insertar ASM, por lo que no seria dificil usar esta rutina dentro de tu programa PICBASIC, y si te puedo decir que es la solucion pues en una oportunidad, utilize este metodo y funciona perfectamente, aca te pego el codigo, pero si bajas la nota de aplicacion ahi vas a ver el circuito, ademas no se si te va a servir pues no se si dispones de esa cantidad de pines, el codigo es para el 16C54 deberas redireccionar la ram para el 16F876
espero te ayude, saludos.
; Filename: DTMF.ASM
; **********************************************
; * Author: John Day *
; * Sr. Field Applications Engineer *
; * Microchip Technology *
; * Revision: 1.1 *
; * Date December 20, 1995 *
; * Part: PIC16C54 *
; * Compiled using MPASM V1.40 *
; **********************************************
; * Include files: *
; * NONE (used by DTMF.ASM) *
; **********************************************
; * Fuses: OSC: XT (3.579545 Mhz xtal) *
; * WDT: OFF *
; * CP: OFF *
; ****************************************************************************
; * This program uses and external R2R ladder network to generate complete *
; * DTMF dial tones used for telphone dialing. *
; ****************************************************************************
; * Program Memory: *
; * 220 Words - sine wave look-up table (7 sine waves total) *
; * 25 Words - keypad sine address matrix look-up *
; * 37 Words - DTMF sine wave base initialization/generation *
; * 3 Words - Initialization *
; * 25 Words - Test sample code *
; * RAM Memory: *
; * 8 Bytes *
; ****************************************************************************
list p=16C54, r=dec
#include <p16c5x.inc>
__CONFIG _XT_OSC&_WDT_OFF&_CP_OFF
WAVEABASE EQU 10h ; Base address of sine A waveform
POINTERA EQU 11h ; Pointer to current position in sine A
WAVEBBASE EQU 12h ; Base address of sine B waveform
POINTERB EQU 13h ; Pointer to current position in sine B
NEXTVALUE EQU 14h ; Sum register to store Sine A + Sine B
SINECOUNT EQU 15h ; LSB counter for time to output DTMF
SINECOUNTH EQU 16h ; MSB counter for time to output DTMF
TEMP EQU 17h ; Temporary storage
ENDSINE EQU .127 ; Value to show the end of a sine table
; ****************************************************************************
; * sinelookup *
; * This is the look-up table for the (4 X 3) keypad matrix sine wave table. *
; * There are (7) sine waves stored here and adding any two from the *
; * matrix will product a DTMF signal for the appropriate key *
; * Crystal Frequency: 3.579545 Mhz *
; * Instructions/Loop: 35 *
; * Base Frequency: 1209 1336 1477 697 770 852 941 Hz *
; * Actual Frequency: 1217 1345 1475 691 774 852 946 Hz *
; * Error 0.7 0.7 -0.1 -0.9 0.5 0 0.5 % *
; * Num Table Entries: 21 19 52 37 33 30 27 *
; * Total Table Entries: 219 *
; * Program Memory: *
; * 220 Words - Used for (7) sine look-up entries *
; * RAM Memory: *
; * NONE - Look-up table only *
; ****************************************************************************
sinelookup ; Used as address lable to call look-up table
addwf PCL,F ; Add sine offset to PC to jump into table
sineoffset ; Used to calculate offset value address
sinerow1 ; Address for sine wave in row 1
retlw 149
retlw 170
retlw 190
retlw 208
retlw 224
retlw 236
retlw 246
retlw 253
retlw 255
retlw 254
retlw 250
retlw 242
retlw 230
retlw 216
retlw 199
retlw 180
retlw 160
retlw 138
retlw 117
retlw 95
retlw 75
retlw 56
retlw 39
retlw 25
retlw 13
retlw 5
retlw 1
retlw 0
retlw 2
retlw 9
retlw 19
retlw 31
retlw 47
retlw 65
retlw 85
retlw 106
retlw 127 ; End of this sine wave
sinerow2 ; Address for sine wave in row 2
retlw 152
retlw 175
retlw 197
retlw 216
retlw 232
retlw 244
retlw 252
retlw 255
retlw 254
retlw 248
retlw 238
retlw 224
retlw 207
retlw 186
retlw 164
retlw 140
retlw 115
retlw 91
retlw 69
retlw 48
retlw 31
retlw 17
retlw 7
retlw 1
retlw 0
retlw 3
retlw 11
retlw 23
retlw 39
retlw 58
retlw 80
retlw 103
retlw 127 ; End of this sine wave
sinerow3 ; Address for sine wave in row 3
retlw 154
retlw 180
retlw 203
retlw 223
retlw 238
retlw 249
retlw 255
retlw 255
retlw 249
retlw 238
retlw 223
retlw 203
retlw 180
retlw 154
retlw 128
retlw 101
retlw 75
retlw 52
retlw 32
retlw 17
retlw 6
retlw 0
retlw 0
retlw 6
retlw 17
retlw 32
retlw 52
retlw 75
retlw 101
retlw 127 ; End of this sine wave
sinerow4 ; Address for sine wave in row 4
retlw 157
retlw 185
retlw 210
retlw 230
retlw 245
retlw 254
retlw 255
retlw 250
retlw 238
retlw 221
retlw 198
retlw 171
retlw 142
retlw 113
retlw 84
retlw 57
retlw 34
retlw 17
retlw 5
retlw 0
retlw 1
retlw 10
retlw 25
retlw 45
retlw 70
retlw 98
retlw 127 ; End of this sine wave
sinecolumna ; Address for sine wave in column A
retlw 165
retlw 200
retlw 228
retlw 247
retlw 255
retlw 252
retlw 238
retlw 215
retlw 183
retlw 147
retlw 108
retlw 72
retlw 40
retlw 17
retlw 3
retlw 0
retlw 8
retlw 27
retlw 55
retlw 90
retlw 127 ; End of this sine wave
sinecolumnb ; Address for sine wave in column B
retlw 169
retlw 206
retlw 235
retlw 252
retlw 255
retlw 245
retlw 222
retlw 188
retlw 149
retlw 106
retlw 67
retlw 33
retlw 10
retlw 0
retlw 3
retlw 20
retlw 49
retlw 86
retlw 127 ; End of this sine wave
sinecolumnc ; Address for sine wave in column C (double sine wave)
retlw 173
retlw 212
retlw 241
retlw 255
retlw 252
retlw 233
retlw 200
retlw 158
retlw 112
retlw 68
retlw 32
retlw 8
retlw 0
retlw 8
retlw 32
retlw 68
retlw 112
retlw 158
retlw 200
retlw 233
retlw 252
retlw 255
retlw 241
retlw 212
retlw 173
retlw 128
retlw 82
retlw 43
retlw 14
retlw 0
retlw 3
retlw 22
retlw 55
retlw 97
retlw 143
retlw 187
retlw 223
retlw 247
retlw 255
retlw 247
retlw 223
retlw 187
retlw 143
retlw 97
retlw 55
retlw 22
retlw 3
retlw 0
retlw 14
retlw 43
retlw 82
retlw 127 ; End of this sine wave
; *****************************************************************************
; * sineaddress *
; * This subroutine is used to calculate actual address in the sinelookup *
; * table for two DTMF waveforms. It is only called by setdtmfbase. W *
; * is loaded with the key number and this routine returns the sinelookup *
; * address the sine waves. *
; * RAM used: W *
; * PROGRAM MEM: 25 Words *
; *****************************************************************************
sineaddress ; Look-up table for sine address
addwf PCL,F ; Add to PC to jump into table
keyoffset
k1 retlw sinerow1-sineoffset ; Offset for Row 1 sine wave
retlw sinecolumna-sineoffset ; Offset for Column A sine wave
k2 retlw sinerow1-sineoffset ; Offset for Row 1 sine wave
retlw sinecolumnb-sineoffset ; Offset for Column A sine wave
k3 retlw sinerow1-sineoffset ; Offset for Row 1 sine wave
retlw sinecolumnc-sineoffset ; Offset for Column A sine wave
k4 retlw sinerow2-sineoffset ; Offset for Row 2 sine wave
retlw sinecolumna-sineoffset ; Offset for Column A sine wave
k5 retlw sinerow2-sineoffset ; Offset for Row 2 sine wave
retlw sinecolumnb-sineoffset ; Offset for Column B sine wave
k6 retlw sinerow2-sineoffset ; Offset for Row 2 sine wave
retlw sinecolumnc-sineoffset ; Offset for Column B sine wave
k7 retlw sinerow3-sineoffset ; Offset for Row 3 sine wave
retlw sinecolumna-sineoffset ; Offset for Column B sine wave
k8 retlw sinerow3-sineoffset ; Offset for Row 3 sine wave
retlw sinecolumnb-sineoffset ; Offset for Column B sine wave
k9 retlw sinerow3-sineoffset ; Offset for Row 3 sine wave
retlw sinecolumnc-sineoffset ; Offset for Column C sine wave
k10 retlw sinerow4-sineoffset ; Offset for Row 4 sine wave
retlw sinecolumna-sineoffset ; Offset for Column C sine wave
k11 retlw sinerow4-sineoffset ; Offset for Row 4 sine wave
retlw sinecolumnb-sineoffset ; Offset for Column C sine wave
k12 retlw sinerow4-sineoffset ; Offset for Row 4 sine wave
retlw sinecolumnc-sineoffset ; Offset for Column C sine wave
key1=k1-keyoffset ; Calculation for sine addr for keypad 1
key2=k2-keyoffset ; Calculation for sine addr for keypad 2
key3=k3-keyoffset ; Calculation for sine addr for keypad 3
key4=k4-keyoffset ; Calculation for sine addr for keypad 4
key5=k5-keyoffset ; Calculation for sine addr for keypad 5
key6=k6-keyoffset ; Calculation for sine addr for keypad 6
key7=k7-keyoffset ; Calculation for sine addr for keypad 7
key8=k8-keyoffset ; Calculation for sine addr for keypad 8
key9=k9-keyoffset ; Calculation for sine addr for keypad 9
keystar=k10-keyoffset ; Calculation for sine addr for keypad *
key0=k11-keyoffset ; Calculation for sine addr for keypad 0
keypound=k12-keyoffset ; Calculation for sine addr for keypad #
; *****************************************************************************
; * senddtmf *
; * This subroutine is used to calculate the offset address for *
; * the two sine waves to be sent and initialize the WAVEABASE and WABEBBASE *
; * file registers. The key number (key0 - key9 or keystar or keypound) is *
; * loaded into W before this routine is called. Next, the DTMF for that *
; * key is sent to the R2R ladder through portB for 320 mS *
; * Example: *
; * movlw key1 *
; * call senddtmf *
; * RAM used: 8 bytes *
; * PROGRAM MEM: 37 Words *
; *****************************************************************************
senddtmf
movwf TEMP ; Initialize temp with key number
call sineaddress ; Get the address for sine wave a for this key
movwf WAVEABASE ; Initialize sine wave A base address
swapf WAVEABASE,F ; swap WAVEABASE so that Z bit is not effected
movwf POINTERA ; Initialize sine wave A pointer address
incf TEMP,W ; Now we get the second sine wave address...
call sineaddress ; Get the address for sine wave b for this key
movwf WAVEBBASE ; Initialize sine wave B base address
swapf WAVEBBASE,F ; swap WAVEBBASE so that Z bit is not effected
movwf POINTERB ; Initialize sine wave B pointer address
movlw 20h ; Place 32 decimal into W for loop counter
movwf SINECOUNTH ; Initialize loop counter to 20
loopsine2cyc
goto loopsine ; Waste two cycles to maintain 35 cycle loop count
loopsine
movf POINTERA,W ; Place sine wave address into W
call sinelookup ; Look-up first sine wave
movwf NEXTVALUE ; Place first sine wave into NEXTVALUE
xorlw ENDSINE ; Update Z bit
swapf WAVEABASE,W ; Restore to beginning of sine wave
btfsc STATUS,Z ; Skip if not at end of sine wave
movwf POINTERA ; Restore start address if at end of sine
incf POINTERA,F ; Move to the next place in the wave
movf POINTERB,W ; Place sine wave address into W
call sinelookup ; Look-up second sine wave
addwf NEXTVALUE,F ; Add second sine wave into NEXTVALUE
xorlw ENDSINE ; Update Z bit
swapf WAVEBBASE,W ; Pointer of sine wave beginneing -> W
btfsc STATUS,Z ; Skip if not at end of sine wave
movwf POINTERB ; Restore start address if at end of sine
incf POINTERB,F ; Move to next place in the wave
rrf NEXTVALUE,W ; Divide by 2, Place output into PORTB
movwf PORTB ; Update PORTB with new R2R value
goto waste2cyc ; Waste (2) cycles for 35 total
waste2cyc
decfsz SINECOUNT,F ; Skip if we are done
goto loopsine2cyc ; Do it again! (add 2 cycles as well)
decfsz SINECOUNTH,F ; Skip if we are done
goto loopsine ; Do it again!
retlw 0 ; Return from sine output
; *****************************************************************************
; * init *
; * This code is used to initialize the PIC. PORTB is set to zero and all *
; * pins are set to outputs *
; * RAM used: 0 bytes *
; * PROGRAM MEM: 3 Words *
; *****************************************************************************
init
clrf PORTB ; Init output latches for port B to 0
clrw ; Clear W register
tris PORTB ; Set all of PORT B to outputs
; *****************************************************************************
; * testallkeys *
; * This code is used to test all possible keys in the keypad. First each *
; * key address is loaded and then senddtmf is called. *
; * RAM used: 0 bytes *
; * PROGRAM MEM: 25 Words *
; *****************************************************************************
testallkeys
movlw key1 ; Place key "1" address into W
call senddtmf ; Transmit DTMF tone for this key
movlw key2 ; Place key "2" address into W
call senddtmf ; Transmit DTMF tone for this key
movlw key3 ; Place key "3" address into W
call senddtmf ; Transmit DTMF tone for this key
movlw key4 ; Place key "4" address into W
call senddtmf ; Transmit DTMF tone for this key
movlw key5 ; Place key "5" address into W
call senddtmf ; Transmit DTMF tone for this key
movlw key6 ; Place key "6" address into W
call senddtmf ; Transmit DTMF tone for this key
movlw key7 ; Place key "7" address into W
call senddtmf ; Transmit DTMF tone for this key
movlw key8 ; Place key "8" address into W
call senddtmf ; Transmit DTMF tone for this key
movlw key9 ; Place key "9" address into W
call senddtmf ; Transmit DTMF tone for this key
movlw keystar ; Place key "*" address into W
call senddtmf ; Transmit DTMF tone for this key
movlw key0 ; Place key "0" address into W
call senddtmf ; Transmit DTMF tone for this key
movlw keypound ; Place key "#" address into W
call senddtmf ; Transmit DTMF tone for this key
goto testallkeys ; jump back and do it again!
resetvector
ORG 1ffh ; The RESET vector of a 54 is at 1FFh
goto init ; Jump to initialion routine
END