lunes, 7 de marzo de 2011

ADC - Analog-to-digital Converter

El ADC en los ATmega, cómo en otros uC´s de 8bits, tiene una resolución máxima de 10bits. Dependiendo de el uC se encontrara un número diferente de canales simples o diferenciales.
La formula clásica para convertir el valor que se obtiene de los registros ADCH:ADCL es:

Vin=5*(ADCH:ADCL )/1024

5/1042 es aproximadamente 48828e-7, entonces Vin=((ADCH:ADCL )*48828)e-7.

Ahora mostrare un ejemplo de la configuración del ADC en un ATmega324P.
Agregaremos unas macros a las nuestro archivo macros.inc:

macros

La macro “PUTM” no hace otra cosa que obtener el valor de una posición de la ram y enviarlo al LCD.
Las otras dos macros realizan una multiplicación como es indicado. Estas se usan para multiplicar ((ADCH:ADCL )*48828).
También se ha usado una rutina para convertir el resultado de la multiplicación a código ascii, esto es para poderlo mostrar en el lcd.

ascii

Antes de llamar a esta rutina Z debe apuntar al dato que se quiere convertir (LSB), Y debe apuntar a la posición de la ram donde se quiere guardar los datos en ascii (MSB).

El programa principal es el siguiente:





SELEC_CH recibe en R16 el canal que se muestreara, luego de escoger el canal se habilita el conversor (ADEN) y se inicia la conversión (ADSC).
ESPERA_ADC esperará hasta el final de la conversión.
CALCULA_VOL obtiene los 10 bits de la conversión en R17:R16 y lo multiplica con R19:R18=48828, luego ese valor convertido la convierte a código ascii y lo pone en la ram (Y=0x0100).
El resultado de la simulación es el mostrado:

fig1

En la ram se puede ver uno de los valores en ascii (000023486268=23486268). La coma decimal debe correr 7 posiciones (debido al factor e-7), entonces el voltaje es 2.34862.


4 comentarios:

  1. Jonathan tengo una pregunta, lo que pasa es que tus macros, hay una difernete de la otra, merefiero a la macro MULT_16X8 Y MULT_16X16, y lo otro es que si puedo usarlo en mi atmega8 y que cosas deberia cambiar para usarlo.Si puedes respondeme a este correo andreix22@gmail.com..gracias

    ResponderEliminar
  2. MULT_16X8: Multiplica un número de 2 bytes por uno de 1 byte. Esta macro tambien la uso para en la siguiente macro(MULT_16X16).
    MULT_16X8: Multiplica un número de 2 bytes por uno de 2 bytes.
    Supongamos que:
    R17:R16=0x1234
    R19:R18=0x5678
    -MULT_16X8 R19,R18,R17
    Esto multiplicará (R19:R18)x(R17)= (0x5678)x(0x12)=0x61740 => R4:R3:R2=0x061740
    -MULT_16X16 R19,R18,R17,R16
    Esto multiplicará (R19:R18)x(R17:R16)= (0x5678)x(0x1234)=0x6260060 => R15:R14:R13:R12=0x06260060.
    Preguntas si puedes usar éste ejemplo en un ATmega8?...claro que si puedes, salamente tienes que cambiar de puerto para usar el lcd(PUERTO_LCD), ver que canales usar para el ADC, y tener presente que el ATmega8 solamente funciona hasta 16MHz.

    ResponderEliminar
  3. claro, lo que pasa es que en un anterior foro(mas especificamente en este:http://avrperu.blogspot.com/2011/06/input-capture-unit.html)a este:http://avrperu.blogspot.com/2011/06/input-capture-unit.html
    las macros de MULT16X8 Y MULT16X16 son diferentes, dime , cual debo de seguir?

    ResponderEliminar
  4. o.k... ya te entendi. Las macros hacen lo mismo, no te preocupes por eso. La diferencia es que las del post "input-capture-unit" lo hace con menos instrucciones (reemplazo dos instrucciones "mov" por una "movw").

    ResponderEliminar