PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : potentiometer abfragen



fabiii9
02.03.2014, 20:00
hallo zusammen,
ich habe ein Potentiometer an den ADC Eingang 2 eines atmega8 angeschlossen.

Nun möchte ich, dass wenn ich an diesem Poti drehe, je nachdem welcher wert am poti eingestellt ist, die eine bzw. die andere LED leuchtet.

Ich habe hier schonmal ein Code.
Allerdings funktioniert der nicht ganz.

was ist falsch??


#include <avr/io.h>


void adc_init (void){

//interne Referenzspannung
//ADMUX = 0xC0;

//AVCC
//ADMUX = 0x40;

//AREF
ADMUX = 0xC0;


ADCSRA = 0x80; //ADC aktivieren, Rest 0 setzen

//ADCSRA |= 0x01; //Vorteiler 2
//ADCSRA |= 0x02; //Vorteiler 4
//ADCSRA |= 0x03; //Vorteiler 8
//ADCSRA |= 0x04; //Vorteiler 16
ADCSRA |= 0x05; //Vorteiler 32
//ADCSRA |= 0x06; //Vorteiler 64
//ADCSRA |= 0x07; //Vorteiler 128

ADCSRA |= (1<<6); //Konvertierung starten

while(ADCSRA & (1<<6)){}; //Kovertierung beendet

uint16_t ergebnis = 0;

ergebnis = ADCL;
ergebnis += (ADCH<<8);

}



uint16_t adc_read (uint8_t kanal){

static uint8_t init = 0;

if(init==0){adc_init(); init++;} //beim ersten Aufruf zunaechst initialisieren

ADMUX &= (0xE0); //Vorhandenen Wert fuer den Kanal loeschen

//den Wert fuer den Kanal schreiben, dabei die vorderen 3 Bits vor evtl. fehlern schuetzen

ADMUX |= (kanal&(0x1F));

ADCSRA |= (1<<6); //Konvertierung starten



while(ADCSRA & (1<<6)){}; //Kovertierung beendet

uint16_t ergebnis = 0;

ergebnis = ADCL;
ergebnis += (ADCH<<8);

return ergebnis; //Ergebnis zurueckgeben

}

int main(void)
{
float messung;

DDRD = 0b00111111;
while(1)
{
messung = adc_read(uint8_t x);

if( messung<=1 ){
PORTD = 0b00000001;
}
else {
PORTD = 0b00000010;
}

}
}

Diese Fehlermeldung kommt:
Error 1 expected expression before 'uint8_t' C:\Dokumente und Einstellungen\user\Desktop\Fader_poti\Fader_2\Fade r_2\Fader_2.c 73 22 Fader_2

was ist an dem Code falsch???

Vielen lieben Dank für eure Unterstützung!!!

Gruß
Fabi

BMS
02.03.2014, 21:06
Hallo,
der Compiler grenzt den Fehler eindeutig auf die Zeile 73 ein, also diese hier:

messung = adc_read(uint8_t x);
Anstatt "uint8_t x" muss natürlich die Nummer des zu messenden Analogeingangs stehen. So hast du es doch auch in adc_read drin!?

Die if-Bedingung mit <=1 wird im Testaufbau vermutlich kaum erreicht, der Rückgabewert von adc_read liegt im Bereich 0...1023. Unter 1 ist recht unwahrscheinlich, da können schon kleinste Offsetfehler das Zünglein an der Waage sein.

Solche Konstrukte sind zwar korrekt, lassen sich jedoch nachträglich schwer nachvollziehen und sind meist nicht portierbar:

ADMUX = 0xC0;
ADCSRA = 0x80; //ADC aktivieren, Rest 0 setzen
ADCSRA |= 0x05; //Vorteiler 32
ADCSRA |= (1<<6); //Konvertierung starten
Lieber an der Stelle die Bits angeben: (1<<deinbit) und bei Bedarf ver-oder-n.

*Hust* http://diyundso.de/?page=6 :Haue

Grüße, Bernhard

fabiii9
03.03.2014, 11:25
Hallo Bernhard,
vielen, vielen Dank für deine Antwort !!!!

Es funktioniert einwandfrei !!!!

Hier der Code für die anderen Leute, die es interessiert und die eine Lösung suchen.


#include <avr/io.h>


void adc_init (void){

//interne Referenzspannung
//ADMUX = 0xC0;

//AVCC
//ADMUX = 0x40;

//AREF
ADMUX = 0xC0;


ADCSRA = 0x80; //ADC aktivieren, Rest 0 setzen

//ADCSRA |= 0x01; //Vorteiler 2
//ADCSRA |= 0x02; //Vorteiler 4
//ADCSRA |= 0x03; //Vorteiler 8
//ADCSRA |= 0x04; //Vorteiler 16
ADCSRA |= 0x05; //Vorteiler 32
//ADCSRA |= 0x06; //Vorteiler 64
//ADCSRA |= 0x07; //Vorteiler 128

ADCSRA |= (1<<6); //Konvertierung starten

while(ADCSRA & (1<<6)){}; //Kovertierung beendet

uint16_t ergebnis = 0;

ergebnis = ADCL;
ergebnis += (ADCH<<8);

}



uint16_t adc_read (uint8_t kanal){

static uint8_t init = 0;

if(init==0){adc_init(); init++;} //beim ersten Aufruf zunaechst initialisieren

ADMUX &= (0xE0); //Vorhandenen Wert fuer den Kanal loeschen

//den Wert fuer den Kanal schreiben, dabei die vorderen 3 Bits vor evtl. fehlern schuetzen

ADMUX |= (kanal&(0x1F));

ADCSRA |= (1<<6); //Konvertierung starten



while(ADCSRA & (1<<6)){}; //Kovertierung beendet

uint16_t ergebnis = 0;

ergebnis = ADCL;
ergebnis += (ADCH<<8);

return ergebnis; //Ergebnis zurueckgeben

}

int main(void)
{
float messung;

DDRD = 0b00111111;
while(1)
{
messung = adc_read(2);

if( messung<=500 ){
PORTD = 0b00000001;
}
else {
PORTD = 0b00000010;
}

}
}


Gruß
Fabi

oberallgeier
03.03.2014, 13:12
... Hier der Code für die anderen Leute, die es interessiert und die eine Lösung suchen.


...
uint16_t ergebnis = 0;

ergebnis = ADCL;
ergebnis += (ADCH<<8);
...Hi Fabi, schön, Glückwunsch. ABER wer mit dem AVR-GCC arbeitet hat einen cleveren Compiler, der nimmt einem die Arbeit beim Auslesen der 16bittigen Register datenblattgerecht ab. Das könnte dann vereinfacht werden zu
...
uint16_t ergebnis = 0;

ergebnis = ADC;
...So läufts bei mir (seit Jahren). Peanuts, sicher, aber eine Zeile gespart und übersichtlich(er).

PS/Hinweis: wichtig ist die Auslesezeit/Sampelzeit für den ADC. Der will laut Datenblatt für maximale Genauigkeit eine Arbeitsfrequenz zwischen 50kHz und 200kHz.

fabiii9
03.03.2014, 15:20
danke für den Tipp :)

Gruß
Fabi