Diferencia entre revisiones de «Buzzer - DEMOQE128»

De Wikitronica
Saltar a: navegación, buscar
(Por interrupciones RTC)
(Por interrupciones RTC o TPM)
 
(No se muestran 79 ediciones intermedias de 15 usuarios)
Línea 1: Línea 1:
 
[[Categoría: DEMOQE128]]
 
[[Categoría: DEMOQE128]]
                                                                                       [[Archivo:BUZZER DEMOQE.jpg|200px|thumb|right|Piezo Buzzer DEMOQE128]]     
+
                                                                                       [[Archivo:Buzzer demo.jpg|250px|thumb|right|Piezo Buzzer DEMOQE128.]]     
  
=BUZZER=
+
==''Buzzer''==
  
 +
[[Archivo:Buzzer 1.jpg|200px|thumb|right|Piezo Buzzer (MSPS23H)Precio por unidad: US$0.22-0.25.]]
 +
Un ''buzzer'' es un transductor electroacústico, o dispositivo de señales de audio, que produce un tono intermitente o continuo, dependiendo de cómo se programe. [[Archivo:Piezo buzzer 2.jpg|200px|thumb|right| Piezo Buzzer (MSPS43B)Precio por unidad: US $ 0.5-1.0]]
 +
                                                                       
 +
Existe una gran variedad de modelos de ''buzzer'', desde magnéticos hasta piezoeléctricos, con distintos precios y especificaciones.
 +
Elegir cuál de estos modelos es mejor depende enteramente del uso que se le quiera dar. Un ''buzzer'' puede servir como alarma, ''beeper'', avisos de fallos o aciertos en ciertos programas o incluso se puede implementar para lograr tonos armónicos o canciones.
  
  
 +
El corazón de un''buzzer'' piezoeléctrico es un disco de piezo el cual consiste en una placa cerámica recubierto de una capa metálica. Debe tener incluido un oscilador para ser considerado''buzzer''.
 +
 
 +
La [[Tarjeta de Desarrollo - DEMOQE128|Tarjeta de Desarrollo DEMOQE128]] contiene un piezo ''buzzer'', el mismo se encuentra conectado al pin PTB5 del microcontrolador por medio de un Jumper. Para poder utilizar este buzzer es necesario que el Jumper esté habilitado.
  
 +
==Inicializaciones de ''Buzzer''==
  
 +
Antes de empezar a codificar y trabajar con el ''buzzer'' se debe verificar que los Jumpers del DEMOQE128 posea la configuración adecuada para su funcionamiento:
  
Un buzzer es un transductor electro acústico o dispositivo de señales de audio que produce un tono intermitente o continuo dependiendo de cómo se programe a trabajar; existen muchos tipos de buzzer desde electromecánicos hasta piezoeléctricos.
+
• Colocar los [[JUMPER SETTINGS|''jumpers'']] de manera que se permita la salida de la señal al ''buzzer''. El ''buzzer''
 +
depende de que el ''jumper'' J19 este colocado de la siguiente manera:
  
  
El DEMOQE128 contiene un piezo buzzer. El corazón de un buzzer piezoeléctrico es un disco de piezo el cual consiste en una placa cerámica recubierto de una capa metalica. Debe tener incluido un oscilador para ser considerado buzzer.  
+
[[Archivo:Jumper buzzer.jpg|289px|thumb|center|''Jumper'' del ''Buzzer'' ]]
  
Algunos buzzer comerciales que se pueden encontrar actualmente  pueden ser:
 
  
 +
• Tener en cuenta con qué puerto trabaja el ''Buzzer'' y activarlo como salida. Se debe colocar
 +
el puerto PTBDD como salida ya que el ''buzzer'' funciona por medio de  PTBD_PTBD5.
  
[[Archivo:Buzzer 1.jpg|200px|thumb|left|Piezo Buzzer (MSPS23H)Precio por unidad: US$0.22-0.25]]
+
<syntaxhighlight lang="asm">
[[Archivo:BUZZER transducer.jpg|200px|thumb|right|Piezo Transducer (MSPT23A)Precio por unidad US $ 0.1-0.5]]
+
PTBDD -> %00100000;
[[Archivo:Piezo buzzer 2.jpg|200px|thumb|center| Piezo Buzzer (MSPS43B)Precio por unidad: US $ 0.5-1.0  ]]
+
</syntaxhighlight>
[[Archivo:BUZZER_magnetico.jpg|200px|thumb|center|SMD Magnetic Buzzer (MSES12D)Precio por unidad: US $ 0.1-0.5  ]]
+
BUZZER_transducer.jpg
+
                                                                                 
+
  
Como se puede observar existe una gran variedad de modelos de buzzer, desde magnéticos hasta piezoeléctricos, con distintos precios y especificaciones.
+
==Implementación==
  
 +
[[Archivo:BUZZER transducer.jpg|200px|thumb|left|Piezo Transducer (MSPT23A)Precio por unidad US $ 0.1-0.5]]
 +
[[Archivo:BUZZER_magnetico.jpg|200px|thumb|left|SMD Magnetic Buzzer (MSES12D)Precio por unidad: US $ 0.1-0.5]] 
  
=Inicializaciones de Buzzer=
+
Antes de empezar a utilizar el ''buzzer'' se debe tener en cuenta un par de cosas importantes:
  
Antes de empezar a codificar y trabajar con el buzzer se debe verificar que el DEMOQE128 posea los settings necesarios para su funcionamiento:
+
* El ''buzzer''  es parte del hardware del DEMOQE128, no depende del micro controlador implementado.
 +
* El ''buzzer'' no posee una estructura definida de control
 +
* La implementación del ''buzzer'' depende del código.
  
• Colocar los jumpers de manera que se permita la salida de la señal al buzzer. El buzzer depende de que el jumper J19 este colocado de la siguiente manera:
 
  
[[Archivo:Jumper buzzer.jpg|289px|thumb|center|Jumper del Buzzer ]]
 
  
• Tener en cuenta con que puerto trabaja el Buzzer y activarlo como salida. Se debe colocar el puerto PTBDD como salida ya que el buzzer funciona por medio de  PTBD_PTB5.
 
  
 +
Como se mencionó anteriormente para implementar el ''buzzer'' no contamos con registros de control ni con secuencias de instrucciones de control, para poder utilizarlo debemos trabajar  dentro del código.
  
                                                        <pre> PTBDD= 0xFF; </pre>
+
Se debe programar  el código de manera que emule una señal periódica, de esta  manera podemos usar esta señal como salida para el dispositivo, el cual  arrojará los tonos programados.
  
=Implementación=
 
  
Antes de empezar a utilizar el buzzer se debe tener en cuenta un par de cosas importantes:
+
'''¿Cómo crear una señal periódica?'''
  
• El buzzer es parte del hardware del DEMOQE128 no depende del micro controlador implementado.
+
Se puede utilizar una señal periódica para implementar los tonos en el ''buzzer'', dado que no se cuenta con un conversor Digital/Analógico en la Tarjeta de Desarrollo DemoQE, las señales de salida que se entregarán al buzzer serán digitales.
• El buzzer no posee una estructura definida de control
+
Para efectos prácticos el ''buzzer''  recibirá una señal periódica que alternará entre 1  y 0. Una señal cuadrática sería un buen ejemplo para la implementación de este método de diseño.
• La implementación del buzzer depende del codigo.
+
  
  
Como se menciono anteriormente para implementar el buzzer no contamos con registros de control ni con  secuencias de instrucciones de control, para poder utilizarlo debemos trabajar  dentro del código.  
+
[[Archivo:Onda cuadrada.jpg|613px|thumb|center|Onda periodica de salida al ''Buzzer'']]
Se debe programar  el código de manera que emule una señal periódica, de esta  manera podemos usar esta señal como salida para el dispositivo , el cual  arrojara los tonos programados.
+
  
  
Como crear una señal periódica:
+
Al momento de crear la señal hay que tomar en cuenta los siguientes aspectos para el tipo de tono que se quiera producir:
  
Se puede utilizar una señal periódica para implementar los tonos en el buzzer,  para efectos prácticos el buzzer  solo recibirá un 1 o un 0 dependiendo de en que tiempo se tome la señal y cuanto tiempo se mantenga en dicha salida. Una señal cuadrática seria un buen ejemplo para la implementación de este método de diseño.
+
* El tiempo que va a durar un tono.
 +
* La frecuencia del tono.
 +
* El espacio de tiempo entre tonos para evitar que se solapen.
  
 +
==Generación de solo un tono==
  
[[Archivo:Onda cuadrada.jpg|613px|thumb|center|Onda periodica de salida al Buzzer]]
+
===Configuración del puerto de salida===
 +
Colocar como salida el puerto PTBDD. Esto permite generar una salida en el puerto que esta conectado al ''buzzer''.
 +
<syntaxhighlight lang="c">
 +
    PTBDD -> #%00100000;
  
 +
</syntaxhighlight>
 +
Rutina de configuración de puerto de salida para el "buzzer" en lenguaje ensamblador:
 +
<syntaxhighlight lang="c">
 +
CONFIGURAR_GPO:
  
Al momento de crear la señal hay que tomar en cuenta ciertas cosas para el tipo de tono que se quiera producir, entre esas están las siguientes:
+
MOV #%00100000,PTBDD    ;INICIALIZA EL PUERTO PTB5 COMO SALIDA
  
• La cantidad de ciclos de reloj de la onda
+
MOV #%00000000,PTBD ;VALOR INICIAL EN CERO
• La duración  en la que se repetirá la onda cuadrada deseada
+
</syntaxhighlight>
• El diseño de los tiempos  entre tonos para evitar que se solapen
+
  
 +
===Por interrupciones RTC o TPM===
  
 +
'''Habilitar interrupciones del [[RTC (Real-timer counter) - MC9S08QE128|RTC (Real Time Counter)]]:
  
 +
Las interrupciones RTC o TPM se usarán para determinar el periodo de la onda.
  
 +
'''En assembler'''
  
=Generación de solo un tono=
+
<syntaxhighlight lang="asm">
 +
CONFIGURAR_RTC:
 +
LDA #%00100100
 +
STA SCGC2 ;ACTIVADO IRQ CLOCK GATE CONTROL Y RTC CLOCK GATE CONTROL
 +
LDA #$00 ;RTCMOD en 0 max
 +
STA RTCMOD ;CONFIGURADO EN 00 EL MODULO DEL RTC, RESETEA CUANDO RTIF
 +
;SE ACTIVA. RTI:Real-Time Interrupt Flag
 +
LDA #%00011101         ;RTIF=0.RTCLKS:00 RTC source is the 1-kHz low power oscillator (LPO)
 +
STA RTCSC ;RTIE=1.(Real-Time Interrupt Enable). RTCPS :1101-> 0,1 s
 +
                        RTS
 +
</syntaxhighlight>
  
==Por interrupciones RTC==
 
  
 +
'''En lenguaje C'''
  
 +
<syntaxhighlight lang="c">
 +
            SCGC2=0x04;            //Habilita BUS Clock para RTC
 +
            RTCMOD=0x00;          //Se inicializa el módulo Real Time Counter.
 +
            RTCSC=0x1E;            //Para que active la Bandera RTIF cada 1s.
 +
</syntaxhighlight>
  
• Colocar como salida el puerto PTBDD. Esto permite generar una salida en el puerto que esta conectado al buzzer.
+
''' Habilitar las interrupciones del [[Timer TPM]] - [[Ejemplo Timer TPM por interrupciones]]'''
+
    <pre> PTBDD= 0xff; </pre>
+
  
 +
'''En assembler'''
  
 +
<syntaxhighlight lang="asm">
 +
CONFIGURAR_TPM:
 +
LDA #00
 +
STA TPM1MOD ;Se inicializa el modulo del TPM
 +
LDA #%01001111 ;TPM1SC: TOF=0,TOIE=1,CPWMS=0,CLKSB=0,CLKSA=0
 +
STA TPM1SC ;PS2=1,PS1=1,PS0=1
 +
RTS                                                 
 +
</syntaxhighlight>
  
• Habilitar interrupciones RTC (Real Time Counter):
 
  
Las interrupciones RTC se usaran para determinar el periodo de la onda.
+
'''Período de la onda:'''
  
 +
El programa entrará en la rutina de interrupción que asignada al Timer seleccionado una vez se llegue al valor máximo del módulo del mismo. Durante esta rutina se negará la salida PTBD_PTB5, esto determina la mitad del periodo. Si se observa la onda cuadrada se puede notar que con cada cambio de flanco o salida negada  la  amplitud de la onda cambia de “0” a “1”, cuando la onda haga dos cambios (vuelva al estado que se toma como referencia) se cumple un periodo, por eso cada interrupción por RTC representa medio periodo.
  
• El periodo de la onda es determinado de la siguiente manera:
+
Se continúa negando la salida PTBD_PTBD5 por un tiempo indeterminado, esto genera un tono en la salida del ''buzzer'', el cual reconoce los cambios en el periodo de la señal como el tono en cuestión.
  
El programa entrara en la rutina de interrupción que se diseño anteriormente  por RTC, durante esta rutina se negara la salida PTBD_PTB5, esto determina la mitad del periodo. Si se observa la onda cuadrada se puede notar que con cada cambio de flanco o salida negada  la  amplitud de la onda cambia de “0” a “1”, cuando la onda haga dos cambios (vuelva al estado que se toma como referencia) se cumple un periodo, por eso cada interrupción por RTC representa medio periodo.
+
A continuación, se presentan dos ejemplos de posibles rutinas de interrupcion para ambos casos:
  
 +
'''Para RTC'''
  
• Se continúa negando la salida PTBD_PTB5  por un tiempo indeterminado, esto genera un tono en la salida del buzzer, el cual reconoce los cambios en el periodo de la señal como el tono en cuestión.
+
<syntaxhighlight lang="c">
 +
RTCInterrupt:
 +
LDA #%10000000
 +
ORA RTCSC ;Baja la bandera RTIF
 +
STA RTCSC
 +
BRCLR PTBD_PTBD5,PTBD,UNO  ;Si PTB5 esta en 0 va a la rutina correspondiente a colocar 1
 +
BRSET PTBD_PTBD5,PTBD,CERO  ;Si PTB5 esta en 1 va a la rutina correspondiente a colocar 0
 +
 +
CERO:
 +
BCLR PTBD_PTBD5,PTBD
 +
RTI
 +
UNO:
 +
BSET PTBD_PTBD5,PTBD
 +
RTI
 +
</syntaxhighlight>
  
Variación de tonos:
+
'''Para TPM'''
Nota= para cambiar el tono, se debe configurar el RTC de manera que module la duración entre interrupciones (esto cambiara el periodo de la onda). Ver configuración de RTC
+
<syntaxhighlight lang="c">
  
==Generación de tonos manual sin RTC==
+
TPMInterrupt:
 +
            lda      TPM1SC
 +
            and      #%01111111                      ;Se baja la bandera de interrupcion
 +
            sta      TPM1SC
 +
            brset    5,PTBD,Negador                  ;Si el bit 5 del puerto PTBD se encuentra en 1, se niega.
 +
            mov      #$20,PTBD                      ;si se encuentra e 0 se coloca en 1
 +
            bra      loop
  
• Los primeros pasos de inicialización son exactamente iguales con o sin RTC
+
Negador:
 +
                                                    ;Si el bit PTB5 se encuentra en 1, se coloca en 0
 +
            mov      #$00,PTBD
  
 +
loop:
 +
            RTI
  
• Al momento de implementar las interrupciones, si no se posee el conocimiento para usar el RTC también se puede crear un periodo “manualmente”, se debe tener  como parámetro  la cantidad de ciclos de reloj que tendrá la onda cuadrada. Luego se debe  “sincronizar”  el tiempo que tarda cada instrucción del programa  con respecto a la cantidad e ciclos de la onda. Para poder completar los ciclos faltantes (la onda usualmente se toma mas ciclos de reloj que las instrucciones de cambio de periodo) se pueden utilizar “nops” iterados dentro de las mismas instrucciones si se trata de assembler o ciclos si se trabaja con C.
+
</syntaxhighlight>
  
• Se puede utilizar una tabla de frecuencias para cada “nota” que se desea, si se quiere hacer un sonido especifico ( esto para cuando se desea generar mas de un tono), el programa leerá estas variaciones y las tomara como un cambio en el periodo, que en si es lo que define que nota tomara como salida el buzzer.  
+
Ambos algoritmos pueden ser usados en cualquiera de los dos temporizadores. Ahora bien, para lograr que un determinado tono suene durante cierto periodo de tiempo, puede implementarse un contador. Este se utiliza de tal manera que, cada vez que se entre al temporizador, se incremente su valor y al llegar a su maximo, el buzzer deje de sonar.
  
• Aunque es posible generar una onda de esta manera es mejor utilizar el RTC pues este diseñoes muy poco eficiencia y se desperdicia la verdadera capacidad del DEMOQE128.
+
Un ejemplo de interrupcion implementando el contador es el siguiente
  
Un ejemplo de este diseño seria:
+
<syntaxhighlight lang="c">
<pre>
+
;----------Subrutina----------
 +
 
 +
Tono_Continuo:
 +
            lda    #Flag                          ;Se verifica si  ya se configuro el TPM para esta subrutina
 +
            cmp    #00                            ;si no es asi se configura. Esto se hace para Flaginicial=0. En la rutina de configuracion del TPM
 +
            bne    LoopRaya                      ;debe negarse para que no se reconfigure
 +
            bsr    Configurar_TPM1
 +
            lda    Contador                      ;Se espera a que el contador predeterminado llegue a FF, para
 +
            cmp    #$FF                          ;que se cumpla el tiempo necesitado para generar un tono audible y considerable en el buzzer
 +
            bne    Tono_Continuo                  ;Una vez que se llega a FF se apaga el TPM y se retorna para continuar
 +
            jsr    Apagar_TPM1                    ;con el programa
 +
            clr    Contador                      ;Se limpia el contador
 +
            com    Flag                          ;Se coloca la bandera en el estado inicial para poder ser usada nuevamente
 +
            rts                                 
 +
 
 +
;----------Interrupcion--------
 +
 
 +
TPMinterrupt:
 +
            lda      TPM1SC
 +
            and      #%01111111                  ;Se baja la bandera de interrupcion
 +
            sta      TPM1SC
 +
            brset    5,PTBD,Negador              ;Si el bit 5 del puerto PTBD se encuentra en 1, se niega.
 +
            mov      #$20,PTBD                  ;Si se encuentra e 0 se coloca en 1
 +
            bra      loop
 +
 
 +
Negador:
 +
                                                  ;Si el bit PTB5 se encuentra en 1, se coloca en 0
 +
            mov      #$00,PTBD
 +
 
 +
loop:
 +
            inc      Contador                    ;Se incrementa el contador
 +
            rti
 +
           
 +
</syntaxhighlight>
 +
 
 +
<syntaxhighlight lang="c">
 +
Notas:                                                                                                                                   
 +
1) Estas interrupciones pueden hacerse con cualquier tipo de timer, en este articulo se ejemplifica solo para RTC y TPM                                                                                                   
 +
2) Es necesario recordar que, bajo esta configuracion, el TPM depende del reloj del bus. Si se utiliza un reloj distinto al que viene por
 +
defecto (4MHZ), deben realizarse los calulos pertinentes para obtener el tiempo deseado.
 +
</syntaxhighlight>
 +
 
 +
 
 +
'''Variación de tonos:'''
 +
 
 +
* Para cambiar el tono existen en cuestión dos procedimientos:
 +
 
 +
 
 +
'''1) Por tiempo de interrupción basados en el módulo RTCMOD o TPMMOD:'''
 +
 
 +
La frecuencia de operación del timer es fija y la variable es el módulo.
 +
Al variar el tiempo que tarda el reloj en llegar a la interrupción, se está modulando el periodo de la onda, por ende, se esta seleccionando una frecuencia de trabajo. Lo recomendable es fijar un reloj muy rápido, ya que permite establecer una gran variedad de frecuencias.
 +
 
 +
 
 +
El reloj más rápido que se puede lograr con RTC es el de 31.25us, el cual se obtiene a partir del reloj interno (IRCLK) de 32KHz, éste debe ser activado en el registro de control de ICS (Internal Clock Source) utilizando una instrucción como BSET ICSC1_IRCLKEN,ICSC1 para poder utilizarlo, es decir, no basta con activar los bits correspondientes de RTCLKS.
 +
 
 +
 
 +
 
 +
Ver ejemplo en:
 +
 
 +
'''Macro:''' Notas Musicales [[Medio:Notas_Musicales.pdf‎]]
 +
 
 +
'''Tabla de notas musicales''': [[Medio:Tabla_de_notas.xlsx‎]]
 +
 
 +
;Nota:Estos ejemplos fueron realizados para TPMx en la configuracion dada por "Tabla de notas musicales", sin embargo, es igualmente aplicable para RTC.
 +
 
 +
 
 +
'''2) Por variación de la frecuencia y módulo fijo:'''
 +
 
 +
La idea de este método es dejar el RTCMOD o TPMMOD fijo y variar la frecuencia de operación del Timer. Para ello, se modifica continuamente el registro RTCSC o TPM1SC segun sea el caso, en sus bits[3:0], para hacer coincidir la frecuencia del reloj seleccionado con la frecuencia de la nota deseada.
 +
 
 +
;Nota:Este procedimiento no es el más adecuado, sin embargo funciona.
 +
Se recomienda colocar el modulo en 0x00 para este procedimiento.
 +
 
 +
 
 +
 
 +
;Adicionalmente:
 +
En el caso que se quiera programar más de una secuencia de tonos, o "canciones" juntas, un dato de interés podría ser que el ''buzzer'' no puede reconocer frecuencias (expresadas en periodos) muy altas o muy bajas, lo cual usualmente es útil para hacer "silencios" entre una canción y otra. Esto se puede realizar mediante la colocación de -1, que se refiere al valor de $FFFF en TPMMOD (es una frecuencia muy alta, que el ''buzzer'' no reconocerá) y no emitirá sonido. Cuatro "-1" corresponden a 1 segundo. Sin embargo, lo mejor para generar silencios es tener una rutina que apague el buzzer cada vez que se reciba alguna letra o se deje de presionar algún botón, pues las frecuencias muy altas, dependiendo del reloj utilizado, pueden ser molestas o simplemente ser ruidos.
 +
 
 +
==Generación de tonos usando PWM==
 +
 
 +
<syntaxhighlight lang="c">
 +
#define PRESCALAR 0
 +
#define MODULO 32768 //4Mhz / MODULO / 1 (prescaler) = aprox. 122Hz
 +
#define DUTY25 (MODULO/4)
 +
 
 +
void main(void)
 +
{
 +
    // Inicializaciones
 +
  SOPT1_COPE=0;      /*Desabilitar el watchdog*/
 +
  ADCSC1 = 0x20; // Se selecciona el canal ADCH0, Se selecciona modo de conversion continua y se habilitan las interrupciones
 +
  ADCSC2 = 0x00; // Se deshabilita la funcion de comparacion y se selecciona el software trigger
 +
  ADCCFG = 0x40; // Se selecciona Long Sample time y se divide el Bus Clock entre 2
 +
  APCTL1 = 0x00; // Se deshabilita el puerto asociado al canal ADCH0 ya que esta siendo usado como entrada analogica
 +
  ADCCFG_MODE=1;    /*12bit conversion*/
 +
    //inicializacion pwm
 +
TPM1SC_CLKSA = 1; // Se elige como source del reloj para el TPM el "Bus Rate Clock"   
 +
 
 +
TPM1SC_CLKSB = 0;   
 +
 
 +
TPM1SC_PS = PRESCALAR; //y dividido entre 1   
 +
 
 +
TPM1MOD = MODULO; // Se guarda el valor del modulo para el contador   
 +
 
 +
TPM1C0SC_MS0B = 1; // Se elige la modalidad "PWM edge aligned"   
 +
 
 +
TPM1C0SC_ELS0A = 1; // Corresponde a la configuración de pulso "Low-True"   
 +
 
 +
TPM1C0V = DUTY25; // Con esto obtendremos un duty cycle aprox del 25%
 +
   
 +
    for(;;)
 +
    {
 +
          ADCSC1_ADCH=0x0;
 +
          while(ADCSC1_COCO==0); // Esperar que la conversion se ejecute
 +
          TPM1MOD = ADCR; //Cambio el Valor del módulo
 +
  TPM1C0V = TPM1MOD/4; //25%dutycicle
 +
      }
 +
}
 +
</syntaxhighlight>
 +
 
 +
 
 +
 
 +
''Nota: Falta probar el código''
 +
 
 +
===Generación de tonos manual (sin RTC)===
 +
 
 +
* Los primeros pasos de inicialización son exactamente iguales con o sin RTC
 +
 
 +
 
 +
* Al momento de implementar las interrupciones, si no se posee el conocimiento para usar el RTC también se puede crear un periodo “manualmente”, se debe tener  como parámetro  la cantidad de ciclos de reloj que tendrá la onda cuadrada. Luego se debe  “sincronizar”  el tiempo que tarda cada instrucción del programa  con respecto a la cantidad de ciclos de la onda. Para poder completar los ciclos faltantes (la onda usualmente se toma más ciclos de reloj que las instrucciones de cambio de periodo) se pueden utilizar “nops” iterados dentro de las mismas instrucciones si se trata de assembler, o ciclos si se trabaja con C.
 +
 
 +
 
 +
 
 +
* Se puede utilizar una tabla de frecuencias para cada “nota” que se desea, si se quiere hacer un sonido específico ( esto para cuando se desea generar más de un tono), el programa leerá estas variaciones y las tomará como un cambio en el periodo, que en sí es lo que define que nota tomará como salida el ''buzzer''.
 +
 
 +
 
 +
 
 +
* Aunque es posible generar una onda de esta manera, es mejor utilizar el RTC pues este diseño es muy poco eficiente y se desperdicia la verdadera capacidad del [[Tarjeta de Desarrollo - DEMOQE128|DEMOQE128]].
 +
 
 +
 
 +
Un ejemplo de este diseño sería:
 +
 
 +
<syntaxhighlight lang="asm">
 
;************************************************************************** ;           
 
;************************************************************************** ;           
;*** Rutina de generacion de ondas cuadradas, de 30 ciclos de reloj *******;
+
;*** Rutina de generación de ondas cuadradas, de 30 ciclos de reloj *******;
 
;*** se llevará a cabo tantas veces como indique PERIODO,          ******* ;           
 
;*** se llevará a cabo tantas veces como indique PERIODO,          ******* ;           
;*** Luego negará la salida del Buzzer y repetirá el conteo de PERIODO ****;
+
;*** Luego negará la salida del ''Buzzer'' y repetirá el conteo de PERIODO ****;
 
;*** 30 ciclos * 250 ns (Tiempo de cada ciclo) = 7.5uS    *****************;
 
;*** 30 ciclos * 250 ns (Tiempo de cada ciclo) = 7.5uS    *****************;
 
;**************************************************************************;             
 
;**************************************************************************;             
  
Flanco:    NOP                  ;1 ciclo - Los NOP son para compensar los ciclos usados en cambiar el flanco
+
MOV 0, COUNTER;
             NOP                 
+
MOV 0, COUNTER_2
             NOP                 
+
 
             NOP                 
+
Flanco:    NOP                  ;1 ciclo - Los NOP son para compensar los Ciclos usados en cambiar el Flanco.
             NOP                    
+
             LDA COUNTER
            NOP                 
+
             INCA
            NOP                                   
+
             STA COUNTER
            NOP
+
             BNE COUNTER, #12,Flanco                    
            NOP                 
+
                       
            NOP
+
            NOP                 
+
            NOP                 
+
 
Cambio:    NOP                   
 
Cambio:    NOP                   
             NOP
+
             LDA COUNTER
             NOP                  ;1 ciclo
+
             INCA
             NOP                 
+
             STA COUNTER
             NOP                 
+
             BNE COUNTER, #10,Cambio 
            NOP                 
+
            NOP                 
+
            NOP                                   
+
            NOP                 
+
            NOP
+
 
                                
 
                                
             AIX #-1                ;2 ciclos
+
             AIX #-1                ;2 ciclos.
             CPHX #$0000          ;3 ciclos - Revisa si el contador llega a cero, compare hx con el valor
+
             CPHX #$0000          ;3 ciclos - Revisa si el contador llega a cero, compare HX con el valor.
             BNE Flanco            ;3 ciclos - Si aun no se termina el periodo, decrementar contador, NECESITA DE  RESULTADO DE LA funcion anterior para actuar
+
             BNE Flanco            ;3 ciclos - Si aun no se termina el periodo, decrementar contador, NECESITA DE  RESULTADO DE LA Función anterior para actuar.
 
              
 
              
             COM PTBD              ;5 ciclos
+
             COM PTBD              ;5 ciclos.
             LDHX periodo          ;5 ciclos
+
             LDHX periodo          ;5 ciclos.
             BRA  Cambio          ;3 ciclos - Si ya termino el periodo, pasar al siguiente flanco
+
             BRA  Cambio          ;3 ciclos - Si ya terminó el periodo, pasar al siguiente flanco.
 
              
 
              
  
 
;**************************************************************
 
;**************************************************************
</pre>
+
</syntaxhighlight>
 +
 
 +
Para el uso de esta instrucción también se necesita el uso de una tabla de frecuencias que representen una escala de notas o tonos, el programa leerá la "canción"que no será más que una combinación de las frecuencias de la tabla y las traducirá a cambios en periodo como se mencionó anteriormente.  un modelo de dicha tabla podría ser:
 +
 
 +
<syntaxhighlight lang="asm">
 +
;Tabla de Notas musicales ordenadas por octava: do, do#,re,re#,mi,fa,fa#,sol,sol#,la,la#,si
 +
                    ;do, do#,re,re#,mi, fa, fa#,sol,sol#,la,la#,si
 +
SILENCIO:  DC.W    $FFFF
 +
OCTAVA1:    DC.W    509,480,454,428,403,381,359,339,320,302,285,269    ;3
 +
OCTAVA2:    DC.W    254,240,226,213,201,190,179,169,160,151,143,135  ;4
 +
OCTAVA3:    DC.W    126,119,113,106,100,94,89,84,79,75,71,66      ;5
 +
OCTAVA4:    DC.W    63,59,56,53,50,47,44,42,39,37,35,33          ;6 
 +
</syntaxhighlight>
 +
 
 +
•Aun así se recomienda de nuevo no utilizar este método sino uno que implique la variación del periodo por medio de RTC, lo que haría que la cantidad de líneas de código de el programa disminuya significativamente ademas de ser la manera correcta de programar y aprovechar eficientemente las funciones del DEMOQE128.
 +
 
 +
==Programa de Prueba==
 +
 
 +
A continuación se puede observar un enlace a Youtube con un video de la implementación del ''buzzer'', está programado para reproducir dos fragmentos de canciones del juego "ZELDA", primero "''Serenade Of Water''", luego, y con un silencio de segundo y medio, sonará un fragmento de "''Song Of Storms''".
 +
 
 +
http://www.youtube.com/watch?v=jyfUEQ8zmCY
 +
 
 +
 
 +
Utilizando la configuración dada por el macro [[Medio:Notas_Musicales.pdf‎]] es posible representar los siguientes ejemplos:
 +
<syntaxhighlight lang="asm">
 +
;Prueba desde Do4 hasta Si5
 +
 +
Do4
 +
Redonda
 +
DoS4
 +
Redonda
 +
Re4
 +
Redonda
 +
ReS4
 +
Redonda
 +
Mi4
 +
Redonda
 +
Fa4
 +
Redonda
 +
FaS4
 +
Redonda
 +
Sol4
 +
Redonda
 +
SolS4
 +
Redonda
 +
La4
 +
Redonda
 +
LaS4
 +
Redonda
 +
Si4
 +
Redonda
 +
 +
Do5
 +
Redonda
 +
DoS5
 +
Redonda
 +
Re5
 +
Redonda
 +
ReS5
 +
Redonda
 +
Mi5
 +
Redonda
 +
Fa5
 +
Redonda
 +
FaS5
 +
Redonda
 +
Sol5
 +
Redonda
 +
SolS5
 +
Redonda
 +
La5
 +
Redonda
 +
LaS5
 +
Redonda
 +
Si5
 +
Redonda
 +
 
 +
 
 +
 
 +
 
 +
Pokemon_Heal:
 +
Silencio
 +
Corchea
 +
Fa4
 +
Negra
 +
Fa4
 +
Negra
 +
Fa4
 +
Corchea
 +
Do4
 +
Corchea
 +
La4
 +
Negra
 +
JMP Pokemon_Heal
 +
 
 +
 
 +
TETRIS:
 +
 
 +
Silencio
 +
Negra
 +
 
 +
La5
 +
Corchea
 +
FaS5
 +
Semi_Corchea
 +
Sol5
 +
Semi_Corchea
 +
SolS5
 +
Corchea
 +
Sol5
 +
Semi_Corchea
 +
FaS5
 +
Semi_Corchea
 +
Mi5
 +
Corchea
 +
Mi5
 +
Semi_Corchea
 +
Sol5
 +
Semi_Corchea
 +
La5
 +
Corchea
 +
SolS5
 +
Semi_Corchea
 +
Sol5
 +
Semi_Corchea
 +
FaS5
 +
Corchea
 +
FaS5
 +
Semi_Corchea
 +
Sol5
 +
Semi_Corchea
 +
SolS5
 +
Corchea
 +
La5
 +
Corchea
 +
Sol5
 +
Corchea
 +
Mi5
 +
Corchea
 +
Mi5
 +
Negra
 +
Silencio
 +
Blanca
 +
JMP TETRIS
 +
</syntaxhighlight>
 +
 
 +
==Referencias==
 +
 
 +
•[http://www.soundbuzzer.com Imágenes de los ''buzzers'']
 +
 
 +
•[http://cache.freescale.com/files/microcontrollers/doc/user_guide/DEMOQE128UM.pdf?fpsp=1&WT_TYPE=Users%20Guides&WT_VENDOR=FREESCALE&WT_FILE_FORMAT=pdf&WT_ASSET=Documentation DEMOQE128UM]
 +
 
 +
[[Categoría: DEMOQE128]]

Revisión actual del 08:48 31 mar 2013

Piezo Buzzer DEMOQE128.

Buzzer

Piezo Buzzer (MSPS23H)Precio por unidad: US$0.22-0.25.
Un buzzer es un transductor electroacústico, o dispositivo de señales de audio, que produce un tono intermitente o continuo, dependiendo de cómo se programe.
Piezo Buzzer (MSPS43B)Precio por unidad: US $ 0.5-1.0

Existe una gran variedad de modelos de buzzer, desde magnéticos hasta piezoeléctricos, con distintos precios y especificaciones. Elegir cuál de estos modelos es mejor depende enteramente del uso que se le quiera dar. Un buzzer puede servir como alarma, beeper, avisos de fallos o aciertos en ciertos programas o incluso se puede implementar para lograr tonos armónicos o canciones.


El corazón de unbuzzer piezoeléctrico es un disco de piezo el cual consiste en una placa cerámica recubierto de una capa metálica. Debe tener incluido un oscilador para ser consideradobuzzer.

La Tarjeta de Desarrollo DEMOQE128 contiene un piezo buzzer, el mismo se encuentra conectado al pin PTB5 del microcontrolador por medio de un Jumper. Para poder utilizar este buzzer es necesario que el Jumper esté habilitado.

Inicializaciones de Buzzer

Antes de empezar a codificar y trabajar con el buzzer se debe verificar que los Jumpers del DEMOQE128 posea la configuración adecuada para su funcionamiento:

• Colocar los jumpers de manera que se permita la salida de la señal al buzzer. El buzzer depende de que el jumper J19 este colocado de la siguiente manera:


Jumper del Buzzer


• Tener en cuenta con qué puerto trabaja el Buzzer y activarlo como salida. Se debe colocar el puerto PTBDD como salida ya que el buzzer funciona por medio de PTBD_PTBD5.

PTBDD -> %00100000;

Implementación

Piezo Transducer (MSPT23A)Precio por unidad US $ 0.1-0.5
SMD Magnetic Buzzer (MSES12D)Precio por unidad: US $ 0.1-0.5

Antes de empezar a utilizar el buzzer se debe tener en cuenta un par de cosas importantes:

  • El buzzer es parte del hardware del DEMOQE128, no depende del micro controlador implementado.
  • El buzzer no posee una estructura definida de control
  • La implementación del buzzer depende del código.



Como se mencionó anteriormente para implementar el buzzer no contamos con registros de control ni con secuencias de instrucciones de control, para poder utilizarlo debemos trabajar dentro del código.

Se debe programar el código de manera que emule una señal periódica, de esta manera podemos usar esta señal como salida para el dispositivo, el cual arrojará los tonos programados.


¿Cómo crear una señal periódica?

Se puede utilizar una señal periódica para implementar los tonos en el buzzer, dado que no se cuenta con un conversor Digital/Analógico en la Tarjeta de Desarrollo DemoQE, las señales de salida que se entregarán al buzzer serán digitales. Para efectos prácticos el buzzer recibirá una señal periódica que alternará entre 1 y 0. Una señal cuadrática sería un buen ejemplo para la implementación de este método de diseño.


Onda periodica de salida al Buzzer


Al momento de crear la señal hay que tomar en cuenta los siguientes aspectos para el tipo de tono que se quiera producir:

  • El tiempo que va a durar un tono.
  • La frecuencia del tono.
  • El espacio de tiempo entre tonos para evitar que se solapen.

Generación de solo un tono

Configuración del puerto de salida

Colocar como salida el puerto PTBDD. Esto permite generar una salida en el puerto que esta conectado al buzzer.

    PTBDD -> #%00100000;

Rutina de configuración de puerto de salida para el "buzzer" en lenguaje ensamblador:

CONFIGURAR_GPO:

MOV #%00100000,PTBDD    ;INICIALIZA EL PUERTO PTB5 COMO SALIDA

MOV #%00000000,PTBD	;VALOR INICIAL EN CERO

Por interrupciones RTC o TPM

Habilitar interrupciones del RTC (Real Time Counter):

Las interrupciones RTC o TPM se usarán para determinar el periodo de la onda.

En assembler

CONFIGURAR_RTC:
			LDA #%00100100		
			STA SCGC2			;ACTIVADO IRQ CLOCK GATE CONTROL Y RTC CLOCK GATE CONTROL
			LDA #$00			;RTCMOD en 0 max
			STA RTCMOD			;CONFIGURADO EN 00 EL MODULO DEL RTC, RESETEA CUANDO RTIF
							;SE ACTIVA. RTI:Real-Time Interrupt Flag
			LDA #%00011101		        ;RTIF=0.RTCLKS:00 RTC source is the 1-kHz low power oscillator (LPO)
			STA RTCSC			;RTIE=1.(Real-Time Interrupt Enable). RTCPS :1101-> 0,1 s
                        RTS


En lenguaje C

            SCGC2=0x04;            //Habilita BUS Clock para RTC
            RTCMOD=0x00;           //Se inicializa el módulo Real Time Counter.
            RTCSC=0x1E;            //Para que active la Bandera RTIF cada 1s.

Habilitar las interrupciones del Timer TPM - Ejemplo Timer TPM por interrupciones

En assembler

CONFIGURAR_TPM:
			LDA #00		
			STA TPM1MOD			;Se inicializa el modulo del TPM
			LDA #%01001111			;TPM1SC: TOF=0,TOIE=1,CPWMS=0,CLKSB=0,CLKSA=0
			STA TPM1SC			;PS2=1,PS1=1,PS0=1
			RTS


Período de la onda:

El programa entrará en la rutina de interrupción que asignada al Timer seleccionado una vez se llegue al valor máximo del módulo del mismo. Durante esta rutina se negará la salida PTBD_PTB5, esto determina la mitad del periodo. Si se observa la onda cuadrada se puede notar que con cada cambio de flanco o salida negada la amplitud de la onda cambia de “0” a “1”, cuando la onda haga dos cambios (vuelva al estado que se toma como referencia) se cumple un periodo, por eso cada interrupción por RTC representa medio periodo.

Se continúa negando la salida PTBD_PTBD5 por un tiempo indeterminado, esto genera un tono en la salida del buzzer, el cual reconoce los cambios en el periodo de la señal como el tono en cuestión.

A continuación, se presentan dos ejemplos de posibles rutinas de interrupcion para ambos casos:

Para RTC

RTCInterrupt:
		LDA #%10000000
		ORA RTCSC	;Baja la bandera RTIF
		STA RTCSC
		BRCLR PTBD_PTBD5,PTBD,UNO   ;Si PTB5 esta en 0 va a la rutina correspondiente a colocar 1
		BRSET PTBD_PTBD5,PTBD,CERO  ;Si PTB5 esta en 1 va a la rutina correspondiente a colocar 0
		
CERO:
		BCLR PTBD_PTBD5,PTBD
		RTI
UNO:
		BSET PTBD_PTBD5,PTBD
		RTI

Para TPM

TPMInterrupt:
            lda       TPM1SC
            and       #%01111111                      ;Se baja la bandera de interrupcion
            sta       TPM1SC
            brset     5,PTBD,Negador                  ;Si el bit 5 del puerto PTBD se encuentra en 1, se niega.
            mov       #$20,PTBD                       ;si se encuentra e 0 se coloca en 1
            bra       loop

Negador:
                                                     ;Si el bit PTB5 se encuentra en 1, se coloca en 0
            mov       #$00,PTBD

loop:
            RTI

Ambos algoritmos pueden ser usados en cualquiera de los dos temporizadores. Ahora bien, para lograr que un determinado tono suene durante cierto periodo de tiempo, puede implementarse un contador. Este se utiliza de tal manera que, cada vez que se entre al temporizador, se incremente su valor y al llegar a su maximo, el buzzer deje de sonar.

Un ejemplo de interrupcion implementando el contador es el siguiente

;----------Subrutina----------

Tono_Continuo:
            lda    #Flag                          ;Se verifica si  ya se configuro el TPM para esta subrutina
            cmp    #00                            ;si no es asi se configura. Esto se hace para Flaginicial=0. En la rutina de configuracion del TPM
            bne    LoopRaya                       ;debe negarse para que no se reconfigure
            bsr    Configurar_TPM1
            lda    Contador                       ;Se espera a que el contador predeterminado llegue a FF, para
            cmp    #$FF                           ;que se cumpla el tiempo necesitado para generar un tono audible y considerable en el buzzer
            bne    Tono_Continuo                  ;Una vez que se llega a FF se apaga el TPM y se retorna para continuar
            jsr    Apagar_TPM1                    ;con el programa
            clr    Contador                       ;Se limpia el contador 
            com    Flag                           ;Se coloca la bandera en el estado inicial para poder ser usada nuevamente
            rts                                  

;----------Interrupcion--------

TPMinterrupt:
            lda       TPM1SC
            and       #%01111111                  ;Se baja la bandera de interrupcion
            sta       TPM1SC
            brset     5,PTBD,Negador              ;Si el bit 5 del puerto PTBD se encuentra en 1, se niega.
            mov       #$20,PTBD                   ;Si se encuentra e 0 se coloca en 1
            bra       loop

Negador:
                                                  ;Si el bit PTB5 se encuentra en 1, se coloca en 0
            mov       #$00,PTBD

loop:
            inc       Contador                    ;Se incrementa el contador
            rti
Notas:                                                                                                                                     
1) Estas interrupciones pueden hacerse con cualquier tipo de timer, en este articulo se ejemplifica solo para RTC y TPM                                                                                                     
2) Es necesario recordar que, bajo esta configuracion, el TPM depende del reloj del bus. Si se utiliza un reloj distinto al que viene por
 defecto (4MHZ), deben realizarse los calulos pertinentes para obtener el tiempo deseado.


Variación de tonos:

  • Para cambiar el tono existen en cuestión dos procedimientos:


1) Por tiempo de interrupción basados en el módulo RTCMOD o TPMMOD:

La frecuencia de operación del timer es fija y la variable es el módulo. Al variar el tiempo que tarda el reloj en llegar a la interrupción, se está modulando el periodo de la onda, por ende, se esta seleccionando una frecuencia de trabajo. Lo recomendable es fijar un reloj muy rápido, ya que permite establecer una gran variedad de frecuencias.


El reloj más rápido que se puede lograr con RTC es el de 31.25us, el cual se obtiene a partir del reloj interno (IRCLK) de 32KHz, éste debe ser activado en el registro de control de ICS (Internal Clock Source) utilizando una instrucción como BSET ICSC1_IRCLKEN,ICSC1 para poder utilizarlo, es decir, no basta con activar los bits correspondientes de RTCLKS.


Ver ejemplo en:

Macro: Notas Musicales Medio:Notas_Musicales.pdf‎

Tabla de notas musicales: Medio:Tabla_de_notas.xlsx‎

Nota
Estos ejemplos fueron realizados para TPMx en la configuracion dada por "Tabla de notas musicales", sin embargo, es igualmente aplicable para RTC.


2) Por variación de la frecuencia y módulo fijo:

La idea de este método es dejar el RTCMOD o TPMMOD fijo y variar la frecuencia de operación del Timer. Para ello, se modifica continuamente el registro RTCSC o TPM1SC segun sea el caso, en sus bits[3:0], para hacer coincidir la frecuencia del reloj seleccionado con la frecuencia de la nota deseada.

Nota
Este procedimiento no es el más adecuado, sin embargo funciona.

Se recomienda colocar el modulo en 0x00 para este procedimiento.


Adicionalmente

En el caso que se quiera programar más de una secuencia de tonos, o "canciones" juntas, un dato de interés podría ser que el buzzer no puede reconocer frecuencias (expresadas en periodos) muy altas o muy bajas, lo cual usualmente es útil para hacer "silencios" entre una canción y otra. Esto se puede realizar mediante la colocación de -1, que se refiere al valor de $FFFF en TPMMOD (es una frecuencia muy alta, que el buzzer no reconocerá) y no emitirá sonido. Cuatro "-1" corresponden a 1 segundo. Sin embargo, lo mejor para generar silencios es tener una rutina que apague el buzzer cada vez que se reciba alguna letra o se deje de presionar algún botón, pues las frecuencias muy altas, dependiendo del reloj utilizado, pueden ser molestas o simplemente ser ruidos.

Generación de tonos usando PWM

#define PRESCALAR 0
#define MODULO 32768	//4Mhz / MODULO / 1 (prescaler) = aprox. 122Hz 
#define DUTY25 (MODULO/4)

void main(void)
{
    // Inicializaciones 
   SOPT1_COPE=0;      			/*Desabilitar el watchdog*/
   ADCSC1 = 0x20; 			// Se selecciona el canal ADCH0, Se selecciona modo de conversion continua y se habilitan las interrupciones 
   ADCSC2 = 0x00; 			// Se deshabilita la funcion de comparacion y se selecciona el software trigger
   ADCCFG = 0x40; 			// Se selecciona Long Sample time y se divide el Bus Clock entre 2
   APCTL1 = 0x00; 			// Se deshabilita el puerto asociado al canal ADCH0 ya que esta siendo usado como entrada analogica 
   ADCCFG_MODE=1;     			/*12bit conversion*/
    //inicializacion pwm
TPM1SC_CLKSA = 1;			// Se elige como source del reloj para el TPM el "Bus Rate Clock"    

TPM1SC_CLKSB = 0;    

TPM1SC_PS = PRESCALAR;			//y dividido entre 1    

TPM1MOD = MODULO; 			// Se guarda el valor del modulo para el contador    

TPM1C0SC_MS0B = 1; 			// Se elige la modalidad "PWM edge aligned"    

TPM1C0SC_ELS0A = 1;			// Corresponde a la configuración de pulso "Low-True"    

TPM1C0V = DUTY25;			// Con esto obtendremos un duty cycle aprox del 25%
    
    for(;;)
    { 
          ADCSC1_ADCH=0x0;
          while(ADCSC1_COCO==0); 	// Esperar que la conversion se ejecute 
          TPM1MOD = ADCR;		//Cambio el Valor del módulo 
	  TPM1C0V = TPM1MOD/4; 		//25%dutycicle
      }
}


Nota: Falta probar el código

Generación de tonos manual (sin RTC)

  • Los primeros pasos de inicialización son exactamente iguales con o sin RTC


  • Al momento de implementar las interrupciones, si no se posee el conocimiento para usar el RTC también se puede crear un periodo “manualmente”, se debe tener como parámetro la cantidad de ciclos de reloj que tendrá la onda cuadrada. Luego se debe “sincronizar” el tiempo que tarda cada instrucción del programa con respecto a la cantidad de ciclos de la onda. Para poder completar los ciclos faltantes (la onda usualmente se toma más ciclos de reloj que las instrucciones de cambio de periodo) se pueden utilizar “nops” iterados dentro de las mismas instrucciones si se trata de assembler, o ciclos si se trabaja con C.


  • Se puede utilizar una tabla de frecuencias para cada “nota” que se desea, si se quiere hacer un sonido específico ( esto para cuando se desea generar más de un tono), el programa leerá estas variaciones y las tomará como un cambio en el periodo, que en sí es lo que define que nota tomará como salida el buzzer.


  • Aunque es posible generar una onda de esta manera, es mejor utilizar el RTC pues este diseño es muy poco eficiente y se desperdicia la verdadera capacidad del DEMOQE128.


Un ejemplo de este diseño sería:

;************************************************************************** ;           
;*** Rutina de generación de ondas cuadradas, de 30 ciclos de reloj *******;
;*** se llevará a cabo tantas veces como indique PERIODO,           ******* ;           
;*** Luego negará la salida del ''Buzzer'' y repetirá el conteo de PERIODO ****;
;*** 30 ciclos * 250 ns (Tiempo de cada ciclo) = 7.5uS    *****************;
;**************************************************************************;            

MOV 0, COUNTER;
MOV 0, COUNTER_2

Flanco:     NOP                   ;1 ciclo - Los NOP son para compensar los Ciclos usados en cambiar el Flanco.
            LDA COUNTER 
            INCA
            STA COUNTER
            BNE COUNTER, #12,Flanco                   
                        
Cambio:     NOP                   
            LDA COUNTER 
            INCA
            STA COUNTER
            BNE COUNTER, #10,Cambio  
                               
            AIX #-1                ;2 ciclos.
            CPHX #$0000           ;3 ciclos - Revisa si el contador llega a cero, compare HX con el valor.
            BNE Flanco            ;3 ciclos - Si aun no se termina el periodo, decrementar contador, NECESITA DE  RESULTADO DE LA Función anterior para actuar.
            
            COM PTBD              ;5 ciclos.
            LDHX periodo          ;5 ciclos.
            BRA  Cambio           ;3 ciclos - Si ya terminó el periodo, pasar al siguiente flanco.
            

;**************************************************************

Para el uso de esta instrucción también se necesita el uso de una tabla de frecuencias que representen una escala de notas o tonos, el programa leerá la "canción"que no será más que una combinación de las frecuencias de la tabla y las traducirá a cambios en periodo como se mencionó anteriormente. un modelo de dicha tabla podría ser:

;Tabla de Notas musicales ordenadas por octava: do, do#,re,re#,mi,fa,fa#,sol,sol#,la,la#,si 
                    ;do, do#,re,re#,mi, fa, fa#,sol,sol#,la,la#,si
SILENCIO:   DC.W    $FFFF
OCTAVA1:    DC.W    509,480,454,428,403,381,359,339,320,302,285,269    ;3
OCTAVA2:    DC.W    254,240,226,213,201,190,179,169,160,151,143,135  ;4
OCTAVA3:    DC.W    126,119,113,106,100,94,89,84,79,75,71,66       ;5
OCTAVA4:    DC.W    63,59,56,53,50,47,44,42,39,37,35,33          ;6

•Aun así se recomienda de nuevo no utilizar este método sino uno que implique la variación del periodo por medio de RTC, lo que haría que la cantidad de líneas de código de el programa disminuya significativamente ademas de ser la manera correcta de programar y aprovechar eficientemente las funciones del DEMOQE128.

Programa de Prueba

A continuación se puede observar un enlace a Youtube con un video de la implementación del buzzer, está programado para reproducir dos fragmentos de canciones del juego "ZELDA", primero "Serenade Of Water", luego, y con un silencio de segundo y medio, sonará un fragmento de "Song Of Storms".

http://www.youtube.com/watch?v=jyfUEQ8zmCY


Utilizando la configuración dada por el macro Medio:Notas_Musicales.pdf‎ es posible representar los siguientes ejemplos:

;Prueba desde Do4 hasta Si5
			
		Do4
		Redonda
		DoS4
		Redonda
		Re4
		Redonda
		ReS4
		Redonda
		Mi4
		Redonda
		Fa4
		Redonda
		FaS4
		Redonda
		Sol4
		Redonda
		SolS4
		Redonda
		La4
		Redonda
		LaS4
		Redonda
		Si4
		Redonda
		
		Do5
		Redonda
		DoS5
		Redonda
		Re5
		Redonda
		ReS5
		Redonda
		Mi5
		Redonda
		Fa5
		Redonda
		FaS5
		Redonda
		Sol5
		Redonda
		SolS5
		Redonda
		La5
		Redonda
		LaS5
		Redonda
		Si5
		Redonda




Pokemon_Heal:
		Silencio
		Corchea
		Fa4
		Negra
		Fa4
		Negra
		Fa4
		Corchea
		Do4
		Corchea
		La4
		Negra
		JMP Pokemon_Heal


TETRIS:

		Silencio
		Negra

		La5
		Corchea
		FaS5
		Semi_Corchea
		Sol5
		Semi_Corchea
		SolS5
		Corchea
		Sol5
		Semi_Corchea
		FaS5
		Semi_Corchea
		Mi5
		Corchea
		Mi5
		Semi_Corchea
		Sol5
		Semi_Corchea
		La5
		Corchea
		SolS5
		Semi_Corchea
		Sol5
		Semi_Corchea
		FaS5
		Corchea
		FaS5
		Semi_Corchea
		Sol5
		Semi_Corchea
		SolS5
		Corchea
		La5
		Corchea
		Sol5
		Corchea
		Mi5
		Corchea
		Mi5
		Negra
		Silencio
		Blanca
		JMP TETRIS

Referencias

Imágenes de los buzzers

DEMOQE128UM