ADC descuida el voltaje de entrada (ATMega32)

0

En el siguiente código AVR, ¿por qué siempre veo el mismo voltaje para todos los pines del puerto A?

Estoy usando ATMega32.

Por cierto, cuando estoy conectando a tierra algunos pines del puerto A, no veo ningún cambio en la salida. Parece que el AVR descuida todo lo que le doy al puerto A del mismo.

#define F_CPU 8000000UL

#include <avr/io.h>
#include <util/delay.h>
#include <stdlib.h>
#include "lib/hd44780.h"

void InitADC()
{
    ADMUX=(1<<REFS0);                         // For Aref=AVcc;
    ADCSRA=(1<<ADEN)|(1<<ADPS2)|(1<<ADPS1)|(1<<ADPS0); //Rrescalar div factor =128
}

uint16_t ReadADC(uint8_t ch)
{
    //Select ADC Channel ch must be 0-7
    ch=ch&0b00000111;
    ADMUX|=ch;

    //Start Single conversion
    ADCSRA|=(1<<ADSC);

    //Wait for conversion to complete
    while(!(ADCSRA & (1<<ADIF)));

    //Clear ADIF by writing one to it
    //Note you may be wondering why we have write one to clear it
    //This is standard way of clearing bits in io as said in datasheets.
    //The code writes '1' but it result in setting bit to '0' !!!

    ADCSRA|=(1<<ADIF);

    return(ADC);
}

void convert_text(double voltage,char *text)
{
    int voltage_n, voltage_f;
    voltage_n=(int)trunc(voltage);
    voltage_f=(int)trunc((voltage-voltage_n)*100);
    sprintf(text,"%d.%02d",voltage_n,voltage_f);
}

void convert_voltage_text(double voltage,int battery,char *text)
{
    char stext[20];
    convert_text(voltage,stext);
    sprintf(text,"V%d=%s",battery,stext);
}

void main ()
{

    char vtext1[20];
    char vtext2[20];
    char vtext3[20];
    char vtext4[20];
    char line1[20];
    char line2[20];
    uint16_t v_val1, v_val2, v_val3, v_val4;
    double voltage1, voltage2, voltage3, voltage4;

    InitADC();
    lcd_init();
    // DDRA=0;
    // PORTA=0;

    while(1)
    {
    _delay_ms(10);
        v_val1=ReadADC(1);           // Read Analog value from channel-0
    _delay_ms(10);
        v_val2=ReadADC(2);           // Read Analog value from channel-2
    _delay_ms(10);
        v_val3=ReadADC(3);           // Read Analog value from channel-3
    _delay_ms(10);
        v_val4=ReadADC(4);           // Read Analog value from channel-4

        voltage1=((double)v_val1)/1023*5;
        voltage2=((double)v_val2)/1023*5;
        voltage3=((double)v_val3)/1023*5;
        voltage4=((double)v_val4)/1023*5;

        convert_voltage_text(voltage1,1,vtext1);
        convert_voltage_text(voltage2,2,vtext2);
        convert_voltage_text(voltage3,3,vtext3);
        convert_voltage_text(voltage4,4,vtext4);

        sprintf(line1,"%-10s %s",vtext1,vtext2);
        sprintf(line2,"%-10s %s",vtext3,vtext4);

        lcd_clrscr();
        lcd_goto(LCD_LINE1_POS);
        lcd_puts("");
        lcd_puts(line1);
        lcd_goto(LCD_LINE2_POS);
        lcd_puts("");
        lcd_puts(line2);

        _delay_ms(100);             
    }

    return(0);
}
    
pregunta barej

1 respuesta

1

Creo que el póster anterior tiene razón al no borrar los bits de canal en ADMUX. Aquí está mi código bien probado:

unsigned short read_proc_ad(byte adchan){
  //start a new conversion, wait for a result, and return it
  //unsigned short retval;
  ADMUX &= ~0X1F;
  ADMUX |= adchan;
  ADCSRA |= _BV(ADSC);
  while(bit_is_set(ADCSRA,ADSC))wdt_reset();
  return ADC;
}

Tenga en cuenta también que no busco que ADIF suba, sino que busco que ADSC caiga. También es posible que desee borrar el indicador ADIF justo antes de la conversión en lugar de después.

    
respondido por el electrogas

Lea otras preguntas en las etiquetas