ADC en Atmega328p usar dos adcmux para sumarlos y obtener una salida de 8 bits

Hola. Muy buenas.

Así como en Arduino que se pueden leer dos señales analógicas, quiero hacer lo mismo pero sólo con el micro Atmega328p.
Ya creé lo que es mi código, creé una librería para inicializar el ADC y otra para meter datos.
Pero no entiendo una cosa importante, eso del A0 y A1 coloquialmente llamado en Arduino. ¿Es lo mismo que el MUX0 y MUX1 respectivamente?

Ahora, una vez que convierto ambas señales, las debo sumar y sacarlas por 8bits de salida. (0-255)

Abajo dejo los tres códigos que tengo, el primero solo es la creación de las librerías, el segundo para crear lo que es el registro de ADC (aquí es donde busco meter los de MUX0 y MUX1 en la líneas de código siguiente:
C:
    ADMUX &=(0b11110000 << MUX0); // ADMUX &=~  0x0F; Se manda a 0 valores de MUXn
    ADMUX &=(0b11110000 << MUX1);
    ADMUX |= (canal << MUX0)|(canal<<MUX1);  // aquí es donde le estoy diciendo que reciba datos de la A0 y A1.
Les agradeceré muchísimo.

*/ librería*/
C:
#ifndef ADC_H_
#define ADC_H_
#include <avr/io.h>
#include <util/delay.h>
void ADC_init();
int ADC_GetData(int canal);
#endif /* ADC_H_ */

////////////////////////////////////////////////////
/* ADC.c*/
#include "ADC.h"

void ADC_init()
{
    // Output adjust = right, 8 bits//
    ADMUX &=~ (1<<ADLAR);

    // Voltage Reference = AVCC //
    ADMUX |=  (1<<REFS0);
    ADMUX &=~ (1<<REFS1);

    // Frequency divisor = 128 -> 16000/128 = 125 KHz (200kHz -50kHz)
    ADCSRA |= (1<<ADPS0);
    ADCSRA |= (1<<ADPS1);
    ADCSRA |= (1<<ADPS2);
}

int ADC_GetData(int canal)
{
    // Selección del canal de lADC //
    ADMUX &=(0b11110000 << MUX0); // ADMUX &=~  0x0F; Se manda a 0 valores de MUXn
    ADMUX &=(0b11110000 << MUX1);
    ADMUX |= (canal << MUX0)|(canal<<MUX1);

    // Encendemos en ADC
    ADCSRA |= (1<<ADEN);
    _delay_us(10);  

    // Mandamos el muestreo inicia convertion
    ADCSRA |= (1<<ADSC);

    // Esperamos a que muestree, leyendo el flag
    while( !(ADCSRA & (1<<ADIF)) );
    ADCSRA |= (1<<ADIF);    // Reiniciamos el flag

    // Apagamos el ADC
    ADCSRA &=~ (1<<ADEN);

    //Uso de ADC 0 y 1 sólo como convertidor analog a digital
    DIDR0 = (1<<ADC0D)|(1<<ADC1D); //1 para análogo
   
    return ADC;  
}
Main:

C:
/*main.c  código*/

#include <avr/io.h>
#include <avr/interrupt.h>
#include <util/delay.h>
#include "ADC/ADC.h"

int main(void){
    cli();

    //salida de puerto D y B
    DDRD |= (1<<DDB6)|(1<<DDD7); //(0B11000000);
    DDRB |= (0x0F);
    //DDRC = (); //Botones de entrada
    ADC_init();

    sei();

    while (1)
    {
        /*float adcV0 = ADC_GetData(0)*5.0f/1024.0f; //borrar
        while (adcV0);
        {
            PORTB = ADCH;
            _delay_ms(100);
        }
        return 0;*/

        float adcV0 = ADC_GetData(0)*5.0f/1024.0f; //PC0
        float adcV1 = ADC_GetData(1)*5.0f/1024.0f; //PC1
        float adcSum = adcV0 + adcV1;

        if (adcSum > 3.0f)
            PORTB |= (1<<PORTB5);
        else
            PORTB &=~ (1<<PORTB5);
        }
    }
 
Eeemmm... Si aun quieres seguir usando el IDE de Arduino, pero usar solo el Atmega328, entonces no necesitas programar en otro IDE, simplemente programa, carga el sketch, y luego quita el micro del zocalo y usalo en donde quieras.

Si esa no es la idea, entonces dinos en qué IDE estas usando...
 
Efectivamente en la página 257-258 hacen mención de esos registros:

MUX.PNG

Y para elegir el canal, simplemente hacés esto:

C:
...
ADMUX  |=canal;    //Canal: 0-8
...

Te recomiendo hacer una conversión de descarte cada vez que cambiás de canal.
 
¿Es lo mismo que el MUX0 y MUX1 respectivamente?
Como ya lo mencionó el señor cosme, el MUX0,MUX1... si corresponden a los canales analógicos que quieres leer, para ser mas preciso estos bits corresponden al registro ADMUX, dale una mirada.

Por otro lado no entiendo que quieres hacer, viendo tu código no veo razón de sacar una suma de 2 canales ADC(que por cierto esta para 10 bits de resolución). Sacarlos o mostrarlos en 8 bits ? :unsure:


if (adcSum > 3.0f) PORTB |= (1<<PORTB5); else PORTB &=~ (1<<PORTB5);
En esta condición no configuraste para que el B5 este como salida.
 
Atrás
Arriba