Melodias en tonos con PICs

Estoy diseñando un programa en PIC C que me genere una melodia, con frecuencias por medio de un PIC, en especifico el 16F877A, soy novato y ya logre generar dos tonos segidos, pero mi problema es que no le puedo dar tiempo a estos tonos, me explico quiero que el primer tono dure 1 seg. y el otro 2 seg. pongo el codico que tengo hasta ahora y el montaje en proteus por si les interersa, ademas tengo PROHIBIDO usar la libreria TONES, si me pueden ayudar les agradesco.

Código:
#include <16F877A.h>
//#device adc=8

#FUSES NOWDT                    //No Watch Dog Timer
#FUSES XT                       //Crystal osc <= 4mhz
#FUSES PUT                      //Power Up Timer
#FUSES NOPROTECT                //Code not protected from reading
#FUSES NODEBUG                  //No Debug mode for ICD
#FUSES BROWNOUT                 //Reset when brownout detected
#FUSES NOLVP                    //No low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O
#FUSES NOCPD                    //No EE protection
#FUSES NOWRT                    //Program memory not write protected


#use delay(clock=4000000)

#use fast_io(B)
#use fast_io(C)
#define Speaker   PIN_B0      // Altavoz conectado a RB0  

void main(){
   
   set_tris_b(2); // RB<7:2> Salida RB1 entrada (Pulsador) RB0 Salida (Speaker)
   
   do{                              // Bucle infinito
      
      while(!input(PIN_B1)){         // Mientras se presione el
                                    // interruptor conectado a RB1.
                                    
       int i;                              // contador
  output_low(pin_B0);       // inicializo la salida del puerto donde esta el speaker a "0"

  for (i=0; i<255 ;i++)       // ciclo de generacion de señal periodica de periodo descrito + adelante
     {
     output_high(pin_B0);   //semiciclo en "1" logico
     delay_us(500);           // mantener el "1" por 500 microsegundos
     output_low(pin_B0);    //semiciclo en "0" logico
     delay_us(500);           // mantener el "0" por 500 microsegundos
     }                               //Fin de UN periodo de la señal
     delay_ms(300);          //esperar unos 0,3 segundos antes de generar el otro tono

  for (i=0;i<255;i++)       // Otro tono, igual al anterior
     {
     output_high(pin_B0);
     delay_us(500);
     output_low(pin_B0);
     delay_us(500);
  }
  delay_ms(200);
}
       
         
     
         
      }while(true);
}
 

Adjuntos

  • tonos.jpg
    tonos.jpg
    114.7 KB · Visitas: 44
  • tonos.txt
    2 KB · Visitas: 38
Hola diegomen93

Te estoy adjuntando unos documentos y una simulación en ISIS de Proteus. Espero te sirva.

saludos
a sus ordenes
 

Adjuntos

  • Sound.zip
    372.7 KB · Visitas: 85
Este ejemplo te puede servir
Código:
#include <16f876a.h>

#use delay(clock=4000000)
#use fast_io (b)

#fuses HS
#FUSES NOPUT
#FUSES NOBROWNOUT

#define Speaker   PIN_B0

#define nDO     0    // DO
#define nDO_    1    // DO#
#define nRE     2    // RE
#define nRE_    3    // RE#
#define nMI     4    // MI
#define nFA     5    // FA
#define nFA_    6    // FA#
#define nSOL    7    // SOL
#define nSOL_   8    // SOL#
#define nLA     9    // LA
#define nLA_    10   // LA#
#define nSI     11   // SI

int16 FreqNota[12]={  // retardos entre estado alto y bajo para generar las notas
15289, // DO
14430, // DO#
13620, // RE
12856, // RE#
12134, // MI
11453, // FA
10810, // FA#
10204, // SOL
9631,  // SOL#
9090,  // LA
8580,  // LA#
8099   // SI
};


void Play(int nota,int octava,int16 duracion);
void PlayCancion(int cancion);

void main(){
 
  set_tris_b(14);      // B<;3:1>;: Pulsadores B0: Speaker
 
  while (true){
     if(input(PIN_B1))PlayCancion(1); //Si pulso switch 1 toca Pop Corn
     if(input(PIN_B2))PlayCancion(2); //Si pulso switch 2 toca Ecuador
     if(input(PIN_B3))PlayCancion(3); //Si pulso switch 3 toca The lion sleep tonight
  }

}

void Play(int nota, int octava, int16 duracion){
     int16 fn;
     int16 mS_Transcurridos=0;
     int16 CiclosL=0;
    
     fn=FreqNota[nota];         // Define los retardos para generar
                                // la frecuencia de cada nota
     fn>>=(octava);             // Adapta la frecuencia a la octava actual
   
    do{
       
        output_high(Speaker);   // Genera la frecuancia
        delay_us(fn);           // con los retardos mientras
        CiclosL+=(fn);          // aumenta el contador de ciclos transcurridos
        output_low(Speaker);    // en dos partes para repartir el
        delay_us(fn);           // trabajo entre estado alto y bajo.
        CiclosL+=(fn);          //
        CiclosL+=25;            // Compensador.
       
        while(CiclosL>999){     // Se queda en el bucle mientras CiclosL
                                // sea menor a 1000 (1 mS)
           CiclosL-=1000;       // Le resta 1000 a CiclosL
           mS_Transcurridos++;  // y le suma 1 a mS_Transcurridos.
           CiclosL+=25;         // Compensador.
        }
     }while (duracion>mS_Transcurridos); // Repite el bucle hasta que
                                         // haya pasado el tiempo indicado.
    
  
}

void PlayCancion(int cancion){
  switch (cancion){
     case 1:
        //POP CORN
        play (nDO   ,5,166);
        play (nLA_  ,4,166);
        play (nDO   ,5,166);
        play (nSOL  ,4,166);
        play (nRE_  ,4,166);
        play (nSOL  ,4,166);
        play (nDO   ,4,166);
        delay_ms (166);
        play (nDO   ,5,166);
        play (nLA_  ,4,166);
        play (nDO   ,5,166);
        play (nSOL  ,4,166);
        play (nRE_  ,4,166);
        play (nSOL  ,4,166);
        play (nDO   ,4,166);
        delay_ms (166);
        play (nDO   ,5,166);
        play (nRE   ,5,166);
        play (nRE_  ,5,166);
        play (nRE   ,5,166);
        play (nRE_  ,5,166);
        play (nDO   ,5,166);
        play (nRE   ,5,166);
        play (nDO   ,5,166);
        play (nRE   ,5,166);
        play (nLA_  ,4,166);
        play (nDO   ,5,166);
        play (nLA_  ,4,166);
        play (nDO   ,5,166);
        play (nSOL_ ,4,166);
        play (nDO   ,5,166);
     break;
     case 2:  
        //ECUADOR
        play (nLA   ,3,100);
        delay_ms (200);
        play (nMI   ,3,100);
        delay_ms (200);
        play (nDO   ,4,100);
        delay_ms (100);
        play (nSI   ,3,100);
        delay_ms (100);
        play (nRE   ,4,100);
        delay_ms (100);
        play (nSI   ,3,100);
        delay_ms (100);
        play (nSOL  ,3,100);
        delay_ms (100);
        play (nLA   ,3,100);
        delay_ms (200);
        play (nMI   ,3,100);
        delay_ms (200);
        play (nDO   ,4,100);
        delay_ms (100);
        play (nSI   ,3,100);
        delay_ms (100);
        play (nRE   ,4,100);
        delay_ms (100);
        play (nSI   ,3,100);
        delay_ms (100);
        play (nSOL  ,3,100);
        delay_ms (100);
        play (nDO   ,4,100);
        delay_ms (200);
        play (nSOL  ,3,100);
        delay_ms (200);
        play (nMI   ,4,100);
        delay_ms (100);
        play (nRE   ,4,100);
        delay_ms (100);
        play (nMI   ,4,100);
        delay_ms (100);
        play (nRE   ,4,100);
        delay_ms (100);
        play (nSOL  ,3,100);
        delay_ms (100);
        play (nDO   ,4,100);
        delay_ms (200);
        play (nLA   ,3,100);
        delay_ms (200);
        play (nDO   ,4,100);
        delay_ms (100);
        play (nSI   ,3,100);
        delay_ms (100);
        play (nDO   ,4,100);
        delay_ms (100);
        play (nSI   ,3,100);
        delay_ms (100);
        play (nSOL  ,3,100);
     break;
     case 3:
        //The lion sleep tonight
        play (nDO   ,3,125);
        delay_ms (250);
        play (nRE   ,3,125);
        delay_ms (125);
        play (nMI   ,3,125);
        delay_ms (250);
        play (nRE   ,3,125);
        delay_ms (250);
        play (nMI   ,3,125);
        play (nFA   ,3,125);
        delay_ms (250);
        play (nMI   ,3,125);
        delay_ms (125);
        play (nRE   ,3,125);
        delay_ms (250);
        play (nDO   ,3,125);
        delay_ms (250);
        play (nRE   ,3,125);
        play (nMI   ,3,125);
        delay_ms (250);
        play (nRE   ,3,125);
        delay_ms (125);
        play (nDO   ,3,125);
        delay_ms (250);
        delay_ms (125);
        play (nMI   ,3,125);
        delay_ms (125);
        play (nRE   ,3,500);
     break;
  }
}
simulacion proteus
Ver el archivo adjunto tonos con pic.rar
 
Atrás
Arriba