ADC med avr

PIC, AVR, Arduino, Raspberry Pi, Basic Stamp, PLC mm.
Användarvisningsbild
björn
EF Sponsor
Inlägg: 2570
Blev medlem: 29 mars 2004, 23:09:55

ADC med avr

Inlägg 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);

};
}
Användarvisningsbild
erixon
Inlägg: 380
Blev medlem: 27 augusti 2003, 10:21:58

Inlägg 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 :)
Användarvisningsbild
björn
EF Sponsor
Inlägg: 2570
Blev medlem: 29 mars 2004, 23:09:55

Inlägg 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......
Användarvisningsbild
erixon
Inlägg: 380
Blev medlem: 27 augusti 2003, 10:21:58

Inlägg 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
Användarvisningsbild
björn
EF Sponsor
Inlägg: 2570
Blev medlem: 29 mars 2004, 23:09:55

Inlägg 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.
cyr
Inlägg: 2712
Blev medlem: 27 maj 2003, 16:02:39
Ort: linköping
Kontakt:

Inlägg 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...
Användarvisningsbild
björn
EF Sponsor
Inlägg: 2570
Blev medlem: 29 mars 2004, 23:09:55

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