Atmega8 Multiple ADC and display it

Go To Last Post
5 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hi,

 

i'm struggling to read/display 4 ADC port.

 



#include <avr/io.h>
#include <avr/interrupt.h> 
#include "lcd.h"
#include <stdlib.h>
#include <stdio.h>  

char v[7];

int main(void)
{

	lcd_init(LCD_DISP_ON); /* initialize display, cursor off */
	lcd_clrscr(); /* clear the screen*/

  ADCSRA |= (1 << ADPS0) | (1 << ADPS2); // Set ADC prescalar
  ADCSRA |= (1 << ADFR);  // Set ADC to Free-Running Mode
  ADCSRA |= (1 << ADEN);  // Enable ADC

sei();

ADCSRA |= (1 << ADSC);  // Start A2D Conversions

    while(1)
    {

    }
}


ISR(ADC_vect)
{
	uint8_t theLow = ADCL;
	uint16_t theTenBitResult = ADCH<<8 | theLow;

	switch (ADMUX)
	{
		case 0b00000000:
		
		lcd_gotoxy( 7, 1 );
		dtostrf(theTenBitResult,4,0,v);
		lcd_puts(v);
	
		ADMUX |= 0b00000001;
		break;
		
		case 0b00000001:
		
		lcd_gotoxy( 0, 1 );
		dtostrf(theTenBitResult,4,0,v);
		lcd_puts(v);
		
		ADMUX |= 0b00000000;
		
		break;
		
		default:
		// no default		
		break;
	}
	
	 ADCSRA |= (1 << ADSC);  // Start A2D Conversions
	
}

If i read one by one is working, but i cannot read more than one. at least on the display did not show anything.

  int main(void)
{

	
	lcd_init(LCD_DISP_ON); /* initialize display, cursor off */
	lcd_clrscr(); /* clear the screen*/

  ADCSRA |= (1 << ADPS0) | (1 << ADPS2); // Set ADC prescalar
  ADCSRA |= (1 << ADFR);  // Set ADC to Free-Running Mode
  ADCSRA |= (1 << ADEN);  // Enable ADC
  
	
	ADMUX |= 0b00000000; //ADC0
	//ADMUX |= 0b00000001; ADC1
	
sei();

ADCSRA |= (1 << ADSC);  // Start A2D Conversions
  
  while(1)
    {
		
			uint8_t theLow = ADCL;
			uint16_t theTenBitResult = ADCH<<8 | theLow;
		
			lcd_gotoxy( 7, 1 );
			dtostrf(theTenBitResult,4,0,v);
			lcd_puts(v);
    }			
    
    }

My uC is Atmega 8 running at 1Mhz(internal clock) with external AREF 2.5V.

 

Last Edited: Fri. Nov 28, 2014 - 06:33 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0
ADCSRA |= (1 << ADPS0) | (1 << ADPS2); // Set ADC prescalar

You are setting a prescaler of 32.  At 1 MHz, that will give you an ADC clock of 31.25 kHz.  The ADC is spec'd to run between 50 kHz and 200 kHz, so this is technically too slow.

 

This isn't responsible for troubles, though.

 

You've selected free-running mode.  In that mode as soon as one conversion is complete another is started.  So in your ISR this:

	 ADCSRA |= (1 << ADSC);  // Start A2D Conversions

... has no effect as a new conversion is already under way.

 

More importantly the MUX bits are latched at the start of each conversion, so when you change them in your ISR you're actually changing them for the next conversion, not the one currently under way.

 

 

"Experience is what enables you to recognise a mistake the second time you make it."

"Good judgement comes from experience.  Experience comes from bad judgement."

"Wisdom is always wont to arrive late, and to be a little approximate on first possession."

"When you hear hoofbeats, think horses, not unicorns."

"Fast.  Cheap.  Good.  Pick two."

"We see a lot of arses on handlebars around here." - [J Ekdahl]

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

To be clear, you should turn off free-running mode. Also:

ADMUX |= 0b00000000;

This does nothing. To clear a bit you need:

ADMUX &= ~0b00000001;

 

Regards,
Steve A.

The Board helps those that help themselves.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Koshchi wrote:
This does nothing.
Very good.  I'd stopped looking once I found the first error.

 

The to OP, as written your code will sample ADC0, and then forever ADC1.  Follow @Koshchi's advice.

"Experience is what enables you to recognise a mistake the second time you make it."

"Good judgement comes from experience.  Experience comes from bad judgement."

"Wisdom is always wont to arrive late, and to be a little approximate on first possession."

"When you hear hoofbeats, think horses, not unicorns."

"Fast.  Cheap.  Good.  Pick two."

"We see a lot of arses on handlebars around here." - [J Ekdahl]

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Thanks for all your help! Now is working half but i still need to review the code..

 

I forgot to enable the ADC interrupt!