Tonos DTMF con pic 16F88

(1/1)

redk292:
Hace algo mas de un mes, me han dejado de trabajo en la U, el diseño de un simulador de tonos DTMF, para esto se debe tener en cuenta los siguientes requisitos :titanic:
1- Diseñar un generador de tonos DTMF que mediante un teclado 4x4 imprima en LCD 16x2 en numero seleccionado y genere mediante algun sistema, el tono respectivo.
2- Generar el codigo en C compiler o MikroC.
3- Habilitar la comunicacion con otro pic 16F88 que a 1.10 mt de distancia imprima en pantalla LCD el numero digitado.
4- El segundo pic debe tener el codigo en Assembler.

Ahora hasta el momento lo que he conseguido es que la LCD se reciba por puerto A desabilitando el MCLR para conectar el enable, las instrucciones de cambio de pines en la LCD son tomadas de la Revista Ucontrol 2 :rolleyes2:, tambien encontre la configuracion de teclado 4x4 en un solo pin que puedo utilizar el A4.

Para la salida de tonos encontre como realizar la generacion por PWM por el puerto B, lo que me parece interesante ya que me queda libre el campo de comunicacion RS232.

Ahora el codigo que tengo en C compiler, porque en MikroC cambia la declaracion de unas variables constantes e incluso tengo conflicto con unas instrucciones. :pared

Código:

#include <16f88.h>
#use delay(clock=8000000)
#fuses nowdt,noput,nobrownout,nolvp,noprotect,INTRC_IO, nomclr

#define use_portb_lcd TRUE
#use rs232(baud=9600,parity=N,xmit=PIN_B5,rcv=PIN_B2,bits=8)

// Baud= velocidad de tx, Parity permite utilizar 1 bit de paridad para
// comprobar errores,

#use standard_io(a)
#use standard_io(b)

#define LCD_DATA_PORT getenv("SFR:PORTA")
#define LCD_E      PIN_A4
#define LCD_RS     PIN_A6
#define LCD_RW     PIN_A7
#define LCD_DB4    PIN_A0
#define LCD_DB5    PIN_A1
#define LCD_DB6    PIN_A2
#define LCD_DB7    PIN_A3
#include <lcd.c>

#define _Tecl4x4.c
#define Teclado_B0   PIN_A0
#define Teclado_B1   PIN_A1
#define Teclado_B2   PIN_A2
#define Teclado_B3   PIN_A3
#define Teclado_B4   PIN_A4
#define Teclado_B5   PIN_A5
#define Teclado_B6   PIN_A6
#define Teclado_B7   PIN_A7
#include <Tecl4x4.c>


int wave=0;
char a;


/*void main (void)
{
 setup_oscillator(OSC_8MHZ|OSC_INTRC);
 
  while(true)
        {

         a = getc();

         if(a == '2')

         putc('H');

         }
} */
/* -----------------------------------------------------------------------------
                            F_Low F_High  TONE HM9270_Q4 Q3 Q2 Q1  Hex_from_HM9270
                                                  pin_A3 A2 A1 A0   PORTA & 0x0F
----------------------------------------------------------------------------- */
#define  TONE_1    0x01  // 697   1209     1        0    0  0  1          1
#define  TONE_2    0x02  // 697   1336     2        0    0  1  0          2
#define  TONE_3    0x03  // 697   1477     3        0    0  1  1          3
#define  TONE_4    0x04  // 770   1209     4        0    1  0  0          4
#define  TONE_5    0x05  // 770   1336     5        0    1  0  1          5
#define  TONE_6    0x06  // 770   1477     6        0    1  1  0          6
#define  TONE_7    0x07  // 852   1209     7        0    1  1  1          7
#define  TONE_8    0x08  // 852   1336     8        1    0  0  0          8
#define  TONE_9    0x09  // 852   1477     9        1    0  0  1          9
#define  TONE_0    0x0A  // 941   1336     0        1    0  1  0          a
#define  TONE_mi   0x0B  // 941   1209     *        1    0  1  1          b
#define  TONE_pa   0x0C  // 941   1477     #        1    1  0  0          c
#define  TONE_A    0x0D  // 697   1633     A        1    1  0  1          d
#define  TONE_B    0x0E  // 770   1633     B        1    1  1  0          e
#define  TONE_C    0x0F  // 852   1633     C        1    1  1  1          f
#define  TONE_D    0x00  // 941   1633     D        0    0  0  0          0
// -----------------------------------------------------------------------------

CONST unsigned int SINE_WAVE_HIGH[256] = //Onda seno amplitud range : 8 ~ 248
   {
      128,131,134,137,140,143,146,149,151,154,157,160,163,166,168,
      171,174,177,179,182,185,187,190,192,195,197,199,202,204,206,
      209,211,213,215,217,219,221,223,224,226,228,229,231,232,234,
      235,236,238,239,240,241,242,243,244,244,245,246,246,247,247,
      247,248,248,248,248,248,248,248,247,247,247,246,246,245,244,
      244,243,242,241,240,239,238,236,235,234,232,231,229,228,226,
      224,223,221,219,217,215,213,211,209,206,204,202,199,197,195,
      192,190,187,185,182,179,177,174,171,168,166,163,160,157,154,
      151,149,146,143,140,137,134,131,128,125,122,119,116,113,110,
      107,105,102, 99, 96, 93, 90, 88, 85, 82, 79, 77, 74, 71, 69,
       66, 64, 61, 59, 57, 54, 52, 50, 47, 45, 43, 41, 39, 37, 35,
       33, 32, 30, 28, 27, 25, 24, 22, 21, 20, 18, 17, 16, 15, 14,
       13, 12, 12, 11, 10, 10,  9,  9,  9,  8,  8,  8,  8,  8,  8,
        8,  9,  9,  9, 10, 10, 11, 12, 12, 13, 14, 15, 16, 17, 18,
       20, 21, 22, 24, 25, 27, 28, 30, 32, 33, 35, 37, 39, 41, 43,
       45, 47, 50, 52, 54, 57, 59, 61, 64, 66, 69, 71, 74, 77, 79,
       82, 85, 88, 90, 93, 96, 99,102,105,107,110,113,116,119,122,
      125
   };

CONST unsigned int SINE_WAVE_LOW[256] = // Onda seno amplitud range : 43 ~ 213
   {
      128,130,132,134,136,138,140,143,145,147,149,151,153,155,157,
      159,161,162,164,166,168,170,172,173,175,177,179,180,182,184,
      185,187,188,190,191,192,194,195,196,197,199,200,201,202,203,
      204,205,206,207,207,208,209,209,210,210,211,211,212,212,212,
      213,213,213,213,213,213,213,213,213,212,212,212,211,211,210,
      210,209,209,208,207,207,206,205,204,203,202,201,200,199,197,
      196,195,194,192,191,190,188,187,185,184,182,180,179,177,175,
      173,172,170,168,166,164,162,161,159,157,155,153,151,149,147,
      145,143,140,138,136,134,132,130,128,126,124,122,120,118,116,
      113,111,109,107,105,103,101, 99, 97, 95, 94, 92, 90, 88, 86,
       84, 83, 81, 79, 77, 76, 74, 72, 71, 69, 68, 66, 65, 64, 62,
       61, 60, 59, 57, 56, 55, 54, 53, 52, 51, 50, 49, 49, 48, 47,
       47, 46, 46, 45, 45, 44, 44, 44, 43, 43, 43, 43, 43, 43, 43,
       43, 43, 44, 44, 44, 45, 45, 46, 46, 47, 47, 48, 49, 49, 50,
       51, 52, 53, 54, 55, 56, 57, 59, 60, 61, 62, 64, 65, 66, 68,
       69, 71, 72, 74, 76, 77, 79, 81, 83, 84, 86, 88, 90, 92, 94,
       95, 97, 99,101,103,105,107,109,111,113,116,118,120,122,124,
      126
   };

int8 index1,index2,inc1,inc2;

#INT_RTCC
void wave_generator()
{
   int16 wave;

   set_rtcc(25);           // when clock is 20MHz, interrupts every 100us

   wave   = SINE_WAVE_LOW[index1];
   wave  += SINE_WAVE_HIGH[index2];
   wave >>= 1;
   output_b(wave);

   index1 += inc1;  
   index2 += inc2;
   if(index1 >= 256)  index1 -= 256;
   if(index2 >= 256)  index2 -= 256;
}

#define DTMF_ROW1   18  //18 for  697 Hz, increment this many times every 100us
#define DTMF_ROW2   20  //20 for  770 Hz,                     for SIN_WAVE[256]
#define DTMF_ROW3   22  //22 for  852 Hz,
#define DTMF_ROW4   24  //24 for  941 Hz,

#define DTMF_COLA   32  //32 for 1209 Hz,
#define DTMF_COLB   35  //34 for 1336 Hz,  
#define DTMF_COLC   38  //38 for 1477 Hz,
#define DTMF_COLD   43  //42 for 1633 Hz,

void generate_dtmf_tone(int8 keypad, long duration)  {

   index1=0;   index2=0;  inc1=0;   inc2=0;

   if     ((keypad== 1)||(keypad== 2)||(keypad== 3)||(keypad==13)) inc1=DTMF_ROW1;
   else if((keypad== 4)||(keypad== 5)||(keypad== 6)||(keypad==14)) inc1=DTMF_ROW2;
   else if((keypad== 7)||(keypad== 8)||(keypad== 9)||(keypad==15)) inc1=DTMF_ROW3;
   else if((keypad==11)||(keypad==10)||(keypad==12)||(keypad== 0)) inc1=DTMF_ROW4;

   if     ((keypad== 1)||(keypad== 4)||(keypad== 7)||(keypad==11)) inc2=DTMF_COLA;
   else if((keypad== 2)||(keypad== 5)||(keypad== 8)||(keypad==10)) inc2=DTMF_COLB;
   else if((keypad== 3)||(keypad== 6)||(keypad== 9)||(keypad==12)) inc2=DTMF_COLC;
   else if((keypad==13)||(keypad==14)||(keypad==15)||(keypad== 0)) inc2=DTMF_COLD;

   setup_counters(RTCC_INTERNAL,RTCC_DIV_2);
   enable_interrupts(INT_RTCC);

   enable_interrupts(GLOBAL);    

   while ( duration-- > 0 )  delay_us(1000);

   disable_interrupts(INT_RTCC);
   output_b(0);
}
void main()  
{
   char k=0,tecla;
   INT tec=0;
   setup_oscillator(OSC_8MHZ|OSC_INTRC);
   lcd_init();
   DELAY_MS(100);
   //SETUP_ADC_PORTS( NO_ANALOGS );  //CONFIGURA ENTRADAS ANALOGAS (PORTA-> ANALOG)
   setup_adc_ports(san4);
   SETUP_ADC(ADC_CLOCK_INTERNAL);//DEFINICION DE FRECUENCIA DE OPERACION
   SET_ADC_CHANNEL(4);           //SELECCION DE CANAL 0 PARA CONVERSION A/D
  lcd_putc("TONOS ");
  lcd_gotoxy(1,2);
  lcd_putc("NUM: ");
   delay_us(100);

   while(TRUE)
   {
      tec=read_ADC();
      delay_ms(50);
      if(tec>=0 && tec<164)
      {
      k='6';
      }
      if(tec>=164 && tec<174)
      {
      + k='3';
      }
      if(tec>=174 && tec<180)
      {
      k='#';
      }
      if(tec>=180 && tec<184)
      {
      k='7';
      }
      if(tec>=184 && tec<188)
      {
      k='9';
      }
      if(tec>=188 && tec<194)
      {
      k='2';
      }
      if(tec>=194 && tec<201)
      {
      k='0';
      }
      if(tec>=201 && tec<208)
      {
      k='8';
      }
      if(tec>=208 && tec<215)
      {
      k='5';
      }
      if(tec>=215 && tec<220)
      k='1';
      }
      if(tec>=220 && tec<224)
      {
      k='*';
      }
      if(tec>=224 && tec<235)
      {
      k='4';
      }
      if(tec>=235 && tec<242)
      {
      k='#';
      }
      tecla=k;
      if(tec>=242)
      {
      k=0;
      }
      if(tecla!=0)
      {
      generate_dtmf_tone(tecla, 20);
      lcd_putc(tecla);
      }
}  
      #INT_RTCC
void wave_generator()
 :cabron
Claro que esta instruccion inicial de key es para un teclado matricial de 4x3. pero ya estoy trabajando en la  4x4.

Agradesco toda la ayuda que me puedan suministrar, y en estos dias dejo la imagen del montaje que realizo en Proteus 7

redk292:
Las caritas con gafas son "8" pero salieron asi.

HJ:
Los tonos DTMF los tenes que generar y decodificar con los micros, o podes utilizar algún integrado como el MT8880?

Con ese integrado la generación y detección de tonos DTMF es muy simple.

Saludos

Navegación

[0] Índice de Mensajes