Sida 1 av 1

ADC med avr

Postat: 4 juni 2005, 21:45:13
av björn
Nu har jag fått igång lite test med ad-omvandling med en atmega16.
Jag läser på ADC0, och presenterar värder binärt på portd, men det blir inget stabilt värde alls. om jag har 2 volt på adc0 så visar den allt ifrån ca 0,5 till 4,5 volt. Jag har en potentiometer på 0-9k i serie med ett 1k motsånd som jag mäter över(mellan).
Är det någon som har någon ide varför det visar så olika?
Jag har inget lågpassfilter innan avr kretsen men jag tycker inte att det skall göra så stor skillnad.

kod:

#include <avr/io.h>

#define ADC_VREF_TYPE 0x20
// Read the AD conversion result
unsigned int read_adc(unsigned char adc_input)
{


edit: glömde säga att jag har 4,95 volt som ref.
ADMUX=adc_input|ADC_VREF_TYPE;
// Start the AD conversion
ADCSRA|=0x40;
// Wait for the AD conversion to complete
while ((ADCSRA & 0x10)==0);
ADCSRA|=0x10;
return ADC;
}

// Declare global variables
unsigned char adc_input;

int main(void)
{
// Declare local variables
unsigned int read, i;
double adcres;
int result;

// Port B initialization
//PORTB=0x00;
//DDRB=0x00;

// Port F initialization

DDRD=0xFF;
//PORTD=0xFF;
// ADC initialization
// ADC Clock frequency: 125.000 kHz
// ADC Voltage Reference: AREF pin
// ADC High Speed Mode: Off
// ADC Auto Trigger Source: None
ADMUX=ADC_VREF_TYPE;
ADCSRA=0x83;
SFIOR&=0x2F;

// Select ADC input 0
adc_input=0;

for (;;)
{
mytemp=0;
for(i=0;i<250;i++) //tidigare <250
{
read=read_adc(adc_input);
adcres=adcres+read;
}
result=adcres/250;
PORTD=(unsigned char) ~(result);
//PORTD=(unsigned char) ~(result>>8);

};
}

Postat: 5 juni 2005, 15:11:45
av erixon
Du noll ställer aldrig adcres
Du skriver ut ett tal som är up till 10bitar på en port som har 8pinnar...
så tabort de 2 sista bitarna...

Några andra fel kan jag inte se för till fället...

Hoppas det gav några svar :)

Postat: 5 juni 2005, 17:26:58
av björn
Jag har ändrat så att jag nollar adres, men jag får inte mycket logik i det jag får ut. Vilka åtta bitar är det jag skall använda om jag struntar i de 2 MSB?
där är två olika kodrader för visningen i koden, vilken är rättatt använda då?

PORTD=(unsigned char) ~(result);
eller
//PORTD=(unsigned char) ~(result>>8);
??
ps. jag har det vänster justerat.

EDIT: jag testade med det sndra alternativet och då verkar det funka, men det verkar motsatt dvs ju högre spänning jag lägger på ADC0 desto mindre visar den på portd. Varför? jag fattar noll......

Postat: 5 juni 2005, 18:24:45
av erixon
MSB Står för Most Significant Bit

Vilket innebär att de har störts värde
så jag tror att du vill ha bort LSB

Du kan ha ADLAR = 1 och då använder (unsigned char) ~(result>>8)
eller ADLAR = 0 och då använder (unsigned char) ~(result>>2)

Tips kan vara att använda long iställe för double vilket kommer att då betydligt snabbar utan att du tappar presiton i det här fallet

Postat: 5 juni 2005, 18:35:49
av björn
OK, det med MSB visste jag men tänkte fel när jag skrev...
Då skall det alltså funka som jag har det nu, med ADLAR = 0 och (unsigned char) ~(result>>8)
men vad kan vara fel då jag får ut "tvärtom" värden?
0 volt visar 11111111 och 4,95 volt visar 00000011.

Postat: 5 juni 2005, 18:38:49
av cyr
Är inverteringen (~) till för att kompensera för något i hårdvaran i AVR?

Annars så är det väl därför du får omvänt...

Postat: 5 juni 2005, 18:46:56
av björn
AHAA, jag visste inte att det var invertering, missade nog i det i C-kursen :oops: Tack cyr
Jag följde ett kod esempel jag hade....