PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Probleme mit dem ADC



Basti87
06.11.2005, 13:26
Hallo,
ich habe bei mir einen Roboter angefangen zur Linienverfolgung.
Basis bildet ein Atmega64 Controller und als Programmierplattform E-Lab PED32 - Pascaldialekt.
Dazu möchte ich den ADC verwenden und habe auch schon die Werte mit getadc(i) abgefragt. Jedoch möchte ich gerne über die Register die Werte abfragen, da dies den Prozess beschleunigt. Bis dahin alles schön und gut, jedoch bekomme ich keine / unsinnige Werte über meine Abfrage.
Folgenden Code verwende ich für die ADC-Initalisierung und den Start der Konvertierung:


ADCSRA:=$CC;
FOR i :=0 TO 5 DO // i läuft von 0 bis 7 einmal durch
sensor:=i;
if i>0
then ADMUX:=$C0+Byte(potenz(2,word(i-1))); // AVCC, channel:=i
else ADMUX:=$C0;
endif;

//Hellwert
led[i]:=false; //LED einschalten
ADCSRA:=$CC; // Konvertierung starten
WaitSema(sema);


Die Werte werden im Interrupt eingetragen, der folgenderweise aussieht:


interrupt ADCRdy;
var sensl,sensh:byte;
begin
sensl :=ADCL;
sensh :=ADCH;

if led[i]
then
SensorN[sensor]:=(word(sensh) SHL 8) OR (word(sensl));
else
SensorL[sensor]:=(word(sensh) SHL 8) OR (word(sensl));
endif;

IncSema(sema);
end;

Die Register habe ich aus folgenden Gründen so gesetzt:
ADCSRA --> ADC einschalten, Konvertierung starten, kein Freilauf, Interrupt aktivieren und 16er Teiler
ADMUX --> interner Vergleich, rechtsjustiertes Ergebnis sowie Kanal

Als Wert bekomme ich für den 2. Sensor immer 259 und ansonsten 0 (z.T. aber auch Anzeigen wie "0 0" obwohl ich IntToStr(Sensor[i]:3) verwende).

izaseba
06.11.2005, 14:47
Hallo,
leider habe ich überhaupt keine Ahnung von Pascal, aber was bedeutet diese Zeile


SensorN[sensor]:=(word(sensh) SHL 8) OR (word(sensl)) ?

In welcher Reihenfolge werden die Register ausgelesen?
So wie das dort steht, zuerst ADCH und dann ADCL ?
Wenn ja ist das Dein Problem, es muß zuerst ADCL und erst dann ADCH
ausgelesen werden.

Am sonsten möge sich jemand melden, der Ahnung vom Pascal hat

Gruß Sebastian

Basti87
06.11.2005, 14:58
SensorN[sensor]:=(word(sensh) SHL 8 ) OR (word(sensl))

In welcher Reihenfolge werden die Register ausgelesen?
So wie das dort steht, zuerst ADCH und dann ADCL ?
Wenn ja ist das Dein Problem, es muß zuerst ADCL und erst dann ADCH
ausgelesen werden.

Das bedeutet, dass sensh 8 Bits nach links verschoben und dann ein logisches ODER mit sensl ausgeführt wird.
ADCL und ADCH werden weiter oben im Code in der richtigen Reihenfolge ausgelesen!

izaseba
06.11.2005, 15:27
Ja, stimmt ok, war ja nur ein Versuch.
Aber wie gesagt, von Pascal null Ahnung...

Gruß Sebastian

Rakke
07.11.2005, 21:19
Hei Basti,

bin auch kein Pascaller, das macht das Verstehen etwas zäh.

Eins kann ich mir vorstellen: du startest in deinem Code erst die Konvertierung (ADCSRA) und weist dann den Multiplexer zu. Da die Konvertierung schon läuft, wird der zugewiesene Kanal erst für den nächsten Durchlauf verwendet, d. h. deine Kanäle sind alle um eins verschoben. So ein Hinweis findet sich jedenfalls im Handbuch (ATMega 8, S. 203: Bits 3:0 – MUX3:0: Analog Channel Selection Bits; The value of these bits selects which analog inputs are connected to the ADC. See Table 75 for details. If these bits are changed during a conversion, the change will not go in effect until this conversion is complete (ADIF in ADCSRA is set).).

Versuch doch mal, erst den Kanal zuzuweisen und dann den ADCSRA auf 0xCC zu setzen. Ein ähnliches Problem hatte ich auch mal, allerdings mit freifliegender Konvertierung.

Viel Erfolg,
Rakke

Basti87
08.11.2005, 20:06
Danke für die Hilfe, aber das Problem lag an anderer Stelle!
Es gibt in dem Delphi-Programm eine Hilfsunit für den ADC. Diese hatte ich am Anfang benutzt, dann aber doch auf direkten Registerzugriff umgestellt. Doch die Implementierung hatte ich gelassen und diese löste unverständliche Fehler aus. Als ich diese löschte, erhielt ich prompt die richtigen Werte!