Вы находитесь на странице: 1из 16

MICROCONTROLADORES ATMEGA:

MANEJO DEL ADC:


Los AVR de la serie megaAVR tienen un ADC de aproximaciones sucesivas de 10 bits.
Los uC AVR de la serie ATmegaXX8 destinan todo su puerto C como canales de
entrada del ADC.
El ADC del ATMEGA8 posee dos modos de funcionamiento:
Conversin nica:
La conversin se inicia al escribir un 1 lgico en el bit de inicio de conversin
ADSC del registro ADCSRA, y permanece as hasta que dicha conversin finaliza.
Carrera libre:
En el modo de carrera libre, el ADC convierte la seal de entrada en forma
continua. La primera conversin se inicia escribiendo un 1 lgico en el bit de
inicio de conversin ADSC del registro ADCSRA. Para seleccionar este modo se
debe escribir 1 en el bit ADFR del registro ADCSRA; si se escribe un 0 se
finaliza el modo carrera nica.
Registro ADCSRA:

Analicemos los bits del registro ADCSRA:


Bit 7: ADEN habilitador del ADC. Al escribir 1 en el ADEN el ADC se habilitara
caso contrario si se escribe 0 el ADC se deshabilitara.
Bit 6: ADSC inicio de conversin del ADC. En el modo de conversin simple al
escribir 1 lgico en este bit se inicializa cada conversin. En el modo carrera
libre escribir 1 en el ADSC indica el inicio de la primera conversin. ADSC
permanecer en 1 durante todo el tiempo de conversin y cambiara a 0 al
completar la conversin.
Bit 5: ADFR selector de carrera libre del ADC. Debemos poner a 1 el ADFR.
BIT 2:0 ADPS2:0 bit de seleccin del pre escalador. Estos bit s determinan el
factor de divisin entre la frecuencia del cristal y la entrada del reloj del ADC.
Esto lo vemos en la siguiente tabla:

Registro ADMUX:

Analicemos los bits del registro ADMUX:


Bit 7:6 REFS1:0 bit de seleccin de voltaje de referencia, veamos la siguiente
tabla:

Bit 5 ADLAR. Ajusta a la izquierda el resultado de la conversin (ADLAR=1) o


caso contrario es ajustado a la derecha, veamos esto en los registros ADCH y
ADCL.

Bit 3:0 MUX 3:0 Seleccin del canal de referencia al que sea conectado el ADC

Si se selecciona un nuevo canal, el ADC primero terminara la conversin en curso y


luego cambiara el canal.

Problema 1:
Visualizar a travs de los leds el valor binario tomado del ADC conectado a un
potencimetro. El ADC trabajara a manera de conversin simple y tomaremos 8 de los
10 bits dispuestos de los cuales los ajustaremos para que se trabaje con una salida de 0
a 63, todo se visualizara en los leds.
Solucin:
Codigo del programa:
/*
* AVRGCC45.c
*
* Created: 10/11/2014 4:30:23
* Author: mayhua
*/
#include <avr/io.h>
void configurar_adc ()
{
ADCSRA=1<<ADEN|1<<ADSC|0<<ADPS2|0<<ADPS1|0<<ADPS0;
ADMUX=0<<REFS1|0<<REFS0|1<<ADLAR|0<<MUX3|0<<MUX2|1<<MUX1|0<<MUX0;
//CONVERSION UNICA/HABILITAMOS EL ADC/PREESCALADOR 2
//AJUSTE A LA IZQUIEDA/ CANAL ADC2/VOLTAJE DE REFERENCIA DESACTIVADO
}
void configurar_puertos ()
{
//puerto d como salida
DDRD=0xff;
}
int main(void)
{//definimos las variables
int adc_val;
//LAMMAMSO A SUUBRUTINAS
configurar_adc();
configurar_puertos();
while(1)
{//progrma principal
//activamos el bit de adsc (inicio de la conversion)
//del registro adcsra
ADCSRA |=_BV (ADSC);
//ajustamos la recta
adc_val=(ADCH*63)/255;//esto para q valla de 0a 63
//mostramos por el puerto d
PORTD=adc_val;
//TODO:: Please write your application code
}
}

En la simulacin vemos que a medida que varia el potencimetro lo ara su referencia en


los leds del puerto d :

Para el caso de usar todos los leds se tendr:


* AVRGCC45.c
*
* Created: 10/11/2014 4:30:23
* Author: mayhua
*/
#include <avr/io.h>
void configurar_adc ()
{
ADCSRA=1<<ADEN|1<<ADSC|0<<ADPS2|0<<ADPS1|0<<ADPS0;
ADMUX=0<<REFS1|0<<REFS0|1<<ADLAR|0<<MUX3|0<<MUX2|1<<MUX1|0<<MUX0;
//CONVERSION UNICA/HABILITAMOS EL ADC/PREESCALADOR 2
//AJUSTE A LA IZQUIEDA/ CANAL ADC2/VOLTAJE DE REFERENCIA DESACTIVADO
}
void configurar_puertos ()
{
//puerto d como salida
DDRD=0xff;
}
int main(void)
{//definimos las variables
int adc_val;
//LAMMAMSO A SUUBRUTINAS
configurar_adc();
configurar_puertos();
while(1)
{//progrma principal
//activamos el bit de adsc (inicio de la conversion)
//del registro adcsra
ADCSRA |=_BV (ADSC);
//ajustamos la recta
adc_val=ADCH;//esto para q valla de 0a 63
//mostramos por el puerto d
PORTD=adc_val;
//TODO:: Please write your application code
}
}

Ahora a medida que variamos el potencimetro este desplazara el leds prendido segn la
magnitud simulando as e movimiento en uno de los ejes.
/*
* AVRGCC46.c
*
* Created: 10/11/2014 5:42:07
* Author: mayhua
*/
#include <avr/io.h>
void configurar_adc ()
{
ADCSRA=1<<ADEN|1<<ADSC|0<<ADPS2|0<<ADPS1|0<<ADPS0;
ADMUX=0<<REFS1|0<<REFS0|1<<ADLAR|0<<MUX3|0<<MUX2|1<<MUX1|0<<MUX0;
//CONVERSION UNICA/HABILITAMOS EL ADC/PREESCALADOR 2
//AJUSTE A LA IZQUIEDA/ CANAL ADC2/VOLTAJE DE REFERENCIA DESACTIVADO
}
void configurar_puertos ()
{
//puerto d como salida
DDRD=0xff;
}
int main(void)
{//definimos las variables
int adc_val;
int rango;
//LAMMAMSO A SUUBRUTINAS
configurar_adc();
configurar_puertos();
while(1)
{//progrma principal
//activamos el bit de adsc (inicio de la conversion)
//del registro adcsra
ADCSRA |=_BV (ADSC);
//ajustamos la recta
adc_val=ADCH;//esto para q valla de 0a 63
//ahora segun se mueva el potencimetro el ledsa se desplazaa
rango=adc_val;
if (rango>0 & rango<=32)
{PORTD=0x01;
}
if (rango>32 & rango<=64)
{PORTD=0x02;
}
if (rango>64 & rango<=96)
{PORTD=0x04;
}
if (rango>96 & rango<=128)
{PORTD=0x08;
}
if (rango>128 & rango<=160)
{PORTD=0x10;
}
if (rango>160 & rango<=192)
{PORTD=0x20;
}
if (rango>192 & rango<=224)
{PORTD=0x40;
}
if (rango>224)
{PORTD=0x80;
}

}
}

Usaremos dos canales del mdulo ADC pero tambin se estar usando como antes el modo de
conversin nica. De tal forma que se puede simular la entrada de dos de los ejes del proyecto
i asi visualar el movimiento del leds.
/*
* AVRGCC46.c
*
* Created: 10/11/2014 5:42:07
* Author: mayhua
*/
#include <avr/io.h>
/*
void configurar_adc ()
{
ADCSRA=1<<ADEN|1<<ADSC|0<<ADPS2|0<<ADPS1|0<<ADPS0;
ADMUX=0<<REFS1|0<<REFS0|1<<ADLAR|0<<MUX3|0<<MUX2|1<<MUX1|0<<MUX0;
//CONVERSION UNICA/HABILITAMOS EL ADC/PREESCALADOR 2
//AJUSTE A LA IZQUIEDA/ CANAL ADC2/VOLTAJE DE REFERENCIA DESACTIVADO
}
*/
void configurar_puertos ()
{
//puerto d como salida
DDRD=0xff;
//puerto b como salida
DDRB=0xff;
}
int main(void)
{//definimos las variables
int adc_val,adc_valor;
int rango,ran;
//LAMMAMSO A SUUBRUTINAS
//configurar_adc();
configurar_puertos();
while(1)
{//progrma principal
ADCSRA=1<<ADEN|1<<ADSC|0<<ADPS2|0<<ADPS1|0<<ADPS0;
ADMUX=0<<REFS1|0<<REFS0|1<<ADLAR|0<<MUX3|0<<MUX2|1<<MUX1|0<<MUX0;
ADCSRA |=_BV(ADSC);
//ajustamos la recta
adc_val=ADCH;//esto para q valla de 0a 63
//ahora segun se mueva el potencimetro el ledsa se desplazaa
rango=adc_val;
if (rango>0 & rango<=32)
{PORTD=0x01;
}
if (rango>32 & rango<=64)
{PORTD=0x02;
}
if (rango>64 & rango<=96)
{PORTD=0x04;
}
if (rango>96 & rango<=128)
{PORTD=0x08;
}
if (rango>128 & rango<=160)

{PORTD=0x10;
}
if (rango>160 & rango<=192)
{PORTD=0x20;
}
if (rango>192 & rango<=224)
{PORTD=0x40;
}
if (rango>224)
{PORTD=0x80;
}
ADCSRA=1<<ADEN|1<<ADSC|0<<ADPS2|0<<ADPS1|0<<ADPS0;
ADMUX=0<<REFS1|0<<REFS0|1<<ADLAR|0<<MUX3|0<<MUX2|0<<MUX1|1<<MUX0;
ADCSRA |=_BV(ADSC);
adc_valor=ADCH;
ran=adc_valor;
if (ran>0 & ran<=32)
{PORTB=0x01;
}
if (ran>32 & ran<=64)
{PORTB=0x02;
}
if (ran>64 & ran<=96)
{PORTB=0x04;
}
if (ran>96 & ran<=128)
{PORTB=0x08;
}
if (ran>128 & ran<=160)
{PORTB=0x10;
}
if (ran>160 & ran<=192)
{PORTB=0x20;
}
if (ran>192 & ran<=224)
{PORTB=0x40;
}
if (ran>224)
{PORTB=0x80;
}
}
}

Se llego al modo de dos usaos del adc uno por cada uno
/*
* AVRGCC46.c
*
* Created: 10/11/2014 5:42:07
* Author: mayhua
*/
#include <avr/io.h>
/*
void configurar_adc ()
{
ADCSRA=1<<ADEN|1<<ADSC|0<<ADPS2|0<<ADPS1|0<<ADPS0;
ADMUX=0<<REFS1|0<<REFS0|1<<ADLAR|0<<MUX3|0<<MUX2|1<<MUX1|0<<MUX0;
//CONVERSION UNICA/HABILITAMOS EL ADC/PREESCALADOR 2
//AJUSTE A LA IZQUIEDA/ CANAL ADC2/VOLTAJE DE REFERENCIA DESACTIVADO
}
*/
void configurar_puertos ()
{
//puerto d como salida
DDRD=0xff;
//puerto b como salida
DDRB=0xff;
}
int main(void)
{//definimos las variables
int adc_val,adc_valor;
int rango,ran;
//LAMMAMSO A SUUBRUTINAS
//configurar_adc();
configurar_puertos();
while(1)
{//progrma principal
ADCSRA=1<<ADEN|1<<ADSC|0<<ADPS2|0<<ADPS1|0<<ADPS0;
ADMUX=0<<REFS1|0<<REFS0|1<<ADLAR|0<<MUX3|0<<MUX2|1<<MUX1|0<<MUX0;
ADCSRA |=_BV(ADSC);
//ajustamos la recta
adc_val=ADCH;//esto para q valla de 0a 63
//ahora segun se mueva el potencimetro el ledsa se desplazaa
rango=adc_val;
if (rango>0 & rango<=32)
{PORTD=0x01;
}
if (rango>32 & rango<=64)
{PORTD=0x02;
}
if (rango>64 & rango<=96)
{PORTD=0x04;
}
if (rango>96 & rango<=128)
{PORTD=0x08;
}
if (rango>128 & rango<=160)
{PORTD=0x10;
}
if (rango>160 & rango<=192)
{PORTD=0x20;
}
if (rango>192 & rango<=224)
{PORTD=0x40;

}
if (rango>224)
{PORTD=0x80;
}

ADCSRA=1<<ADEN|1<<ADSC|0<<ADPS2|0<<ADPS1|0<<ADPS0;
ADMUX=0<<REFS1|0<<REFS0|1<<ADLAR|0<<MUX3|0<<MUX2|0<<MUX1|1<<MUX0;
ADCSRA |=_BV(ADSC);
adc_valor=ADCH;
ran=adc_valor;
if (ran>0 & ran<=32)
{PORTB=0x01;
}
if (ran>32 & ran<=64)
{PORTB=0x02;
}
if (ran>64 & ran<=96)
{PORTB=0x04;
}
if (ran>96 & ran<=128)
{PORTB=0x08;
}
if (ran>128 & ran<=160)
{PORTB=0x10;
}
if (ran>160 & ran<=192)
{PORTB=0x20;
}
if (ran>192 & ran<=224)
{PORTB=0x40;
}
if (ran>224)
{PORTB=0x80;
}
}
}

Ahora coloqumoslo en una matriz de leds, con lo cual visualicemos el desplazamiento del leds
en dos dimensiones, asi podemos ver el desplazamiento del leds si se fue a la derecha o a la
izquierda.
/*
* AVRGCC46.c
*
* Created: 10/11/2014 5:42:07
* Author: mayhua
*/
#include <avr/io.h>
/*
void configurar_adc ()
{
ADCSRA=1<<ADEN|1<<ADSC|0<<ADPS2|0<<ADPS1|0<<ADPS0;
ADMUX=0<<REFS1|0<<REFS0|1<<ADLAR|0<<MUX3|0<<MUX2|1<<MUX1|0<<MUX0;
//CONVERSION UNICA/HABILITAMOS EL ADC/PREESCALADOR 2
//AJUSTE A LA IZQUIEDA/ CANAL ADC2/VOLTAJE DE REFERENCIA DESACTIVADO
}
*/
void configurar_puertos ()

{
//puerto d como salida
DDRD=0xff;
//puerto b como salida
DDRB=0xff;
}
int main(void)
{//definimos las variables
int adc_val,adc_valor;
int rango,ran;
//LAMMAMSO A SUUBRUTINAS
//configurar_adc();
configurar_puertos();
while(1)
{//progrma principal
ADCSRA=1<<ADEN|1<<ADSC|0<<ADPS2|0<<ADPS1|0<<ADPS0;
ADMUX=0<<REFS1|0<<REFS0|1<<ADLAR|0<<MUX3|0<<MUX2|1<<MUX1|0<<MUX0;
ADCSRA |=_BV(ADSC);
//ajustamos la recta
adc_val=ADCH;//esto para q valla de 0a 63
//ahora segun se mueva el potencimetro el ledsa se desplazaa
rango=adc_val;
if (rango>0 & rango<=32)
{PORTD=0x01;
}
if (rango>32 & rango<=64)
{PORTD=0x02;
}
if (rango>64 & rango<=96)
{PORTD=0x04;
}
if (rango>96 & rango<=128)
{PORTD=0x08;
}
if (rango>128 & rango<=160)
{PORTD=0x10;
}
if (rango>160 & rango<=192)
{PORTD=0x20;
}
if (rango>192 & rango<=224)
{PORTD=0x40;
}
if (rango>224)
{PORTD=0x80;
}

ADCSRA=1<<ADEN|1<<ADSC|0<<ADPS2|0<<ADPS1|0<<ADPS0;
ADMUX=0<<REFS1|0<<REFS0|1<<ADLAR|0<<MUX3|0<<MUX2|0<<MUX1|1<<MUX0;
ADCSRA |=_BV(ADSC);
adc_valor=ADCH;
ran=adc_valor;
if (ran>0 & ran<=32)
{PORTB=0xFE;
}
if (ran>32 & ran<=64)
{PORTB=0xFD;
}
if (ran>64 & ran<=96)

{PORTB=0xFB;
}
if (ran>96 & ran<=128)
{PORTB=0xF7;
}
if (ran>128 & ran<=160)
{PORTB=0xEF;
}
if (ran>160 & ran<=192)
{PORTB=0xDF;
}
if (ran>192 & ran<=224)
{PORTB=0xBF;
}
if (ran>224)
{PORTB=0x7F;
}
}
}

Simulacin en el Proteus:
Se inicialmente los potencimetros al 50% de su valor esto me indica que la
maqueta est en posicin horizontal lo que mostrar en la matriz de leds con el
leds casi en el medio:

Al mover uno de los potencimetros del punto medio o valor de posicin horizontal este se
mover:

Y al mover el otro potencimetro serai como mover otro de los ejes del sentsor de movimiento
o inclinometro.

Вам также может понравиться