In the following AVR code, why do I always see the same voltage for all pins of port A?

I am using ATMega32.

BTW, when I am grounding some pins of port A I do not see any change in the output. It seems AVR neglects what ever I give to port A of it.

#define F_CPU 8000000UL

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

{
}

{
//Select ADC Channel ch must be 0-7
ch=ch&0b00000111;

//Start Single conversion

//Wait for conversion to complete

//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' !!!

}

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;

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

while(1)
{
_delay_ms(10);
_delay_ms(10);
_delay_ms(10);
_delay_ms(10);

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);
}

• What is connected to the external Reference? Whats is the "I always see the same voltage" voltage? And from what I can tell, ReadADC() won't properly set the correct channel when called multiple times, because ADMUX|=ch; won't clear existing MUX3..0 bits.
– Rev
Jun 23 '15 at 6:51
• @Rev1.0 Aref=VCC. How to clear existing Mux3..0 properly? Jun 23 '15 at 6:54
• Well ADMUX &= 0b11111000; should clear the lower 3 bits before assigning the new value from ch with ADMUX |= ch;.
– Rev
Jun 23 '15 at 7:03

I think previous poster is right about not clearing the channel bits in ADMUX. Here's my well tested code:

unsigned short read_proc_ad(byte adchan){
//start a new conversion, wait for a result, and return it
//unsigned short retval;

• Please update the answer with my solution: ch=ch&0b00000111; ADMUX&=~(0b00000111); ADMUX|=ch; Jun 26 '15 at 23:31