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:
Conversión única: La conversión se inicia al escribir un “1” lógico en el bit de inicio de conversión
ADSC del registro ADCSRA, y permanece así hasta que dicha d icha conversión finaliza.
Carrera libre: En el modo de carrera libre, el ADC convierte la señal de entrada en forma continua. La primera conversión conversión se inicia escribiendo escribiendo un “1” lógico en el bit de
inicio de conversión ADSC del registro registro ADCSRA. Para seleccionar seleccionar este modo se registro ADCSRA; si se escribe un “0” se debe escribir “1” en el bit ADFR del registro
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 conversión del ADC. En el modo de conversión simple al escribir 1 lógico en este bit se inicializa cada conversión. En el modo carrera libre escribir 1 en el ADSC indica el inicio de la primera primera conversión. ADSC permanecerá en 1 durante todo el tiempo de conversión y cambiara a 0 al completar la conversión.
Bit 5: ADFR selector de carrera libre del ADC. Debemos poner a 1 el ADFR.
BIT 2:0 ADPS2:0 bit de selección del pre escalador. Estos bit s determinan el factor de división 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 selección de voltaje de referencia, veamos la siguiente tabla:
Bit 5 ADLAR. Ajusta a la izquierda el resultado de la conversión (ADLAR=1) o caso contrario es ajustado a la derecha, veamos esto en los registros ADCH y ADCL.
Bit 3:0 MUX 3:0 Selección del canal de referencia al que sea conectado el ADC
Si se selecciona un nuevo canal, el ADC primero terminara la conversión en curso y luego cambiara el canal.
Problema 1:
Visualizar a través de los leds el valor binario tomado del ADC conectado a un potenciómetro. El ADC trabajara a manera de conversión 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. Solución:
Codigo del programa: /* * AVRGCC45.c * * Created: 10/11/2014 4:30:23 * Author: mayhua */ #include
void configurar_adc () { ADCSRA=1<
En la simulación 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 void configurar_adc () { ADCSRA=1<
Ahora a medida que variamos el potenciómetro este desplazara el leds prendido según la magnitud simulando así e movimiento en uno de los ejes. /* * AVRGCC46.c * * Created: 10/11/2014 5:42:07 * Author: mayhua */ #include void configurar_adc () { ADCSRA=1<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 módulo ADC pero también se estará usando como antes el modo de conversión ú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 /* void configurar_adc () { ADCSRA=1<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<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 /* void configurar_adc () { ADCSRA=1<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<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 coloquémoslo en una matriz de leds, con lo cual visualicemos el desplazamiento del leds en dos dimensiones, asi podemos ver el desplazamiento del l eds si se fue a la derecha o a la izquierda. /* * AVRGCC46.c * * Created: 10/11/2014 5:42:07 * Author: mayhua */ #include /* void configurar_adc () { ADCSRA=1<
{ //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<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<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; } } } Simulación en el Proteus: Se inicialmente los potenciómetros al 50% de su valor esto me indica que la maqueta está en posición horizontal lo que mostrar en la matriz de leds con el leds casi en el medio:
Al mover uno de los potenciómetros del punto medio o valor de posición horizontal este se moverá:
Y al mover el otro potenciómetro serai como mover otro de los ejes del sentsor de movimiento o inclinometro.