Autor Tema: Notas musicales  (Leído 39714 veces)

0 Usuarios y 1 Visitante están viendo este tema.

Desconectado septiembre_negro

  • PIC18
  • ****
  • Mensajes: 310
Re: Notas musicales
« Respuesta #60 en: 06 de Noviembre de 2009, 16:31:24 »
Muy buena la interfas grafica :-/ :-/ aunque creo que para complicarse menos se podría omitir la parte de la partitura. ya que ciento que es redundante  si partimos del supuesto que ya tenemos la partitura
Saludos

Desconectado micro_cadaver

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 2102
    • blog microembebidos
Re: Notas musicales
« Respuesta #61 en: 06 de Noviembre de 2009, 16:41:46 »
pero si no colocamos la partitura entonces como escribimos la cancion para generar los ritmos y las notas?

Me explico:
El tones.c requiere los siguientes parametros
- tempo: es una propiedad que es una referencia de velocidad que dura un compas (usaremos el 4/4 por ahora), como el pic no puede manejar calculos matematicos complicados, dejaremos configurados algunos valores discretos para seleccionar.
- tono de la nota: si es LA, La sostenido, o RE, etc...
- duracion de la nota: se apoyara en el "tempo", en tonces cada REDONDA dura el tempo (si no es asi corrijanme porfavor), una BLANCA la mitad de la REDONDA, y asi sucesivamente.

Se puede colocar el nombre de las notas tambien, y un sin numero de indicadores para hacer más flexible la escritura de los temas.
« Última modificación: 06 de Noviembre de 2009, 17:11:20 por micro_cadaver »
a cosechar!!!... :P
pic32... ahi voy....
aguante el micro 16f84  !!!!

visita mi pagina: http://www.microembebidos.wordpress.com

Desconectado septiembre_negro

  • PIC18
  • ****
  • Mensajes: 310
Re: Notas musicales
« Respuesta #62 en: 06 de Noviembre de 2009, 17:51:30 »
Mm creo que aquí  tenemos enfocado el problema de manera diferente  como yo lo miro es así.
1.   tengo la partitura en mano (la descargue e imprimí)
2.   por medio del piano grafico boy introduciendo las notas que boy leyendo de la partitura.
3.   el sofwer va generando la matriz de datos producto de ir realizando la conversión de las notas del piano a los valores de la librería notes.c
4.   al indicarle al sof que e terminado  genera un archivo .txt para copiar y pegar al sof del pic.
Entonces  así como yo lo miro esta de mas que el sof me genere gráficamente la partitura que ya tengo.
Aunque tan solo es mi opinión y no tiene que ser como digo ya que no tengo la menor idea si generar la partitura grafica represente mucho problema o  tan solo termine siendo un plus.

Desconectado micro_cadaver

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 2102
    • blog microembebidos
Re: Notas musicales
« Respuesta #63 en: 06 de Noviembre de 2009, 17:59:58 »
ah.... que habias entendido por esa partitura, en realidad lo habia puesto como a manera de pantalla de salida nomas. La verdad ayuda mucho, la secuencia seria asi:

1. tengo la partitura en la mano (la plancha)
2. por medio del piano grafico voy introduciendo las notas, estas se van reflejando en la pantalla superior, donde se puede visualizar sobre una partitura las notas que vamos escribiendo, asi como su duracion (blanca negra corchea etc).
3. una vez q terminamos, le damos a generar archivo *.c

la partitura quedara como un registro de lo que escribistes, porsiacaso necesitas modificarlo algo o transportar tu "arreglo" a otro lugar donde se encuentre otra aplicacion.

que tal asi? vamos dandole forma. saludos  :-/ :-/

PD: MLO no se pronuncia, donde estara...
a cosechar!!!... :P
pic32... ahi voy....
aguante el micro 16f84  !!!!

visita mi pagina: http://www.microembebidos.wordpress.com

Desconectado MLO__

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 4581
Re: Notas musicales
« Respuesta #64 en: 06 de Noviembre de 2009, 20:21:28 »
Aca toy.

Ojo, debe ser la partitura  y no una tablatura  ;-)

El soft deberia identificar el tipo de nota (blanca, negra, etc) y la altura tonal de la misma según la armadura de clave -eso yo lo posteare mas tarde- y de ahi el soft generar el .c que seria un vector con las variables, en si seria un string no?

Saludos
El papel lo aguanta todo

Desconectado micro_cadaver

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 2102
    • blog microembebidos
Re: Notas musicales
« Respuesta #65 en: 07 de Noviembre de 2009, 01:28:34 »
entonces antes de continuar con el soft, algun aporte más, algo que le falte o asi queda?

a cosechar!!!... :P
pic32... ahi voy....
aguante el micro 16f84  !!!!

visita mi pagina: http://www.microembebidos.wordpress.com

Desconectado septiembre_negro

  • PIC18
  • ****
  • Mensajes: 310
Re: Notas musicales
« Respuesta #66 en: 07 de Noviembre de 2009, 17:45:50 »
Pues no, creo qué así como planteas la interfas esta muy bien ahora para quedar claro lo único que el pic es capas de interpretar es; nota, octava, duración de la nota
Adicionalmente se podría agregar el tiempo que dura la pieza me refiero a que la pieza se ejecute mas rápido o mas lento. pero esto hay que trabajarlo por que no lo e conseguido.
Para que quede mas claro lo que el sof debe generar es algo así
Código: [Seleccionar]
#define SIZE 54


const struct note
{
   long tone;
   long length;
}noche_de_paz[SIZE] = {
Fb_note[1],750, Gb_note[1],250,Fb_note[1],500, Db_note[1],500, P_note[1],500,
P_note[1],250, Fb_note[1],750, Gb_note[1],250, Fb_note[1],500, Db_note[1],500,
P_note[1],500, P_note[1],250, Cb_note[2],500, Ab_note[1],750, P_note[1],500,
P_note[1],250, B_note[1],1000, B_note[1],500, Fb_note[1],750, P_note[1],500,
P_note[1],250, Gb_note[1],1000, Gb_note[1],500, B_note[1],750, Ab_note[1],250,
gb_note[1],500, Fb_note[1],750, Gb_note[1],250, Fb_note[1],500, Db_note[1],750,
P_note[1],500, P_note[1],250, Gb_note[1],1000, Gb_note[1],500, B_note[1],750,
A_note[1],250, Gb_note[1],500, Fb_note[1],750, Gb_note[1],250, FB_note[1],500,
D_note[1],750, P_note[1],500, P_note[1],250, Cb_note[2],1000, Cb_note[2],500,
E_note[2],750, Cb_note[2],250, Ab_note[1],500, B_note[1],998, Db_note[2],1000,
P_note[1],500, P_note[1],250, B_note[1],500};


Desconectado principal1414

  • PIC10
  • *
  • Mensajes: 1
Re: Notas musicales
« Respuesta #67 en: 17 de Noviembre de 2013, 18:36:39 »
Pues si gusto eso es lo que pretendo el código rtttl lo recién lo  descubrir pero sigo sin aclararme es posible utilizar este código como referencia para implementarlo con la librería notes del ccs. Me explico
Esto es un código rttl  Simpsons:d=4,o=5,b=160:32p,c.6,e6,f#6,8a6,g.6,e6,c6,8a,8f#,8f#,8f#,2g
Como quedaría si es posible utilizando la librería notes de ccs??
Ahora lo obvio seria utilizar directamente el código rtttl en el pic pero para mi desgracia el ejemplo que encontré utiliza una lógica muy avanzada y lo único que e conseguido es un tremendo dolor de cabeza ya ni siquiera pretendo entenderlo por ahora .
Si esta en la capacidad de alguien entender este ejemplo que habría que hacer para introducir mas melodías, modificar las que ya tiene no implica problema se sustituye el código actual por el de la melodía a y ya estampero lo que pretendo es meter tantas melodías como lo permita la memoria del pic.
Aquí una breve descripción del código rttl

 http://personal.telefonica.terra.es/web/japus/rtplayer_es.html


Y aquí el programa que encontré en los foros del ccs para incrementar el código rtttl desafortunadamente para mi como principiante esta mas que en chino

Código: [Seleccionar]

/*                                                                           */
/*            RTTTL Ring Tone Player for Microchip Microcontrollers          */
/*                                                                           */
/* This program was designed to run on the PICDEM2 Plus demo board from      */
/* Microchip.                                                                */
/*                                                                           */
/* Usage:                                                                    */
/*         S3 - Selects Melody                                               */
/*         S2 - Starts/Stops Melody                                          */
/*                                                                           */
/* This code was designed for a clock speed of 20MHz                         */
/* The target device was a PIC18F452.                                        */
/* You can use the PIC16F877 by changing the setup of CCP1 to                */
/* CCP_COMPARE_INT.  You will also need to toggle the output pin in the      */
/* CCP1 interrupt routine.                                                   */
/*                                                                           */
/* Many of the tunes were downloaded from "www.mrtones.com"                  */
/*****************************************************************************/
#case
#list
#if defined(__PCH__)
  #include "18F452.h"
#else
  #include "16F876.h"
#endif
#device *=16

#define CLOCKSPEED     10000000
#define CCP_COMPARE_TOGGLE_MATCH        2

#use delay(CLOCK=CLOCKSPEED)
#fuses HS, NOWDT, NOLVP, PUT


#define TMR1_PRESCALE  8
#define NOTE_C_SHARP   (((CLOCKSPEED/4)/277.18)/TMR1_PRESCALE)            // 277.18Hz
#define NOTE_D_SHARP   (((CLOCKSPEED/4)/311.13)/TMR1_PRESCALE)            // 311.13 Hz
#define NOTE_F_SHARP   (((CLOCKSPEED/4)/369.99)/TMR1_PRESCALE)            // 369.99 Hz
#define NOTE_G_SHARP   (((CLOCKSPEED/4)/415.30)/TMR1_PRESCALE)            // 415.30 Hz
#define NOTE_A_SHARP   (((CLOCKSPEED/4)/466.16)/TMR1_PRESCALE)            // 466.16 Hz

#define NOTE_C         (((CLOCKSPEED/4)/261.63)/TMR1_PRESCALE)            // 261.63 Hz
#define NOTE_D         (((CLOCKSPEED/4)/293.66)/TMR1_PRESCALE)            // 293.66 Hz
#define NOTE_E         (((CLOCKSPEED/4)/329.63)/TMR1_PRESCALE)            // 329.63 Hz
#define NOTE_F         (((CLOCKSPEED/4)/349.23)/TMR1_PRESCALE)            // 349.23 Hz
#define NOTE_G         (((CLOCKSPEED/4)/392.00)/TMR1_PRESCALE)            // 392.00 Hz
#define NOTE_A         (((CLOCKSPEED/4)/440.00)/TMR1_PRESCALE)            // 440.00 Hz
#define NOTE_B         (((CLOCKSPEED/4)/493.88)/TMR1_PRESCALE)            // 493.88 Hz
#define NOTE_SILENCE   0

#define DURATION_32   5    // Duration = 2^x
#define DURATION_16   4    // Duration = 2^x
#define DURATION_8    3    // Duration = 2^x
#define DURATION_4    2    // Duration = 2^x
#define DURATION_2    1    // Duration = 2^x
#define DURATION_1    0    // Duration = 2^x

typedef enum
{
  SILENTNIGHT,
  JINGLEBELLS,
  LAST_MELODY
}MELODIES;

typedef struct
{
  int Head;
  int Tail;
  int Count;
} NOTESTAT;

typedef struct
{
  long note;
  long duration;
}NOTE_DEF;


struct
{
  int TRISC0:1;
  int TRISC1:1;
  int TRISC2:1;
  int TRISC3:1;
  int TRISC4:1;
  int TRISC5:1;
  int TRISC6:1;
  int TRISC7:1;
}TRISCbits;
#if defined(__PCH__)
  #locate TRISCbits = 0xF94
#else
  #locate TRISCbits = 0x87
#endif

long TMR1;
#if defined(__PCH__)
  #locate TMR1 = 0xFCE
#else
  #locate TMR1 = 0x0E
#endif

int TMR1L;
#if defined(__PCH__)
  #locate TMR1L = 0xFCE
#else
  #locate TMR1L = 0x0E
#endif

int TMR1H;
#if defined(__PCH__)
  #locate TMR1H = 0xFCF
#else
  #locate TMR1H = 0x0F
#endif

int TMR0;
#if defined(__PCH__)
  #locate TMR0 = 0xFD6
#else
  #locate TMR0 = 0x01
#endif

#define   MAX_NOTE_BUFFER_SIZE  4
#define   NOTE_ROLLOVER_MASK     0b00000011
NOTE_DEF  NoteBuffer[MAX_NOTE_BUFFER_SIZE];
NOTESTAT  Notestat = {0,0,0};

long      DurationCount=0;
int       Tempo=0;
long      Note_Ticks=0;
MELODIES  Melody_Pointer;
long      Note_Index = 0xFFFF;
BOOLEAN   PlayMelodyFlag = TRUE;


const struct
{
  char tune1[128];
  char tune2[65];
  int  defaultoctave;
  int  defaultduration;
  int  tempo;
}SilentNight = {
                 {"f#.,8g#,f#,d#.,p.,f#.,8g#,f#,d#.,p.,2c#6,c#6,a#.,p.,2b,b,f#.,p.,2g#,g#,b.,8a#,g#,f#.,8g#,f#,d#.,p.,2g#,g#,b.,8a#,g#,f#.,8g#,f#,"},{"d#.,p.,2c#6,c#6,e.6,8c#6,a#,2b.,2d#6,p.,b,f#,d#,f#.,8e,c#,b.4,1p"},
                 5,
                 DURATION_4,
                 140
               };
const struct
{
  char tune1[128];
  char tune2[75];
  int  defaultoctave;
  int  defaultduration;
  int  tempo;
}JingleBells = {
                 {"8e.,8e.,e.,8e.,8e.,e.,8e.,8g.,c,16d.,2e,p,8f.,8f.,f,16f.,8f.,8e.,8e.,16e.,16e.,8e.,8d.,8d.,8e.,d.,g.,8e.,8e.,e.,8e.,8e.,e.,8e.,"},{"8g.,c,16d.,2e,p,8f.,8f.,f,16f.,8f.,8e.,8e.,16e.,16e.,8g.,8g.,8f.,8d.,c.,1p"},
                 5,
                 DURATION_4,
                 180
               };

/* Function Prototypes */
void InitTimer(void);
int PlayMelody();
void PlayNote(long note, int octave, int duration);
char get_char_from_tune(long index);
int get_tempo(void);
int get_defaultoctave(void);
int get_defaultduration(void);
void Melody_Task(void);


//-----------------------------------------------------------------------------
// Start of Code
//-----------------------------------------------------------------------------


/* *************************************************************************
  DESCRIPTION:  This function handles checking for button presses
  RETURN:       none
  ALGORITHM:    none
  NOTES:        none
 *************************************************************************** */
void main(void)
{
  TRISCbits.TRISC2 = 0;
  InitTimer();
  enable_interrupts(GLOBAL);
  Melody_Pointer = JINGLEBELLS;
  while(1)
  {
    Melody_Task();
  }
}

/* *************************************************************************
  DESCRIPTION:  This function handles the playing of a melody
  RETURN:       True if the melody is still active or False if its complete
  ALGORITHM:    none
  NOTES:        none
 *************************************************************************** */
int PlayMelody(void)
{

  int octave = 0;
  int duration = 0;
  long note = 0;

  // Check for a valid Melody
  if (Melody_Pointer >= LAST_MELODY)
  {
    // Reset the Melody to the start
    Melody_Pointer = 0;
    Note_Index = 0xFFFF;
  }

  // Load notes while we have enough room
  while (Notestat.Count < MAX_NOTE_BUFFER_SIZE)
  {

    // Is this the first note?
    if (Note_Index == 0xFFFF)
    {
      Tempo = get_tempo();
      Note_Index = 0;
    }

    // Set Default duration
    duration = get_defaultduration();
    // Set Default Octave
    octave = get_defaultoctave();

    // Play a bit of slience between notes
    if (get_char_from_tune(Note_Index) == ',')
    {
      PlayNote(0, 4, DURATION_32);
      Note_Index++;
      return(TRUE);
    }

    // We are checking the duration
    else if ((get_char_from_tune(Note_Index) == '3') && (get_char_from_tune(Note_Index+1) == '2'))
    {
      duration = DURATION_32;
      Note_Index += 2;
    }
    else if ((get_char_from_tune(Note_Index) == '1') && (get_char_from_tune(Note_Index+1) == '6'))
    {
      duration = DURATION_16;
      Note_Index += 2;
    }
    else if (get_char_from_tune(Note_Index) == '8')
    {
      duration = DURATION_8;
      Note_Index++;
    }
    else if (get_char_from_tune(Note_Index) == '4')
    {
      duration = DURATION_4;
      Note_Index++;
    }
    else if (get_char_from_tune(Note_Index) == '2')
    {
      duration = DURATION_2;
      Note_Index++;
    }
    else if (get_char_from_tune(Note_Index) == '1')
    {
      duration = DURATION_1;
      Note_Index++;
    }

    // Now we get the note
    switch (get_char_from_tune(Note_Index++))
    {
      case 'c':
        if (get_char_from_tune(Note_Index) == '#')
        {
          note = NOTE_C_SHARP;
          Note_Index++;
        }
        else
          note = NOTE_C;
        break;
      case 'd':
        if (get_char_from_tune(Note_Index) == '#')
        {
          note = NOTE_D_SHARP;
          Note_Index++;
        }
        else
          note = NOTE_D;
        break;
      case 'e':
        note = NOTE_E;
        break;
      case 'f':
        if (get_char_from_tune(Note_Index) == '#')
        {
          note = NOTE_F_SHARP;
          Note_Index++;
        }
        else
          note = NOTE_F;
        break;
      case 'g':
        if (get_char_from_tune(Note_Index) == '#')
        {
          note = NOTE_G_SHARP;
          Note_Index++;
        }
        else
          note = NOTE_G;
        break;
      case 'a':
        if (get_char_from_tune(Note_Index) == '#')
        {
          note = NOTE_A_SHARP;
          Note_Index++;
        }
        else
          note = NOTE_A;
        break;
      case 'b':
        note = NOTE_B;
        break;
      case 'p': // slience
        note = NOTE_SILENCE;
        break;
    }

    // See if this note is 1.5x the duration
    if (get_char_from_tune(Note_Index) == '.')
    {
      // Use the MSB to signify 1.5x
      duration |= 0x80;
      Note_Index++;
    }

    // Get the octave
    switch (get_char_from_tune(Note_Index))
    {
      case '4':
        octave = 4;
        Note_Index++;
        break;
      case '5':
        octave = 5;
        Note_Index++;
        break;
      case '6':
        octave = 6;
        Note_Index++;
        break;
      case '7':
        octave = 7;
        Note_Index++;
        break;
      default:
        break;
    }

    // Sometimes the duration multiplier comes after the octave
    if (get_char_from_tune(Note_Index) == '.')
    {
      /* Duration 1.5x */
      duration |= 0x80;
      Note_Index++;
    }

    // Play the note (we actually just load it in a buffer
    PlayNote(note, octave, duration);

    // Is this the end?
    if (get_char_from_tune(Note_Index) == 0)
    {
      Note_Index = 0xFFFF;
      return(FALSE);
    }
  }
  return(TRUE);
}

/* *************************************************************************
  DESCRIPTION:  This function handles checking for button presses
  RETURN:       none
  ALGORITHM:    none
  NOTES:        none
 *************************************************************************** */
void PlayNote(long note, int octave, int duration)
{
  long duration_count;

  // Process octave
  switch (octave)
  {
    case 4 :
      break;
    case 5 :
      note = note >> 1;
      break;
    case 6 :
      note = note >> 2;
      break;
    case 7 :
      note = note >> 4;
      break;
  }

  // Process Note Duration
  duration_count = 256;
  duration_count >>= (duration & 0x7F);

  // If duration is 1.5x add .5 to duration
  if (duration & 0x80)
    duration_count += (duration_count >> 1);

  // Add the note to our buffer
  NoteBuffer[Notestat.Tail].note = note;
  NoteBuffer[Notestat.Tail].duration = duration_count;
  Notestat.Tail++;
  Notestat.Tail &= NOTE_ROLLOVER_MASK;
  Notestat.Count++;
}

/* *************************************************************************
  DESCRIPTION:  This function handles checking for button presses
  RETURN:       none
  ALGORITHM:    none
  NOTES:        none
 *************************************************************************** */
void InitTimer(void)
{
  setup_timer_0(RTCC_DIV_256 | RTCC_8_BIT);
  setup_timer_1(T1_INTERNAL | T1_DIV_BY_8);

  enable_interrupts(INT_CCP1);
  enable_interrupts(INT_TIMER0);
  enable_interrupts(INT_TIMER2);
}


/* *************************************************************************
  DESCRIPTION:  This function handles checking for button presses
  RETURN:       none
  ALGORITHM:    none
  NOTES:        none
 *************************************************************************** */
char get_char_from_tune(long index)
{
  switch (Melody_Pointer)
  {
    case SILENTNIGHT:
      if (index<127)
        return (SilentNight.tune1[index]);
      else
        return (SilentNight.tune2[index-127]);
      break;
    case JINGLEBELLS:
      if (index<127)
        return (JingleBells.tune1[index]);
      else
        return (JingleBells.tune2[index-127]);
      break;
    default:
      break;
  }
}

/* *************************************************************************
  DESCRIPTION:  This function handles checking for button presses
  RETURN:       none
  ALGORITHM:    none
  NOTES:        none
 *************************************************************************** */
int get_tempo(void)
{
  switch (Melody_Pointer)
  {
    case SILENTNIGHT:
      return (SilentNight.tempo);
      break;
    case JINGLEBELLS:
      return (JingleBells.tempo);
      break;
    default:
      break;
  }
}

/* *************************************************************************
  DESCRIPTION:  This function handles checking for button presses
  RETURN:       none
  ALGORITHM:    none
  NOTES:        none
 *************************************************************************** */
int get_defaultoctave(void)
{
  switch (Melody_Pointer)
  {
    case SILENTNIGHT:
      return (SilentNight.defaultoctave);
      break;
    case JINGLEBELLS:
      return (JingleBells.defaultoctave);
      break;
    default:
      break;
  }
}

/* *************************************************************************
  DESCRIPTION:  This function handles checking for button presses
  RETURN:       none
  ALGORITHM:    none
  NOTES:        none
 *************************************************************************** */
int get_defaultduration(void)
{
  switch (Melody_Pointer)
  {
    case SILENTNIGHT:
      return (SilentNight.defaultduration);
      break;
    case JINGLEBELLS:
      return (JingleBells.defaultduration);
      break;
    default:
      break;
  }
}

/* *************************************************************************
  DESCRIPTION:  This function handles checking for button presses
  RETURN:       none
  ALGORITHM:    none
  NOTES:        none
 *************************************************************************** */
void Melody_Task(void)
{
  if (PlayMelodyFlag)
  {
    if (PlayMelody()==0)
      Melody_Pointer++;
  }
}

//----------------------------------------------------------------------------
// ISR routines
//----------------------------------------------------------------------------



#int_ccp1
/* *************************************************************************
  DESCRIPTION:  This function controls the PWM of the piezo speaker
  RETURN:       none
  ALGORITHM:    none
  NOTES:  If you do not wish to use C2 as the output, then you will need
          to toggle your output here.  Make sure that you change the CCP
          setup not to toggle the C2 output if this is the case
 *************************************************************************** */
void ccp1_isr (void)
{
  CCP_1 += Note_Ticks;
#if defined(__PCM__)
  output_toggle(PIN_C2);
#endif
}

/* *************************************************************************
  DESCRIPTION:  This function is used to control the duration of the note
  RETURN:       none
  ALGORITHM:    none
  NOTES:  I store the notes in a buffer so that the main loop has other
          time to do stuff with out have to sit at wait for a note to
          complete.
 *************************************************************************** */
#int_timer0
void timer0_isr (void)
{
  // Preload a value for TMR0 so that we can control how long it takes to
  // trigger an interrupt
  TMR0 = Tempo;

  // Is a note playing?
  if (DurationCount)
  {
    DurationCount--;
    if (!DurationCount)
      setup_ccp1(CCP_OFF);
  }
  // Note is finished playing, do we have anymore in our buffer?
  else if (Notestat.Count)
  {
    DurationCount = NoteBuffer[Notestat.Head].duration;
    Note_Ticks = NoteBuffer[Notestat.Head].note;
    Notestat.Count--;
    Notestat.Head++;
    Notestat.Head &= NOTE_ROLLOVER_MASK;
    CCP_1 = TMR1 + Note_Ticks;
    if (Note_Ticks)
    {
      /* Setup the CCP module to toggle the output pin c2 */
#if defined(__PCH__)
      setup_ccp1(CCP_COMPARE_TOGGLE_MATCH);
#else
      setup_ccp1(CCP_COMPARE_INT);
#endif
    }
    // Nope, we are all through so disable the PWM
    else
    {
      setup_ccp1(CCP_OFF);
    }
  }
}