ADC auf free running mode umstellen (Interrupt)

Persönliche Seite #3344967
Lesenswert?

Hallo Leute,

ich hoffe das ist das richtige Forum dafür, ich schreibs einfach mal.
Vorab ein paar Infos:
ich baue gerade an einem Fußballroboter für den Robocup.
Dort wird ein IR-Ball eingesetzt, weshalb ich auch IR-Sensoren brauche.
Board: atmega2560
ADC: boardeigen
Das Spiel ist sehr auf Geschwindigkeit ausgelegt, weshalb ich die 
Methoden, die Sensoren auslesen und die Motoren steuern, in Interrupts 
legen wollte.


Mein Problem ist:
ich habe eine funktionierende ADC-Methode von einem Freund bekommen.
1
uint8_t readAnalogSensor(uint8_t num)
2
{
3
    if(num>15)
4
    {
5
        return 0;
6
    }
7
    ADMUX=(num & 0x7)|(1<<ADLAR);
8
    ADCSRB = (ADCSRB & ~(1<<MUX5))|(num & (1<<MUX5));
9
    ADCSRA|=(1<<ADIF)|(1<<ADSC);
10
    while(!(ADCSRA&(1<<ADIF)));
11
    ADCSRA|=(1<<ADIF)|(1<<ADSC);
12
    while(!(ADCSRA&(1<<ADIF)));
13
    return ADCH;
14
}
ADC-Config:
1
ADCSRA  = (1<<ADEN)|(1<<ADPS2);
2
ADCSRA |= (1<<ADIE);
3
ADCSRA |= (1<<ADATE);
4
ADCSRB &= ~(1<<ADTS0);
5
ADCSRB &= ~(1<<ADTS1);
6
ADCSRB &= ~(1<<ADTS2);
7
ADCSRA |= (1<<ADSC);
ich würde aber lieber den free-running-Mode(für alle 15 Sensoren) 
einsetzen und dann beim Interrupt den Wert in ein Array schreiben.

Deswegen: wie geht das Mit dem Multiplexer und Interrupts?
Stimmt überhaupt meine Config?
in welche Register wird der Wert der einzelnen Kanäle geschrieben?

hoffe ich habe keine Infos vergessen
Wäre für Hilfe dankbar
Persönliche Seite #3344975
Lesenswert?

Ingo schrieb:
> Hat der Mega2560 wirklich so viele ADC-Kanäle? Das du auch im Freerun
> nur einen Kanal abtasten kannst ist dir klar?
war mir eig klar, wollte trotzdem fragen

Ingo schrieb:
> Hat der Mega2560 wirklich so viele ADC-Kanäle?
ja. sind bei uns alle genutzt

kann man mein Kozept über den Haufen werfen, oder gibt es noch andere 
Möglichkeiten?
#3344981
Lesenswert?

Ist die Doppelabtastung hier
1
    ADCSRA|=(1<<ADIF)|(1<<ADSC);
2
    while(!(ADCSRA&(1<<ADIF)));
3
    ADCSRA|=(1<<ADIF)|(1<<ADSC);
4
    while(!(ADCSRA&(1<<ADIF)));
Absicht?


Wenn ihr alle Kanäle benutzt und die reihum abtasten wollt, dann wirst 
du mit dem Free Running Mode keine Freude haben.

Mach es halt so, dass du den ADC in der Funktion erst ganz zum Schluss 
startest. Beim nächsten Aufruf der Funktion holst du dir das bis dahin 
vorliegende Ergebnis ab, setzt den Kanal auf den nächsten zu sampelnden, 
startest ihn und returnierst aus der Funktion. Während dann das Programm 
an anderen Dingen weiter arbeitet, macht der ADC in der Zwischenzeit 
sein Ding und beim nächsten Aufruf der Funktion liegt dann das Ergebnis 
vor, welches du dir abholst (und den ADC auf dem nächsten Kanal 
startest)
Auf die Art musst du auch nicht auf den ADC warten, hast aber eine 
einfache und eindeutige Zuordnung welches Ergebnis aus welchen ADC_Kanal 
stammt. Denn genau dieser Punkt ist es, der dir im Free Running Mode das 
Genick bricht.
Persönliche Seite #3344984
Lesenswert?

Ingo schrieb:
> STM32F4 eignet sich besser!
geht aus 2 Gründen nicht: wir nutzen schon seit Jahren AVRs. Und bei uns 
liegen noch 8 so Boards rum.

Karl Heinz Buchegger schrieb:
> Ist die Doppelabtastung hier    ADCSRA|=(1<<ADIF)|(1<<ADSC);
>     while(!(ADCSRA&(1<<ADIF)));
>     ADCSRA|=(1<<ADIF)|(1<<ADSC);
>     while(!(ADCSRA&(1<<ADIF)));
> Absicht?

ich denke schon, wie schon gesagt: die Methode ist nicht von mir

Danke Karl Heinz für deinen vorschlag, ich denke, wenn hier keine 
anderen Vorschläge mehr kommen, werde ich ihn in die Tat umsetzen.

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren