Intern Aref (ADCn) i Atmega328P

PIC, AVR, Arduino, Raspberry Pi, Basic Stamp, PLC mm.
mattswe
Inlägg: 159
Blev medlem: 20 augusti 2012, 13:27:51

Intern Aref (ADCn) i Atmega328P

Inlägg 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?
blueint
Inlägg: 23238
Blev medlem: 4 juli 2006, 19:26:11
Kontakt:

Re: Intern Aref (ADCn) i Atmega328P

Inlägg av blueint »

Referensspänningen är inte vad du tror? mät..?
Den kanske inte klarar strömmen, har för mycket ripper eller vadhelst..
Användarvisningsbild
exile
EF Sponsor
Inlägg: 496
Blev medlem: 21 oktober 2005, 23:32:07

Re: Intern Aref (ADCn) i Atmega328P

Inlägg 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?
sodjan
EF Sponsor
Inlägg: 43251
Blev medlem: 10 maj 2005, 16:29:20
Ort: Söderköping

Re: Intern Aref (ADCn) i Atmega328P

Inlägg av sodjan »

Är inte "avkoppling" : "Kan även tillägga att jag i båda fallen har en 0,1uF konding på AREF-pinnen." ?
Användarvisningsbild
exile
EF Sponsor
Inlägg: 496
Blev medlem: 21 oktober 2005, 23:32:07

Re: Intern Aref (ADCn) i Atmega328P

Inlägg av exile »

Missa det! 100nF verkar vara helt ok
mattswe
Inlägg: 159
Blev medlem: 20 augusti 2012, 13:27:51

Re: Intern Aref (ADCn) i Atmega328P

Inlägg 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);
		}
	}
}
Användarvisningsbild
Swech
EF Sponsor
Inlägg: 4750
Blev medlem: 6 november 2006, 21:43:35
Ort: Munkedal, Sverige (Sweden)
Kontakt:

Re: Intern Aref (ADCn) i Atmega328P

Inlägg 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
mattswe
Inlägg: 159
Blev medlem: 20 augusti 2012, 13:27:51

Re: Intern Aref (ADCn) i Atmega328P

Inlägg av mattswe »

Swech, det gör ingen skillnad.
mattswe
Inlägg: 159
Blev medlem: 20 augusti 2012, 13:27:51

Re: Intern Aref (ADCn) i Atmega328P

Inlägg 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.
Skriv svar