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