PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : ATMEGA2560 ADC-Kanäle lesen



bart
29.03.2007, 17:49
Hallo,

ich bastle gerade mit dem RN-Atmega2560 herum, bekomme es aber nicht hin die ADC Kanäle auszulesen, habe etwas Angst da einfach so was rumzuprogrammieren damit das ding nicht den Geist auf gibt.

Ich verwende folgende Funktion zum auslesen (hat bei einemATMEGA8 funktioniert).

Die Zeilen im Code wo die Fragezeichen dahinter stehen, hab ich selbst hinzugefügt. (im Datenblatt gefunden).

Die Funktion gibt jedoch immer den konstanten Wert 510 komischerweise.

Wäre toll wenn jemand hilft.




uint16_t GetAdc(uint8_t pin) {

// min Prescaler = µC Frequ / 200 KHz & max Prescaler = µC Freq. / 50 khz = min 80 & max 320
ADCSRA = (1<<ADEN) | (1<<ADPS2) | (1<<ADPS1); // Prescalar = 128
ADCSRB = (1<<ACME); //??????????
DIDR0=0x03; //?????????

uint8_t i;
uint8_t ii;
uint16_t result;
uint16_t ergebnis;
ergebnis = 0;
// +------------ Dummy-Check ------------+
i = 5; // i x Dummy-Check
while(i){
ADMUX = pin; // Kanal waehlen
ADCSRA |= (1<<ADSC); // eine Wandlung "single conversion"
while(!(ADCSRA & (1<<ADIF))); // auf Abschluss der Konvertierung warten (ADIF-bit)
result = ADCL + (ADCH << 8); // Wandlungsergebnisse erfassen
result = 0; // Zurücksetzen
i--;
}
// +------------- Ermittlung ------------+
i = 10;
ii = i; // Schnitt aus i Ergebnissen
while(i){
ADMUX = pin; // Kanal waehlen
ADCSRA |= (1<<ADSC); // eine Wandlung "single conversion"
while(!(ADCSRA & (1<<ADIF))); // auf Abschluss der Konvertierung warten (ADIF-bit)
result = ADCL + (ADCH << 8); // Wandlungsergebnisse erfassen
ergebnis = ergebnis + result; // Aufaddieren
i--;
}
// +-------- Umrechnung & Ausgabe -------+
ergebnis = ergebnis / ii ;
return ergebnis;
}

Superhirn
29.03.2007, 18:58
Also was auf jeden fall besser wäre, wär wenn du "ergebnis = ADC" schreibst da das auselsen von 16bi registern nicht so einfach ist.

while(i){ ... wird nie gehen. sondern: ist auch eleganter
while((i--)>0) {
...
}
ich machs anders.

ergebnis = ergebnis / ii ; //Enelegant

(ADIF-bit) //was bedeutet das?
es reicht eine dummy zum warmlaufen und es reichen 3 wandlungen zum mittelwert bilden. sonst wartest ja so lange bis der wert da ist und dan stimmt er erst wieder nicht.

So schauts bei mir aus.

/*************************************************

AUTHOR: Thomas Grübler
Version: 0.1
Beschreibung: Erfasst werte am ADC Port

Beispielfunkton zum auslesen der Werte:
void beispiel(void)
{
uint16_t adcval;
adcstart();
adcval = adcget(0); // MUX-Bits auf 0b0000 -> Channel 0
adcval = adcget(2); // MUX-Bits auf 0b0010 -> Channel 2
adcstop();
}

*************************************************/

#include <avr/io.h>
#include "adc.h"
#include "usart.h"
#include "nuetzliches.h"
#define wandlungen 3

void adcstart(void);
void adcstop(void);
uint16_t adcget(uint8_t kanal);

void adcstart(void) {
ADCSRA |= ((1<<ADPS0) | (1<<ADPS1) | (1<<ADPS2) | (1<<ADEN));//ADPS0-2(Vorteiler 128), ADEN (Enable)

ADMUX = 0;
ADMUX |= (1<<REFS1) | (1<<REFS0);

ADCSRA |= (1<<ADSC); // eine ADC-Wandlung als Dummy zum warmlaufen
while ( ADCSRA & (1<<ADSC) ) {
; // auf Abschluss der Konvertierung warten
}
}

void adcstop(void) {
ADCSRA &= ~(1<<ADEN);
}

uint16_t adcget(uint8_t kanal) {
uint8_t i = 0;
uint16_t ergebnis = 0;

ADMUX = kanal; // Kanal waehlen
ADMUX |= (1<<REFS1) | (1<<REFS0); // interne Referenzspannung nutzen

while (i!=wandlungen) { //Mehrere wandlungen und durchschnittswert ermitteln
ADCSRA |= (1<<ADSC); // eine Wandlung "single conversion"
while ( ADCSRA & (1<<ADSC) ) {
; // auf Abschluss der Konvertierung warten
}
i++;
ergebnis += ADC;
}
ergebnis = ergebnis/wandlungen; //Durchschnittswert bilden

return ergebnis;

}

bart
29.03.2007, 19:19
Also die Funktion so wie Sie oben steht funktioniert in meinem ATMega32 problemlos.

Ich habe deine auch mal testweise eingebunden, liefert aber genau das gleiche zurück.

Beim ATMega2560 muss man warscheinlich noch das ADCSRB und DIDR0 setzen, aber wie ?...

Superhirn
29.03.2007, 19:42
Damit kenn ich mich leider nicht aus. da ich bis jetzt nur m16 und m32 benutzte. und mein nächster schritt ein pc sein wird :)

bart
30.03.2007, 14:28
Kann ich eingendlich die Kabel direkt an die Pins anschliessen oder müssen da noch irgendwelche Kondenstoren oder Widerstände dran?

Superhirn
30.03.2007, 20:36
Du kannst sie direkt anschliesen solange sie die referenzspannung nicht übersteigen. und falls du zb nur ein poti hast einen pullup/down widerstand nicht vergessen.
bei vcc-widerstand-adc wär immer die selbe spannung zu messen.