Sida 1 av 1

Intern Aref (ADCn) i Atmega328P

Postat: 24 juli 2014, 23:15:51
av mattswe
Hej!
Jag har skrivit ett program som kör ADCn i en Atmega328P i Single Conversion mode (läser från två kanaler, två analoga ingångar). När jag använder Aref = AVcc så fungerar det utmärkt. Kod enligt följande:

Kod: Markera allt

ADMUX |= (1<<REFS0); // AVcc med ext. kond. på AREF-pin
Nu är det så att den analoga insignalen är mellan 0 och 1V, och därför tänkte jag istället använda den interna 1.1V som referensspänning.

Kod: Markera allt

ADMUX |= (1<<REFS1) | (1<<REFS0); // Intern 1.1V med ext. kond. på AREF-pin
Problemet är att detta fungerar inte. Även då insignalerna är 0V på båda kanalerna så läser ADCn 1023. Jag har inte ändrat på något annat än ovanstående kodrad. Kan även tillägga att jag i båda fallen har en 0,1uF konding på AREF-pinnen.

Några ideer?

Re: Intern Aref (ADCn) i Atmega328P

Postat: 25 juli 2014, 03:19:50
av blueint
Referensspänningen är inte vad du tror? mät..?
Den kanske inte klarar strömmen, har för mycket ripper eller vadhelst..

Re: Intern Aref (ADCn) i Atmega328P

Postat: 25 juli 2014, 18:49:54
av exile
Du råkar inte ändra REFS1 & REFS0 när du byter kanal? Första läsningen efter bytte av Vref är "trasig".
Annars kan du se vad du har för spänning på Aref (notera att pinnen inte nästan inte tål belastning), och har du någon avkoppling på Aref, iså fall hur mycket?

Re: Intern Aref (ADCn) i Atmega328P

Postat: 25 juli 2014, 18:53:40
av sodjan
Är inte "avkoppling" : "Kan även tillägga att jag i båda fallen har en 0,1uF konding på AREF-pinnen." ?

Re: Intern Aref (ADCn) i Atmega328P

Postat: 25 juli 2014, 19:27:52
av exile
Missa det! 100nF verkar vara helt ok

Re: Intern Aref (ADCn) i Atmega328P

Postat: 25 juli 2014, 23:09:02
av mattswe
Nu har jag brutit ner koden till nedanstående program.
Avkopplingen på Vref är som sagt 0,1uF.
Referensspänningen är inte vad du tror? mät..?
När jag kör med AVcc som ref så mäter jag 5V på Aref-pinnen, allt gott och väl. Konverteringen utförs som den ska.
När jag istället kör med intern 1.1V som ref så mäter jag ca. 12mV på Aref-pinnen då de analoga insignalerna (på ADC0 resp. ADC1) är 0V. När jag ökar insignalen på ADC0 så kryper Aref upp något, Vid insignal=5V mäter Aref ca 63mV. Något är uppenbarligen på tok.
Du råkar inte ändra REFS1 & REFS0 när du byter kanal?
Nej, det tror jag inte.
Första läsningen efter bytte av Vref är "trasig".
Jag byter inte Vref under körning. Första läsningen kasserar jag (i fknen initADC()).

Kod: Markera allt

#define F_CPU 8000000UL
#include <avr/io.h>

void initADC()
{
	ADCSRA |= (1<<ADPS2) | (1<<ADPS1); // Prescaler = 64 => 125kHz
	//ADMUX |= (1<<REFS0); // AVcc med ext. kond. på AREF-pin
	ADMUX |= (1<<REFS1) | (1<<REFS0); // Intern 1.1V med ext. kond. på AREF-pin
	ADCSRA |= (1<<ADEN); // Slår på ADCn
	ADCSRA |= (1<<ADSC); // Startar konverteringen		
}

uint16_t readADC(uint8_t inPin)
{
	ADMUX &= 0xF0; // Nollställer MUX3-MUX0
	ADMUX |= inPin;
	ADCSRA |= (1<<ADSC); // Startar en ny konvertering
	while(ADCSRA & (1<<ADSC)); // Väntar tills konverteringen är klar
	
	return ADCW;
}	

int main(void)
{
	DDRB |= ((1<<PB1) | (1<<PB2)); // Outputs
	
	uint16_t adcValue;
	
	initADC();
	
	while(1)
	{
		// ADC0
		adcValue = readADC(0);
		if(adcValue > 512)
		{
			PORTB |= (1<<PB1);
		}
		else
		{
			PORTB &=~(1<<PB1);
		}
		
		// ADC1
		adcValue = readADC(1);
		if(adcValue > 512)
		{
			PORTB |= (1<<PB2);
		}
		else
		{
			PORTB &=~(1<<PB2);
		}
	}
}

Re: Intern Aref (ADCn) i Atmega328P

Postat: 26 juli 2014, 11:03:56
av Swech
Vad händer om du byter

Kod: Markera allt

ADMUX &= 0xF0; // Nollställer MUX3-MUX0
ADMUX |= inPin;
till

Kod: Markera allt

ADMUX = (1<<REFS1) | (1<<REFS0); // Intern 1.1V med ext. kond.
ADMUX |= inPin;
Swech

Re: Intern Aref (ADCn) i Atmega328P

Postat: 26 juli 2014, 11:37:55
av mattswe
Swech, det gör ingen skillnad.

Re: Intern Aref (ADCn) i Atmega328P

Postat: 26 juli 2014, 16:07:22
av mattswe
Tyckte jag försökt allt, så till slut testade jag med ett annat uC-chip. Plötsligt fungerar det. Nu mäter det 1.1V på Aref.
Det verkar som att microcontrollern jag hade helt enkelt var trasig på något sätt. Lite snopet.
Hur som helt, problemet löst.