viernes, 28 de febrero de 2014

COMPARADOR ANALOGICO

                 El siguiente programa presentado tiene como único fin mostrar el uso básico del comparador analógico del microcontrolador AVR, en mi caso del microcontrolador ATMEGA48, esto con el fin de dar a conocer el funcionamiento para una posterior practica donde se hará un uso mas complejo de esta función, esperando utilizar en la medición de distancia con ayuda de un sensor ultrasonido y el comparador analógico.  


DESCRIPCIÓN:

                      El programa es realizado en si es facil de entender pero para facilitar la comprensión de la practica a realizar posteriormente se explicara en esta ocasión su estructura de forma detallada.

COMPARADOR();
                          
                          Esta función realiza la configuración de funcionamiento de nuestro comparador analógico. Primeramente se habilita el bit ADEN del registro ADCSRA  y el bit ACME del registro ADCSRB para permitir utilizar el pin AIN1 como entrada negativa del comparador. También podría dejarse estos bits sin habilitar y el programa funcionaria como se espera, pero se indica para su comprensión mas clara, sobre todo para poder explicar que la entrada negativa puede cambiarse por cualquiera de las entradas analógicas del ADC mediante multiplexion, esto se logra seteando el bit ACME del registro ADCSRB y des-habilitando el bit ADEN del registro ADCSRA, al realizarse esto se elige la entrada negativa del comparador con ayuda del registro ADMUX donde se configurara la entrada que se desea utilizar con los bits MUX2..0. 

//SELECCION DEL MODO DE INTERRUPCION DE COMPARADOR ANALOGICO
//Comparator interrupt on falling output edge
setbit(ACSR,ACIS1);
setbit(ACSR,ACIS0);

                           Los bits ACSI1 y ACSI0 del registro ACSR, estos bits determinar qué eventos de comparación desencadenaran la interrupción del Comparador Analógico.



                               Es importante configurar el funcionamiento de estos bits antes de habilitar la interrupción del comparador analógico, de no ser así la interrupción ocurrirá cuando se cambien los bits.

        //HABILITAR INTERRUPCIÓN DEL COMPARADOR ANALÓGICO
setbit(ACSR,ACIE);
sei();
                     
                            Una vez realizado lo anterior se habilita la interrupción local del comparador analógico, y enseguida la comparación global sei();.

        setbit(DDRB,DDB0);
clearbit(PORTB,PB0);

                               A continuación se declara como salida el pin PB0 del puerto B y se inicializa en nivel bajo.

//INTERRUPCION
ISR (ANALOG_COMP_vect){
bittoggle(PORTB,PB0);
}

                              Se realiza la rutina de interrupción la cual únicamente para ser un caso ilustrativo cambiara el estado del pin de salida PB0 cada vez que el comparador detecte un flanco de subida, es decir cada vez que la entrada positiva cambie a ser mayor que la entrada negativa.

NOTA:
                                        Al final se colocaran tanto el programa del microcontrolador como su simulación en ISIS para observar el comportamiento del mismo, cualquier duda o sugerencia puede ingresarla en los comentarios.

PROGRAMA:


/*
 * comparador_analogico.c
 *
 * Created: 28/02/2014 22:39:47
 *  Author: TERRAFORMARS
 */ 


#include <avr/io.h>
#ifndef F_CPU
#define F_CPU 8000000UL // XTAL de 8 MHz
#endif
#include <util/delay.h>
#include <avr/interrupt.h>

#define setbit(sfr,bit) (_SFR_BYTE(sfr)|=(_BV(bit)))
#define clearbit(sfr,bit) (_SFR_BYTE(sfr)&=~(_BV(bit)))
#define bittoggle(sfr,bit)(_SFR_BYTE(sfr)^=_BV(bit))

//INTERRUPCION
ISR (ANALOG_COMP_vect){
bittoggle(PORTB,PB0);
}

//COMPARADOR ANALÓGICO
void COMPARADOR(){
//UTILIAR AIN1 COMO ENTRADA NEGATIVA
setbit(ADCSRA,ADEN);
//HABILITACION DEL MULTIPLEXOR DEL COMPARADOR ANALOGICO
setbit(ADCSRB,ACME);

//SELECCION DEL MODO DE INTERRUPCION DE COMPARADOR ANALOGICO
//Comparator interrupt on falling output edge
setbit(ACSR,ACIS1);
setbit(ACSR,ACIS0);
//HABILITAR INTERRUPCION DEL COMPARADOR ANALOGICO
setbit(ACSR,ACIE);
sei();
}

int main(void)
{
COMPARADOR();
setbit(DDRB,DDB0);
clearbit(PORTB,PB0);
    while(1)
    {
        //TODO:: Please write your application code 
    }
}

IMÁGENES:

SIMULACIÓN EN ATMEL STUDIO


SIMULACIÓN EN ISIS PROTEUS


ENTRADA MULTIPLEXADA DEL COMPARADOR ANALÓGICO




LINK:

https://mega.co.nz/#!5wUVxD5D!9Sf30yPMwGVxnF8jhztRedMd1OEp1kvvCKo7PQqm8XE

sábado, 22 de febrero de 2014

CONTROL DE MOTOR CON MYOPENLAB Y USART

ACTUALIZADO          

          A continuación se realizara la demostración del control de un motor mediante el software MyopenLab e Isis Proteus, con ayuda de Configure Virtual Serial Port Driver para la creación de los puertos virtuales. Para comenzar se explicara con detalle lo que realizara el programa en MyopenLab y el realizado en el microcontrolador AVR, así como también los componentes y configuraciones añadidas al simulado ISIS PROTEUS. 


DESCRIPCIÓN:

MICROCONTROLADOR:

                  El programa en el microcontrolador esta dividido en dos partes principales, de las cuales una es interrupción para la captura de datos enviados por el software MyopenLab, la segunda es la lectura del canal 0 del ADC para mostrar de forma gráfica la posición de un potenciometro.

                  Programa realizado en  WHILE(1)

                El programa principal lee el valor de ADC0 y lo coloca en la variable analog una vez hecho esto se guarda el valor del mismo en tres variables que indicaran centenas, decenas y unidades cada una. A continuación se asignara el valor correspondiente en ASCII a tres variables mas con ayuda de funciones que determinaran el valor que corresponde. Se enviaran los datos por el puerto serial los cuales serán captados por el programa realizado en MyopenLab y serán tratados para ser mostrados por medio de un elemento visual.

analog=convADC();

pot1=analog/100;
pot2=(analog-100*pot1)/10;
pot3=analog-100*pot1-10*pot2;
centenas_pot();
decenas_pot();
unidades_pot();

                 La razón de la conversión del dato obtenido por el convertidor analógico es debido a que el visualizador analógico no lee el valor de la forma deseada debido a que de ser enviado el dato sin realizar estas operaciones lo que lee es un carácter en ASCII el cual no pertenece a los valores validos que puede recibir por lo que la segmentación del valor y su conversión de cada dato en su equivalente en ASCII permite al programa poder leer el valor numérico de forma correcta.
                 

                  Rutina de interrupción 

                  La interrupción se generara cada vez que halla un dato sin leer en el buffer de recepción para ello son los siguientes setbit(UCSR0B,RXCIE0); sei(); esto habilita la interrupción especifica y global respectivamente.
                    La rutina de interrupción lee el dato enviado por el programa y comprueba si es un dato valido, de ser así realiza lo que indique el case correspondiente y vuelve a su función normal. 
                   Algo que aclarar es que los datos que se aceptaran son los caracteres '1', '2' y '3' los cuales en decimal son 49, 50 y 51 respectivamente.
                    Esta interrupcion realiza la lectura de cuatro cracteres enviados por el programa los cuales determinaran el estado del motor (STOP, LEFT y RIGHT) con el primer caracter recibido; los tres caracteres restantes determinaran la velocidad a la que se movera el motor o actuador. Debido que son recibidos como caracteres individuales se realiza una operacion similar a la realizada dentro del ciclo WHILE con la diferencia de que se utilizan las funciones atoi();, strcpy();, strncpy();, de las librerias:

#include <stdlib.h>
#include <stdio.h>
#include <string.h>

                        Esto es para la conversión de los caracteres recibidos en su equivalente en byte para su uso mas eficiente en la manipulación de los registros principalmente del registro OCR0A el cual determina el ancho de pulso de la señal PWM y por lo tanto la velocidad del motor

MYOPENLAB:

                    El programa realizado utiliza el componente RS232 y se configuro para conectarse con el puerto virtual COM2 para realizar la comunicación con proteus y envía un dato el cual el programa en el microcontrolador lee y con ello cambia el estado del motor conectado al driver L293B para esto se utilizo convertidores de datos y se muestra el estado del motor mediante leds ademas de poder observarse la posicion de un potenciometro conectado al pin ADC0.

ISIS:
       
                    Dentro del entorno de ISIS se modificaron los parámetros del componente COMPIM que se encuentra en la librería de componentes, este dispositivo es util para conectar el puerto virtual COM1 al microcontrolador.


                    Los parámetros seleccionados deben ser los mismos con los que se configura la comunicación en el microcontrolador para el buen funcionamiento del proyecto, de no ser así el programa no funcionara.

PUERTOS VIRTUALES:

                   Con ayuda del programa Configure Virtual Serial Port Driver se crean dos puertos virtuales, para este caso COM1 y COM2 ademas de asegurarse de que se encuentren en el modo estándar.


NOTA:

                       Al final encontrara los links para descargar tanto el programa del microcontrolador así como el realizado en MyopenLab, esto también se puede realizar en Labview si desea crear su propio programa con ayuda del realizado puede hacerlo.
                       Alguna duda o aclaración puede ingresarla en los comentarios


 /*
 * motorConCadena.c
 *
 * Created: 24/02/2014 17:14:30
 *  Author: TERRAFORMARS
 */ 


#include <avr/io.h>
#ifndef F_CPU
#define F_CPU 8000000UL // XTAL de 8 MHz
#endif
#include <util/delay.h>
#include <avr/interrupt.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "UARTAiNit.h"
#include "TIMER0.h"
#include "InitADC.h"
#define setbit(sfr,bit) (_SFR_BYTE(sfr)|=(_BV(bit)))
#define clearbit(sfr,bit) (_SFR_BYTE(sfr)&=~(_BV(bit)))
#define bittoggle(sfr,bit)(_SFR_BYTE(sfr)^=_BV(bit))

unsigned char tempo=0,analog,velocidad=0,i=0,t=1,pot1,pot2,pot3,l,c;
unsigned char a[5]={0},b[5]={0},v1=0,v2=0,v3=0,temp[5]={0},vel0[3]={0},vel1[1]={0},vel2[1]={0},vel3[1]={0},potenciometro[5]={0};
unsigned int vel;
ISR (USART_RX_vect){
//RECIBIR DATO
for(i=0;i<4;i++){
a[i]=ReceiveUART0();
}

//CONVERTIR A CHAR

stringToChar();
//ESTADO DEL MOTOR
switch(tempo){

case 1:
//MOTOR IZQUIERDA
setbit(PORTB,PB1);
COMPAREA_FASTA(2);
clearbit(PORTD,PD5);
break;
case 3:
//MOTOR DERECHA
setbit(PORTB,PB1);
COMPAREA_FASTA(3);
setbit(PORTD,PD5);
break;
case 2:
//MOTOR STOP
clearbit(PORTB,PB1);
vel=65538;
break;
}
if (tempo==1||tempo==2||tempo==3)
{
//CAMBIO DE VELOCIDAD
OCR0A=vel;
}
//borrar();
}

//converir de cadena a char de 8 bits
void stringToChar(){

//ESTADO
strcpy(b,a);
strncpy(temp,b,1);
tempo=atoi(temp);

    //VELOCIDAD
strcpy(b,a);
vel1[0]=b[1];
vel2[0]=b[2];
vel3[0]=b[3];

centenas();
decenas();
unidades();

vel=v1+v2+v3;
     
if (velocidad>=256){velocidad=259;}
if (velocidad>=65534){velocidad=65530;}
/////////////////////

}

void centenas(void){

switch(vel1[0]){

case '2':
v1=200;
break;
case '3':
v1=300;
break;
case '4':
v1=400;
break;
case '5':
v1=500;
break;
}
}

void decenas(void){

switch(vel2[0]){

case '0':
v2=0;
break;
case '1':
v2=10;
break;
case '2':
v2=20;
break;
case '3':
v2=30;
break;
case '4':
v2=40;
break;
case '5':
v2=50;
break;
case '6':
v2=60;
break;
case '7':
v2=70;
break;
case '8':
v2=80;
break;
case '9':
v2=90;
break;
}
}


void unidades(void){

switch(vel3[0]){

case '0':
v3=0;
break;
case '1':
v3=1;
break;
case '2':
v3=2;
break;
case '3':
v3=3;
break;
case '4':
v3=4;
break;
case '5':
v3=5;
break;
case '6':
v3=6;
break;
case '7':
v3=7;
break;
case '8':
v3=8;
break;
case '9':
v3=9;
break;
}
}


void unidades_pot();
void decenas_pot();
void centenas_pot();
//MAIN

int main(void)
{
initADC(2,1,6);
canalADC(0);
initializeUART0(9600,0,8,2,2);
initTIMER0_FAST1();
PREESCALL(3);
COMPAREA_FASTA(2);
setbit(DDRD,DDD5);
setbit(DDRD,DDD6);
clearbit(PORTD,PD5);
setbit(DDRB,DDB1);
setbit(UCSR0B,RXCIE0);
sei();
    while(1)
    {
  
analog=convADC();

pot1=analog/100;
pot2=(analog-100*pot1)/10;
pot3=analog-100*pot1-10*pot2;
centenas_pot();
decenas_pot();
unidades_pot();
//for (c=0;c<2;c++)
//{

for (l=0;l<3;l++)
{
TransmiteUART0(potenciometro[l]);
}
//}
_delay_ms(200);
    }

}


void centenas_pot(void){

switch(pot1){

case 2:
   potenciometro[0]='2';
break;
case 1:
potenciometro[0]='1';
break;
case 0:
potenciometro[0]='0';
break;
}
}

void decenas_pot(void){

switch(pot2){

case 0:
potenciometro[1]='0';
break;
case 1:
   potenciometro[1]='1';
break;
case 2:
   potenciometro[1]='2';
break;
case 3:
   potenciometro[1]='3';
break;
case 4:
   potenciometro[1]='4';
break;
case 5:
   potenciometro[1]='5';
break;
case 6:
   potenciometro[1]='6';
break;
case 7:
   potenciometro[1]='7';
break;
case 8:
   potenciometro[1]='8';
break;
case 9:
   potenciometro[1]='9';
break;
}
}


void unidades_pot(void){

switch(pot3){

case 0:
potenciometro[2]='0';
break;
case 1:
potenciometro[2]='1';
break;
case 2:
potenciometro[2]='2';
break;
case 3:
potenciometro[2]='3';
break;
case 4:
potenciometro[2]='4';
break;
case 5:
potenciometro[2]='5';
break;
case 6:
potenciometro[2]='6';
break;
case 7:
potenciometro[2]='7';
break;
case 8:
potenciometro[2]='8';
break;
case 9:
potenciometro[2]='9';
break;
}
}




IMÁGENES:













PROGRAMA EN ATMEL STUDIO


INTERFAZ CREADA EN MYOPENLAB


SIMULACIÓN DE MAYOPENLAB E ISIS PROTEUS

MOTOR STOP


MOTOR RIGHT



 MOTOR LEFT





PROGRAMA EN ISIS PROTEUS


VÍDEO DEMOSTRATIVO DE FUNCIONAMIENTO



LINKS:

programa del microcontrolador (ACTUALIZADO)
https://mega.co.nz/#!Z4sizQaQ!GUyYZxaatlA7uQLbERorS6fiWk1gZSTm8n7V-WB7-gI

programa en MyopenLab (ACTUALIZADO)
https://mega.co.nz/#!d9twAaxa!O9iNtXYLsdidFbIfXtXeW4Jdcmy70sXYYbTltSGXGWY

si por alguna razón desean obtener los programas anteriores se encuentran a continuación.

programa del microcontrolador
https://mega.co.nz/#!48ll0ApY!YbdodDoA4tHVn70r0frRwUc4PeBTkU9kwfOJ5kWSi6k

programa en MyopenLab
https://mega.co.nz/#!cxkSzAID!clVxvzSyVH7d3e3YjQ3RlV42efhqmzK3SHbtjsPfUCA


sábado, 15 de febrero de 2014

Comunicación entre microcontroladores AVR

           La practica que se mostrará a continuación hará uso del modulo ADC y del USART0 del microcontrolador AVR, con el fin de realizar el envió de datos de un microcontrolador a otro, para demostrar el funcionamiento en tiempo real de la comunicación serial. 
                  La practica constan de dos microcontroladores, el primero ha sido programado para el envió del valor captado por el canal 0 del ADC, el segundo programa realiza la recepción de los datos lo utiliza para determinar el ancho de pulso que tendrá el timer0 en modo fast PWM.

                  DESCRIPCIÓN DEL PROGRAMA

                  PROGRAMA 1
                  Para comenzar se describirá el programa 1 el cual realiza la captura del voltaje analógico y envía por medio del UART.
              
                  canalADC(0);
            initADC(2,1,5);

                  Estas funciones lo que realizan es la selección del canal que utilizara el ADC para la conversión y la configuración del ADC para su funcionamiento en modo corrida libre, el voltaje de referencia es definido por el numero 2, la justificación del resultado adquirido por el ADC se configura a la izquierda para únicamente aceptar 8 bits de información con el numero 1, y se configura el reloj de la conversión con preescalamiento 32 con el numero 5.

            initializeUART0(9600,0,8,2,2);

                  Se inicializa el modulo de comunicación serial con los siguientes parámetros:
  1. Baudrate de 9600.
  2. Modo normal asíncrono.
  3. 8 bits de datos.
  4. Sin paridad.
  5. 2 bits de stop.

             Estos parámetros deben ser los mismos para ambos programas para poder realizar la comunicación.

                 PROGRAMA 2

                 La función del segundo programa es la de recepción de los datos y actualización del registro OCR0A con lo que se variara el ancho de pulso de modo fast PWM.

               initTIMER0_FAST1();
   COMPAREA_FAST(2);
   PREESCALL(5);
     
             El timer0 se configura para funcionar en modo fast PWM, con un preescalamiento de 1024 lo cual se consigue ingresando 5 en la función, en cuanto al modulo al haber coincidencia de los registros TCNT0 y OCR0A es la de cambiar el estado de la salida del pin PD6. No se debe de olvidar declarar el pin del PWM como salida de no ser así el programa no funcionara como es debido.             

    NOTA: Al final colocare el link de ambos programas y su simulación en proteus, alguna duda o sugerencia puede colocarla en los comentarios.

                    


                  PROGRAMA 1

/*
 * pot_uart_pwm.c
 *
 * Created: 08/02/2014 17:42:48
 *  Author: TERRAFORMARS
 */ 


#include <avr/io.h>
#ifndef F_CPU
#define F_CPU 8000000UL // XTAL de 8 MHz
#endif
#include "InitADC.h"
#include "UARTAiNit.h"
#include <util/delay.h>

unsigned char n;


int main(void)
{
canalADC(0);
initADC(2,1,5);
initializeUART0(9600,0,8,2,2);
    while(1)
    {
        //TODO:: Please write your application code 
n=convADC();
TransmiteUART0(n);
_delay_ms(20);
    }
}




                 PROGRAMA 2

/*
 * pot_pwm.c
 *
 * Created: 08/02/2014 17:59:39
 *  Author: TERRAFORMARS
 */ 


#include <avr/io.h>
#ifndef F_CPU
#define F_CPU 8000000UL // XTAL de 8 MHz
#endif
#include "UARTAiNit.h"
#include "TIMER0.h"
#define setbit(sfr,bit) (_SFR_BYTE(sfr)|=(_BV(bit)))
#define clearbit(sfr,bit) (_SFR_BYTE(sfr)&=~(_BV(bit)))
#define bittoggle(sfr,bit)(_SFR_BYTE(sfr)^=_BV(bit))
unsigned char n;

int main(void)
{
initTIMER0_FAST1();
COMPAREA_FAST(2);
PREESCALL(5);
initializeUART0(9600,0,8,2,2);
setbit(DDRD,DDD6);
    while(1)
    {
        //TODO:: Please write your application code 
n=ReceiveUART0();
OCR0A=n;
    }
}



                       IMÁGENES



diagrama de funcionamiento del modo fast PWM


PROGRAMA 1 Y 2 EN ATMEL STUDIO




LINK

https://mega.co.nz/#!owsBBDaJ!hU9gfNqtSdxJ85fLj0rVa4LEXhTwg_ho8xASBQOy4-U


ADC y salida binaria con int1

El siguiente programa tiene por objetivo mostrar una forma simple del uso del ADC y de las interrupciones en particular la interrupción INT1 la cual ha sido utilizada en este momento para cambiar el modo de respuesta al valor del ADC, para ello se ha configurado para que las salidas muestren el valor de la entrada analógica en forma binaria o mediante la activación de las salidas de forma incremental.

DESCRIPCIÓN

El programa esta compuesto principalmente de tres partes para su funcionamiento, se dividirá la información para que la descripción sea mas legible.

1. ADC 
                  initADC(2,1,5);
                 
                  El ADC ha sido configurado para funcionar en el modo corrida libre; también utiliza como voltaje de referencia en el pin  AVcc conectado a una fuente de voltaje la cual sera considerada el voltaje de referencia superior, el voltaje de referencia menor sera en este caso GND conectando entre tierra y el pin Aref un capacitor, esto es principalmente para disminuir el ruido eléctrico. Para la lectura de los resultados se justificara el valor de la conversión a la izquierda para así solo tomar 8 bits de la conversión, de no desear esto puede cambiar el valor 1 que se ha declarado en la función por un 0. La siguiente parte configura el preescalamiento de reloj del ADC, en este programa sera de 32. 
                        
            canalADC(1);
                    
                 Se selecciona el canal deseado para realizar la conversión, en este caso sera el canal 1.

2. INTERRUPCIÓN

           cambio();
                 
                 Se habilita la interrupción externa INT1 configurada para funcionar en modo de flanco de bajada, esto significa que se realizara una interrupción únicamente si en el pin PD3 se ha aplicado un flanco de bajada.              

3. CICLO WHILE


            var=convADC();  
                 
                  Se realiza la lectura del canal 1 y a continuación dependiendo de el valor de la variable n se mostrara el modo salida binaria o el incremento de las salidas.

Alguna duda o sugerencia pueden ingresarla en los comentarios.

Nota:
        El programa completo y la simulación serán puestos al final para ser descargado.

PROGRAMA

/*
 * ADC_LEDS.c
 *
 * Created: 02/02/2014 18:33:01
 *  Author: TERRAFORMARS
 */ 

#ifndef F_CPU
#define F_CPU 8000000UL // XTAL de 8 MHz
#endif
#include <avr/io.h>
#include <avr/iom48.h>
//libreria para configurar el ADC
#include "InitADC.h"

//macros para hacer un uso mas legible del control de puertos.
#define setbit(sfr,bit) (_SFR_BYTE(sfr)|=(_BV(bit)))
#define clearbit(sfr,bit) (_SFR_BYTE(sfr)&=~(_BV(bit)))
#define bittoggle(sfr,bit)(_SFR_BYTE(sfr)^=_BV(bit))

#include <avr/interrupt.h>                                                          /* Libreia para el funcionamiento de las                                                                                                          interrupciones*/
unsigned char n,var;

ISR(INT1_vect){
if (n==0)
{
n=1;
else
{
n=0;
}
}

void cambio(void){
//configuracion para flanco de bajada
setbit(EICRA,ISC11);
clearbit(EICRA,ISC10);
        //Enmascaramiento
setbit(EIMSK,INT1);
}

int main(void)
{
//CONFIGURAR ADC
cambio();                              //configuración de interrupción 
sei();                                     //habilitación de interrupciones global
initADC(2,1,5);
canalADC(1);
DDRB=0xFF;                      //salidas de la conversión
    while(1)
    {
        //TODO:: Please write your application code
var=convADC();                                                //lectura del canal 0


//selección de muestra de datos de las salidas
if (n==0)
{
PORTB=var;
else
{
if (var<=4) //este valor fue arbitrario, se puede elegir un 1 o algún otro valor
{
PORTB=0x00;
}
if (var<=31&&var>4)
{
PORTB=0x01;
}else if (var>31&&var<=63)
{
PORTB=0x03;
}
else if (var>63&&var<=95)
{
PORTB=0x07;
   }else if (var>95&&var<=127)
   {
PORTB=0x0f;
       }else if (var>127&&var<=159)
       {
   PORTB=0x1f;
            }else if (var>159&&var<=191)
            {
       PORTB=0x3f;
            }else if (var>191&&var<=223)
{
PORTB=0x7f;
   }else if (var>223&&var<=255)
   {
PORTB=0xff;
   }
}
//termina else
    }
}

IMAGENES

SIMULACIÓN EN ATMEL STUDIO 6

PREESCALAMIENTO DEL ADC

SIMULACION EN PROTEUS



LINK

https://mega.co.nz/#!MpFGVaDA!G-oYNk5kol7SdQtdvHWllzN0mckrIth39fTW2Ko1S7Y