viernes, 23 de mayo de 2014

Control sencillo PWM Arduino (Explicado)


La modulación por ancho de pulsos de una señal o fuente de energía es una técnica en la que se modifica el ciclo de trabajo de una señal periódica (una sinusoide o una cuadrada, por ejemplo), ya sea para transmitir información a través de un canal de comunicaciones o para controlar la cantidad de energía que se envía a una carga.
El ciclo de trabajo de una señal periódica es el ancho relativo de su parte positiva en relación con el período. Expresado matemáticamente:




D = \frac{\tau}{T}
D es el ciclo de trabajo
\tau es el tiempo en que la función es positiva (ancho del pulso)
T es el período de la función


Bien suficiente de teoría para poder comprender como funciona esto y sobre todo para darnos una idea de sus aplicaciones practicas pasemos a una explicación aun mas sencilla.

Hay ocasiones en que deseamos tener un control analógico donde la variación que se controla sea gradual, similar a un control de volumen por ejemplo  y el principal objetivo es precisamente ese, que el control sea gradual y no pase de estar en apagado a estar a tope, cuando se esta trabajando con microcontroladores ya sea un PIC, un ATMEL o Arduino, nosotros contamos con salidas que pueden tener únicamente 2 valores correspondientes a 0 y 1 lógico en valores respectivos de voltaje ausente y presente, es entonces cuando requerimos de la técnica de PWM que en esencia consiste únicamente en cambiar rápidamente de 1 a 0 durante su ejecución y cuyo control consiste en indicar cuanto tiempo se estará en 1 y cuanto tiempo se estará en 0 para calcular esto se tiene la sencilla formula D = \frac{\tau}{T}  donde  \tau es el tiempo que la función estará a 1 (voltaje) y T es el periodo de la función es decir un intervalo finito de tiempo de una señal, por ejemplo podríamos decir que nuestro periodo T es de de 1000ms y que nuestro \tau es de 200ms tendríamos que D=200ms/1000ms con un resultado D=.2 es decir se tendría un ciclo de trabajo de 20% por lo que si tenemos un motor en el pin de salida este estará 200ms en 5v y 800ms en 0v por consecuente el motor giraría a 20% de su velocidad máxima, como podemos ver esto resulta en algo sencillo donde solo tendríamos que variar el valor de \tau para cambiar el porcentaje de la velocidad de nuestro motor.


Bien ahora el codigo del programa y no hay mejor aprendizaje que la practica asi que a montarlo y probemoslo.


//**************************//
//    PWM ARDUINO SIMPLE    //
//**************************//

int motor=3;     //Declara Pin del motor


void setup()
{
  Serial.begin(9600); //Inicia la comunicacion serial
}

void loop() // la funcion loop se ejectua infinitamente mientras el microcontrolador tenga energia

{           
   if (Serial.available()){  // comprobamos si se recibio alguna instruccion por el puerto serial
  
      char a = Serial.read();  // la variable "a" sera donde guardemos el dato recibido por el puerto serie
      
      if (a>='0' && a<='9'){   //comprobamos que el valor este entre los comandos validos
   
        int velocidad = map(a,'0','9',0,255);  //Escalamos el valor ingresado a rango de PWM

        analogWrite(motor,velocidad);  //Asignamos el valor al pwm del motor

        Serial.print("El motor esta gira a velocidad: "); // imprimimos un mensaje en el monitor serial y la velocidad actual
        Serial.println(a);
      }
  }

}



Espero les aya sido de utilidad.



PIANO MUSICAL 8 NOTAS PIC16F84A



DESCRIPCIÓN:

Para este proyecto se tiene que programar el micro controlador como si fuera un mini-piano con 8 notas musicales. Se usara el Puerto B como entrada, así que se deben activar la resistencias pull-up (internas del micro controlador). La señal es una onda cuadrada que sale por el pin 0 del Puerto A hacia una bocina de 8 ohms. Se usan retardos para representar los unos y ceros de la señal. Las frecuencias son de la 5 octava de las notas musicales.

CIRCUITO:

Este es el circuito utilizado para esta proyecto.  En el PIC16F84A, 8 botones van a sus respectivas entradas en el PORTB, sin resistencias, porque, por medio del código, se han activado las resistencias pull-up internas. Por los otros extremos de éstos, están conectados a tierra. El MCLR está conectado a voltaje. La salida del Pin RA0 va hacia una resistencia de 10kOhms y de ahí a un transistor 2N2222. Un extremo va a tierra y el otro va a una bocina de 8Ohms, el otro pin de la bocina va conectado a voltaje. A los pines 15 y 16 va conectado el cristal de cuarzo de 4Mhz junto con 2 capacitores de 22pF.




MATERIAL:

-Microcontrolador PIC16F84A
-8 micro-switches de 2 terminales
-1 bocina de 8Ohms
-1 resistencia de 1KOhm
-1 transistor de metal 2N2222
-Cristal de cuarzo de 4 MHz
-2 capacitores de 22 pF
-Alambres
-Protoboard
-Fuente y sus cables


CÓDIGO DEL PROGRAMA:

https://mega.co.nz/#!IR0m2IxC!_7pjUpz1iiRUe5thIuR-8ZUBkdxv-15_MAp6Lk15k6o




CONCLUSIÓN:

Reforcé lo que había aprendido sobre las instrucciones de salto y de los retardos. Para hacer una señal, necesitamos hacer retardos, no utilizamos la frecuencia más que para hacer cálculos del tiempo. Las instrucciones de CALL siempre deben llevar un RETURN para evitar el STACK OVERFLOW que se presenta al utilizar muchos GOTO.


TEORIA SOBRE RESISTENCIAS PULL-UP Y FRECUENCIAS DE AUDIO


Una forma usual de producir pulsos es mediante pulsadores que necesitan de sus resistencias correspondientes de pull-up. El PIC16F84A permite configurar una resistencia de pull-up interna en cada una de las líneas del PuertoB, ahorrando estas necesarias resistencias externas se utilizan cuando se utilizan pulsadores u otros dispositivos externos de lectura. Para configurar esta resistencia hay que utilizar el bit NOT_RBPU del registro OPTION:

- /RBPU, (resistor Port B pull-up enable bit) Habilitación de las resistencias pull-up del Puerto B

-/RBPU=0. Habilita las resistencias del PULL-UP del Puerto B

-/RBPU=1. Deshabilita las resistencias de Pull-Up del Puerto B.

Por tanto, para activar las resistencias de Pull-Up del Puerto B basta con resetear el bit NOT_RBPU del registro OPTION utilizando la instrucción:

            bcf       OPTION_REG,NOT_RBPU.

Las resistencias pull up y pull down no son más que resistencias dispuestas en una configuración determinada. Dicha configuración determina si la resistencia es de pull up o pull down. Este tipo de configuración establece un estado lógico a la entrada de un circuito lógico cuando dicho circuito está en reposo, siendo para pull up un estado lógico alto y para pull down bajo. De esta forma, se evita falsos estados producidos por ruido eléctrico si dejáramos una entrada con un valor indeterminado.
En la configuración pull up, cuando el pulsador está en reposo, Vout será prácticamente Vcc pudiéndose considerar como nivel lógico alto. Ahora bien, cuando se pulsa un switch conectado a tierra, se deriva toda la corriente a masa, por tanto Vout será 0v, valor lógico bajo. Esto mismo ocurre con la configuración pull down pero a la inversa. Cuando el circuito esta en reposo, la caída de tensión en la resistencia conectada a tierra es prácticamente 0v que es la misma tensión de Vout. En ese momento tendremos un nivel lógico bajo. Al pulsar el switch conectado a vcc, la caída de tensión en la resistencia conectada a tierra ahora será Vcc, Vout será un nivel lógico alto.
Generalmente, se suele usar un valor de 10K para estas resistencias.
La frecuencia del sonido hace referencia a la cantidad de veces que vibra el aire que transmite ese sonido en un segundo. La unidad de medida de la frecuencia son los Hertzios (Hz). La medición de la onda puede comenzarse en cualquier punto de la misma.

Para que el ser humano pueda oír un determinado sonido su frecuencia debe estar comprendida entre los 20 y los 20 000 Hz.

La frecuencia del sonido está relacionada con la altura de la oscilación de la onda sonora. La altura del sonido es perceptible sólo si la frecuencia de su oscilación es la misma en un intervalo de tiempo mínimo. Los sonidos agudos tienen una altura más elevada y mayor frecuencia que los sonidos graves. La frecuencia del sonido de los tonos agudos oscila entre los 2000 y los 4000 Hz mientras los graves van desde los 125 a los 250 Hz. Los tonos medios tienen una frecuencia de oscilación entre 500 a 1000 Hz.













sábado, 29 de marzo de 2014

Control de Arduino por MATLAB (Serial)



Hoy comparto sencillo código y una breve explicación de como comunicarnos con Arduino por medio de MATLAB, para quien aun no lo sabe esta comunicación se da por medio del puerto serial de Arduino es decir tanto el como con MATLAB tienen la posibilidad de enviar y recibir datos a través de puerto COM bueno comencemos primero con la parte de MATLAB.

PS=serial('COM12');
set(PS,'Baudrate',9600); % se configura la velocidad a 9600 Baudios
set(PS,'StopBits',1); % se configura bit de parada a uno
set(PS,'DataBits',8); % se configura que el dato es de 8 bits, debe estar entre 5 y 8
set(PS,'Parity','none'); % se configura sin paridad
set(PS,'Terminator','CR/LF');% “c” caracter con que finaliza el envío 
set(PS,'OutputBufferSize',2); % ”n” es el número de bytes a enviar
set(PS,'InputBufferSize' ,2); % ”n” es el número de bytes a recibir
set(PS,'Timeout',5); % 5 segundos de tiempo de espera


fopen(PS);
b='e';
for v=1:10

b =input('Ingrese comando: ','s');

for j=1:1
fwrite(PS,b,'uchar');
end

end
fclose(PS); 
delete(PS);
clear PS;

Como podemos ver el código es bastante sencillo y lo primero que tenemos que realizar es la configuración de transmisión de datos como velocidad, paridad, bits de parada, etc.  Arduino debe tener la misma velocidad de transmisión y configuración para que la comunicación se pueda dar.

// La funcion "fopen(); nos abre la comunicación del puerto
fopen(PS);

// Esta es la parte central del programa aquí declaramos una variable de cadena que estaremos editando por medio del serial durante 10 veces es decir no pedirá ingresar un comando en 10 ocasiones donde nosotros podremos enviar cualquier carácter o letra para que el Arduino lo reciba e interprete.
b='e';
for v=1:10

b =input('Ingrese comando: ','s');

for j=1:1
fwrite(PS,b,'uchar');
end

end

//La funcion "fclose(); nos cierra la comunicación del puerto
fclose(PS); 
delete(PS);


clear PS;

Esto seria todo en la parte de MATLAB, el código de Arduino lo dejo en la parte de abajo confió que no tendrán ningún problema en entenderlo lo único que hace es estar a la espera de recibir por medio del puerto serial ya sea una 'e' o una 'd' para encender o apagar el PIN13 donde tenemos un LED.

int lucesA = 13;              
char tecla;
  void setup() {
                pinMode(lucesA, OUTPUT);
                Serial.begin(9600);            // Inicializamos el puerto serial a 9600 baudios
               }


  void lucesA_on() {
                    digitalWrite(lucesA, HIGH);
                   }

  void lucesA_off() {
                     digitalWrite(lucesA, LOW);
                    }

  void Comando() {
                  if (Serial.available()) {
                                           tecla = Serial.read();
                                          }
                  if (tecla == 'd') { // luces altas on
                                     lucesA_on();
                                    } 
                  else if (tecla == 'e') { // luces altas off
                                          lucesA_off();
                                         }
                 }

  void loop() { //ciclo infinito de muestreo de la variable Val para el Switch de casos
               Comando();
              }

Espero les sirva saludos.

jueves, 6 de marzo de 2014

Sumador en ensamblador PIC16F84A

DESCRIPCIÓN:
Lo que se hace en esta práctica es un sumador. El programa se hizo en ensamblador con ayuda del software MPLABX para obtener el *.hex. Éste le va a sumar 15 al dato que se encuentre en el PORTA y se mostrara en el PORTB.


CIRCUITO:


Este es el circuito básico que se usó. En lugar de una barra de LEDs, se usaron LEDs individuales. El RESET o MCLR va conectado a voltaje. Los pines 15 y 16 van conectados al cristal de cuarzo de 4 MHz, junto con los capacitores 22 pF. Los pines de RA van conectados a un dipswitch, al cual se conectan resistencias de 10 Kohms. Los pines RB se conectaron a resistencias de 330 Ohms y de ahí a los LEDs

MATERIAL:
-Microcontrolador PIC16F84A
-8 LEDs
-8 resistores de 330 ohms
-1 dipswitch de 8
-5 resistores de 10 Kohms
-Cristal de cuarzo de 4 MHz
-2 capacitores de 22 pF
-Alambres
-Protoboard
-Fuente y sus cables

CODIGO DEL PROGRAMA:
;---------------------------------------------------------------------------
;Descripcion: Lea un dato por el puerto A PORTA, sumele una constante igual 15.
; Guardelo en una variable, muestrelo en el puerto B PORTB.

;
;Funciona: version 1.0 no
;---------------------------------------------------------------------------
;Configuracion MPLABX
__CONFIG _CP_OFF & _WDT_OFF & _PWRTE_ON & _XT_OSC
LIST P=16F84A
INCLUDE <P16F84A.INC>

K_Const EQU 0x0F ;definiendo una constante
V_Dato EQU 0x0C ;definiendo una variable
;---------------------------------------------------------------------------
;Zona de configuracion del PIC
ORG 0x00
Inicio bsf STATUS,RP0 ;Accesando al banco 1
clrf TRISB ;PORTB como salida
movlw 0xFF ;cargando la cte
movwf TRISA ;puerto A como salida
bcf STATUS,RP0 ;acceso al banco 0
;---------------------------------------------------------------------------
Main movf PORTA,W ;leer el dato
addlw K_Const ;suma el dato mas 15
movwf V_Dato ;guarda el resultado
movwf PORTB ;muestra el resultado
goto Main ;fin del programa y $=salta a el mismo
END
;------------------------------------------------------------------------------------------

TEORÍA SOBRE INSTRUCCIONES DE CARGA:
Las instrucciones de transferencias de datos son típicas de todos los procesadores su misión es transferir el contenido de un registro fuente (f) a un registro destino (d) o bien cargar el destino con una constante. En los microcontroladores PIC todos los datos residen en posiciones de la memoria de datos en el registro de trabajo W.
En la explicación de estas instrucciones se emplea muchas veces una nomenclatura especial muy simple basada en paréntesis y flechas. Con los paréntesis se destaca que se trata del “contenido” de las posiciones de memoria y la flecha de dirección de la transferencia de los datos.
Hay 5 instrucciones de carga propiamente dichas:
clrw: (clear W) El contenido del registro W se borra, es decir, se carga con b’00000000’ y el flag z se activa a “1”. Esta instrucción también se podría considerar como aritmética.
clrf f: (clear f) El contenido del registro ‘f’ se borra, se carga con b’00000000’ y el flag z se activa con ‘1’. Esta accion tambien se podria considerar como aritmetica.
movlw k: (Move Literal to W) El registro W se carga con el valor de los 8 bits de la constante ‘k’. Ningun flag del estado del registro de estado es afectado.
movf f,d: (move f) El contenido del registro ’f’ se carga en el registro destino dependiendo del valor de ‘d’. Si ‘d’ = 0 el destino es el registro W, si ‘d’ = 1 el destino es el propio registro ‘f’. El flag z del registro STATUS queda afectado: z se activa a ‘1’ si el resultado de la operación es cero.
movwf f: (Move W to f) Carga el contenido del registro W al registro ‘f’. Ningun flag del registro de estado es afectado.

miércoles, 5 de marzo de 2014

PIANO DIGITAL CON AT89LP3240/6440

// INSTITUTO DE INGENIERIA Y TECNOLOGIA (IIT/UACJ) //
// SISTEMAS CON MICROPROCESADOR // IVAN MENDOZA 103405
#include <at89lp6440.h>

void config (void)
{ //--------------- CONFIGURACION DE PUERTOS ----------------------//
//entradas
P1M0=0XFF;    //TECLAS TONOS DO-RE-MI-FA-SOL-LA-SI-SI#
P1M1=0X00;

P3M0=0X0E;    //SELECCION DE OCTAVA 0-1-2-3-4-5
P3M1=0X10;

//salidas
P0M0 =0x00;    //LED TONOS DO-RE-MI-FA-SOL-LA-SI-SI#
P0M1 =0xFF;

P2M0 =0x00;   //LED OCTAVAS 0-1-2-3-4-5
P2M1 =0xFF;
//--------------------------------------------------------------//
// TIMER E INTERRUPCIONES
TMOD=0x10;
P3_7=1;
EA=1;
ET1=1;
TR1=0;
TCONB=0x00;
  CLKREG=0x00;
}
///////////////////// FUNCIONES TONOS /////////////////////////////////
void DO(void){
if(P3_3==0&&P3_2==0&&P3_1==0)
{
RH1=0XA6;
RL1=0X33;
TR1=1;
}
else if(P3_3==0&&P3_2==0&&P3_1==1)
{
P2_7=1;
RH1=0XD3;
RL1=0X19;
TR1=1;
}
else if(P3_3==0&&P3_2==1&&P3_1==0)
{
P2_6=1;
RH1=0XE2;
RL1=0X11;
TR1=1;
}
else if(P3_3==0&&P3_2==1&&P3_1==1)
{
P2_5=1;
RH1=0XE9;
RL1=0X8C;
TR1=1;
}
else if (P3_3==1&&P3_2==0&&P3_1==0)
{
P2_4=1;
RH1=0XEE;
RL1=0X6A;
TR1=1;
}
else if(P3_3==1&&P3_2==0&&P3_1==1)
{
P2_3=1;
RH1=0XF1;
RL1=0X08;
TR1=1;
}
P3_4=0;
TR1=0;
}
void RE(void){
if(P3_3==0&&P3_2==0&&P3_1==0)
 {
RH1=0XB0;
 RL1=0X47;
TR1=1;
    }
else if(P3_3==0&&P3_2==0&&P3_1==1)
{P2_7=1;
RH1=0XD8;
RL1=0X23;
TR1=1;
}
else if(P3_3==0&&P3_2==1&&P3_1==0)
{P2_6=1;
RH1=0XE5;
RL1=0X6C;
TR1=1;
}
else if(P3_3==0&&P3_2==1&&P3_1==1)
{P2_5=1;
RH1=0XEC;
RL1=0X11;
TR1=1;
}
else if(P3_3==1&&P3_2==0&&P3_1==0)
{P2_4=1;
RH1=0XF0;
RL1=0X0E;
TR1=1;
}
else if(P3_3==1&&P3_2==0&&P3_1==1)
{P2_3=1;
RH1=0XF2;
RL1=0XB6;
TR1=1;
}

P3_4=0;
TR1=0;
}
void MI(void){
if(P3_3==0&&P3_2==0&&P3_1==0)
 {
RH1=0XB8;
 RL1=0XFA;
TR1=1;
    }
else if(P3_3==0&&P3_2==0&&P3_1==1)
{P2_7=1;
RH1=0XDC;
RL1=0X7D;
TR1=1;
}
else if(P3_3==0&&P3_2==1&&P3_1==0)
{P2_6=1;
RH1=0XE8;
RL1=0X53;
TR1=1;
}
else if(P3_3==0&&P3_2==1&&P3_1==1)
{P2_5=1;
RH1=0XEE;
RL1=0X3E;
TR1=1;
}
else if(P3_3==1&&P3_2==0&&P3_1==0)
{P2_4=1;
RH1=0XF1;
RL1=0XCB;
TR1=1;
}
else if(P3_3==1&&P3_2==0&&P3_1==1)
{P2_3=1;
RH1=0XF4;
RL1=0X29;
TR1=1;
}

P3_4=0;
TR1=0;
   


}
void FA(void){
if(P3_3==0&&P3_2==0&&P3_1==0)
 {
RH1=0XBC;
RL1=0XD8;
TR1=1;
    }
else if(P3_3==0&&P3_2==0&&P3_1==1)
{P2_7=1;
RH1=0XE9;
RL1=0X9C;
TR1=1;
}
else if(P3_3==0&&P3_2==1&&P3_1==0)
{P2_6=1;
RH1=0XEF;
RL1=0X35;
TR1=1;
}
else if(P3_3==0&&P3_2==1&&P3_1==1)
{P2_5=1;
RH1=0XF2;
RL1=0X95;
TR1=1;
}
else if(P3_3==1&&P3_2==0&&P3_1==0)
{P2_4=1;
RH1=0XF4;
RL1=0XCE;
TR1=1;
}
else if(P3_3==1&&P3_2==0&&P3_1==1)
{P2_3=1;
RH1=0XF6;
RL1=0X08;
TR1=1;
}

P3_4=0;
TR1=0;
   


}
void SOL(void){
if(P3_3==0&&P3_2==0&&P3_1==0)
 {
RH1=0XC4;
RL1=0X35;
TR1=1;
    }
else if(P3_3==0&&P3_2==0&&P3_1==1)
{P2_7=1;
RH1=0XE2;
RL1=0X1A;
TR1=1;
}
else if(P3_3==0&&P3_2==1&&P3_1==0)
{P2_6=1;
RH1=0XEC;
RL1=0X11;
TR1=1;
}
else if(P3_3==0&&P3_2==1&&P3_1==1)
{P2_5=1;
RH1=0XF1;
RL1=0X0D;
TR1=1;
}
else if(P3_3==1&&P3_2==0&&P3_1==0)
{P2_4=1;
RH1=0XF4;
RL1=0XCE;
TR1=1;
}
else if(P3_3==1&&P3_2==0&&P3_1==1)
{P2_3=1;
RH1=0XF6;
RL1=0X08;
TR1=1;
}

P3_4=0;
TR1=0;
   


}
void LA(void){
if(P3_3==0&&P3_2==0&&P3_1==0)
 {
RH1=0XCA;
RL1=0XBB;
TR1=1;
    }
else if(P3_3==0&&P3_2==0&&P3_1==1)
{P2_7=1;
RH1=0XE5;
RL1=0X5D;
TR1=1;
}
else if(P3_3==0&&P3_2==1&&P3_1==0)
{P2_6=1;
RH1=0XEE;
RL1=0X3E;
TR1=1;
}
else if(P3_3==0&&P3_2==1&&P3_1==1)
{P2_5=1;
RH1=0XF2;
RL1=0XAE;
TR1=1;
}
else if(P3_3==1&&P3_2==0&&P3_1==0)
{P2_4=1;
RH1=0XF5;
RL1=0X58;
TR1=1;
}
else if(P3_3==1&&P3_2==0&&P3_1==1)
{P2_3=1;
RH1=0XF7;
RL1=0X1E;
TR1=1;
}

P3_4=0;
TR1=0;
   


}
void SI(void){
 if(P3_3==0&&P3_2==0&&P3_1==0)
 {
RH1=0XD0;
RL1=0X8D;
TR1=1;
    }
else if(P3_3==0&&P3_2==0&&P3_1==1)
{P2_7=1;
RH1=0XE8;
RL1=0X46;
TR1=1;
}
else if(P3_3==0&&P3_2==1&&P3_1==0)
{P2_6=1;
RH1=0XF0;
RL1=0X2E;
TR1=1;
}
else if(P3_3==0&&P3_2==1&&P3_1==1)
{P2_5=1;
RH1=0XF4;
RL1=0X23;
TR1=1;
}
else if(P3_3==1&&P3_2==0&&P3_1==0)
{P2_4=1;
RH1=0XF6;
RL1=0X82;
TR1=1;
}
else if(P3_3==1&&P3_2==0&&P3_1==1)
{P2_3=1;
RH1=0XF8;
RL1=0X17;
TR1=1;
}
P3_4=0;
TR1=0;
   


}
void SII(void){
if(P3_3==0&&P3_2==0&&P3_1==0)
 {
RH1=0XD3;
RL1=0X2F;
TR1=1;
    }
else if(P3_3==0&&P3_2==0&&P3_1==1)
{P2_7=1;
RH1=0XE9;
RL1=0X97;
TR1=1;
}
else if(P3_3==0&&P3_2==1&&P3_1==0)
{P2_6=1;
RH1=0XF1;
RL1=0X0F;
TR1=1;
}
else if(P3_3==0&&P3_2==1&&P3_1==1)
{P2_5=1;
RH1=0XF4;
RL1=0XCB;
TR1=1;
}
else if(P3_3==1&&P3_2==0&&P3_1==0)
{P2_4=1;
RH1=0XF7;
RL1=0X09;
TR1=1;
}
else if(P3_3==1&&P3_2==0&&P3_1==1)
{P2_3=1;
RH1=0XF8;
RL1=0X87;
TR1=1;
}

P3_4=0;
TR1=0;
   


}


//////////////////////////////////////////////////////////////////////

// INICIO DE PROGRAMA //
void main (void)
{
  config(); // llamamos a la funcion para cargar configuracion
while(1)
{ P0=0;
P2=0;
// int tono=P1;    //tonos de la octava do-re-mi-fa-sol-la-si-si#
switch(P1)
{
case 1://DO
P0_0=1; DO();
break;

case 2://RE
P0_1=1; RE();
break;

case 4://MI
P0_2=1; MI();
break;

case 8://FA
P0_3=1; FA();
break;

case 16://SOL
P0_4=1; SOL();
break;

case 32://LA
P0_5=1; LA();
break;

case 64://SI
P0_6=1; SI();
break;

case 128://SI#
P0_7=1; SII();
break;

case 0:
P3_4=0;
break;
}
}
}
void int_timer_1(void) interrupt 3
{
P3_4=~P3_4;//conmutacion
}