kevin_
Don't Blame Me, Blame Yourself..
Hallo,
omdat alle leerstof afgehandeld is mogen wij ons bezig houden met C tijdens de les.
Ik probeer nu 2 potentiometers uit te lezen en die waarden gebruiken in 2 IF-statements eronder:
void InitADC()
{
ADMUX=(1<<REFS0);
ADCSRA=(1<<ADEN)|(1<<ADPS2)|(1<<ADPS1)|(1<<ADPS0);
}
uint16_t ReadADC(uint8_t ch)
{
ch=ch&0b00000111;
ADMUX|=ch;
ADCSRA|=(1<<ADSC);
while(!(ADCSRA & (1<<ADIF)));
ADCSRA|=(1<<ADIF);
return(ADC);
}
// PROGRAMMA deel weggelaten
int main()
{
DDRB = 0xFF;
PORTB = 0x00;
PORTB |= (0 << PB2);
uint16_t adc0;
uint16_t adc1;
InitADC();
while(1)
{
adc0=ReadADC(0);
adc1=ReadADC(1);
if (adc0 < 600)
{
//programma
}
else if (adc0 < 700)
{
//programma
}
else
{
//programma
}
//2de IF-lus
if (adc1 < 600)
{
//programma
}
else if (adc1 < 650)
{
//programma
}
else
{
//programma
}
} //while-lus
return 0;
}
Als ik alleen kanaal nul uitlees, dan werkt de code
Als ik alleen kanaal een uitlees dan werkt de code ook
Als ik echter de 2 kanalen uitlees (zoals hierboven), dan wordt in beide IF-lussen gewerkt met de 'adc1'-waarde.
(Hij stelt dus adc0 gelijk aan adc1 in de IF-voorwaarde?)
Wat doe ik hier fout?
Alvast bedankt,
kevin
In je ReadADC routine ben je nogal fanatiek bezig te OR'en met waarden die op dat moment in de control registers zitten:
ADMUX|=ch;
Hier wil je niet OR'en, maar het register in zijn geheel updaten. Ik kan me niet herinneren of de prescaler bits ook in dit register zitten. If so, de variabele ch AND'en met het channel bitmask (doe je al op de 3 laagste bits) en dan de prescaler bits er bij in OR'en en vervolgens hard aan de poort toekennen.
Edit: Nee het is de ref voltage bits die er nog bij in zitten zoals je init aangeeft met (1<<REFS0). Dus bovenstaande opmerking is juist, ipv prescaler bits dus de ref bits er bij OR'en:
ADMX = (ch & 0b00000111) | (1<<REFS0)
Nu zal het vast werken.
P.S. de OR assignment ( |= ) is wel goed voor de ADSC en ADIF bits.
kevin_
Don't Blame Me, Blame Yourself..
die 2 stukjes (ReadADC en InitADC) had ik van het internet gehaald en ze leken te werken?
Ik ga de code nu aanpassen...
Ik ga het morgen zeker eens uitproberen!
Alvast bedankt,
Kevin
Die code werkt bij een éénmalige aanroep ja. Als je de code volgt, kunnen channel bits alleen 1 worden, en gaan nooit meer naar 0 vanwege de or. 0b0111 |= 0b0000 = nog steeds 0b0111.
Het stukje code komt vast uit iets dat van maar 1 (configureerbaar) kanaal leest of zo. Een andere mogelijkheid is dat in het origineel InitADC() steeds wordt aangeroepen voor dat ReadADC wordt aangeroepen. Stukjes code rippen is prima maar werk het altijd door. Net als mensen dat zo leuk kunnen met forum posts, kun je ook code uit zijn verband trekken waardoor het niet helemaal meer juist is 
Beter is het om proberen te doorgronden wat de voorbeeld source doet en dan zelf iets schoons op poten zetten met de vergaarde kennis. Anders kun je je inderdaad het apezuur zoeken naar wat er eventueel mis kan zijn.
kevin_
Don't Blame Me, Blame Yourself..
en zo gebeurt het ook in het echte leven; iets wordt doorverteld zonder de context te weten.
Morgen nog eens heel het stukje ADC, de theorie overlopen 
Dank je om mij iets bij te leren!
Op 19 mei 2010 22:48:03 schreef kevin_:Morgen nog eens heel het stukje ADC, de theorie overlopen
De AVR datasheet is alles wat je nodig hebt, dan met name het hoofdstukje over de ADC. Eens bekijken wat voor registers dat ding nou heeft, welke bits er in zitten en wat ze doen. Naast deze rauwe data is de datasheet ook de handleiding voor de devices. De manier van initaliseren, afhandelen van interrupts e.d. wordt ook allemaal netjes uitgelegd.