Forum: Mikrocontroller und Digitale Elektronik AD Wandlung beim Mega103


von Bernie Schybulla (Gast)


Lesenswert?

Hallo Zusammen,

ich muß mehrere Kanäle schenll hintereinander einlesen, leider
funktioniert dieses nur, wenn ich eine Millisekunde zwischen dem
Einlesen der einzelnen Kanäle vergehen lasse, ansonsten werden
komischerweise beim zweiten Kanal die Werte vom ersten eingelesen.

Vielleicht liegt auch ein anderer Fehler in meiner Routine vor.

Hier sind die beiden Routinen für das Einlesen, die ich nacheinander
aufrufe :

Analog_PIR1:

  ldi     Temp,$01   ; Einlesen Kanal 1
  out     ADMUX,Temp

  ldi     Temp,$C5  ; Initialisiere Wandler
  out     ADCSR,Temp
Flag_PIR1:
        sbis    ADCSR,4   ; Warte bis Wandlung beendet
  rjmp    Flag_PIR1

        in  Analog_L,ADCL  ; Lese Werte aus
  in  Analog_H,ADCH

  sts  sAnalog_L1,Analog_L  ; Speichere Werte
  sts  sAnalog_H1,Analog_H
  ret

Analog_PIR2:

  ldi     Temp,$02  ; Einlesen Kanal 2
  out     ADMUX,Temp

  ldi     Temp,$C5    ; Initialisiere Wandler
  out     ADCSR,Temp

Flag_PIR2:
        sbis    ADCSR,4     ; Warte bis Wandlung beendet
        rjmp    Flag_PIR2

        in  Analog_L,ADCL  ; Lese Werte aus
        in  Analog_H,ADCH

  sts  sAnalog_L2,Analog_L  ; Speichere Werte
  sts  sAnalog_H2,Analog_H
  ret

von Joerg Wunsch (Gast)


Lesenswert?

Irgendwo steht im Datenblatt, wie man die Umschaltung machen muß.
Du solltest wohl sofort nach dem Start einer Messung auf den
nächsten Kanal umschalten, da die tatsächliche Umschaltung ohnehin
bis zum Ende der laufenden Messung verzögert wird, so jedenfalls
habe ich es in Erinnerung.

von ERDI - Soft (Gast)


Lesenswert?

Lies mal das Datenblatt durch. Irgendwo steht, dass eine Änderung des
Kanals erst bei der nachfolgenden Wandlung übernommen wird. Du mußt
also schon während der Wandlung vom ersten Kanal auf den zweiten
umschalten, sonst misst du zweimal den ersten.
Ich denke mal, du hast den ADC im Free-running-mode?

von Bernie Schybulla (Gast)


Lesenswert?

Vielen Dank erstmal für die Antworten, leider funktioniert das so auch
nicht. Ich hatte auch vorher schon eine Test durchgeführt, bei dem ich
in jeder Routine den Wert 10 mal gewandelt habe bevor ich ihn
gespeichert hatte und das hat auch nicht funktioniert.

Wo steht denn im Datenblatt etwas darüber, ich kann da leider nicht
viel finden, nur das was ich oben umgesetzt habe !!!

von Bernie Schybulla (Gast)


Lesenswert?

Hallo Erdi,

wenn ich das richtig sehe kann der Mega103 nur im SingleConversion Mode
 betrieben werden !!! Der Free-running-mode existiert wohl erst beim
Mega128 !!!

von ERDI - Soft (Gast)


Lesenswert?

Hm, hast wohl recht. Free-Running gibts beim mega103 nicht. Schade, hab
noch 10 Stück, die damit für mich wohl nutzlos werden.
Hast du den Prescaler richtig eingestellt? Wenn der zu groß ist, dauert
ein Wandlung ziemlich lang. Und vor allem mußt du schon während der
ersten Wandlung den Kanal wechseln, sonst mißt du zweimal den gleichen
Kanal.
Wie sieht eigentlich deine komplette Initialisierung aus?

von Bernie Schybulla (Gast)


Lesenswert?

Hallo Erdi,

also als Initalisierung dachte ich eigentlich reicht das Beschreiben
des ADCSR Register, da gebe ich ja die Wandlung vor. Den Prescaler habe
ich auf 32 eingestellt, hatte ihn aber auch schon schneller. Aber das
dürfte ja nichts ausmachen, da ich ja das Flag abwarte und dann
eigentlich die Wandlung beendet sein sollte.

Es steht auch im Datenblatt, daß man den Kanal vor dem Start der
Wandlung auswählen muß und das mache ich ja oben. Also ich habe ehrlich
keine Ahnung woran es liegt ??? Habe ich denn noch etwas bei der
Initialisierung vergessen ???

Willst Du die 10 Mega103 zufällug verkaufen, dann frag ich mal meinen
Chef, weil der letztens noch welche suchte !!!

von ERDI - Soft (Gast)


Lesenswert?

Kannst du mal den ganzen Code posten? Habe gerade ein paar kleine
Probleme damit.
Warum benutzt du eigentlich keine IRQ-Routine. Der A/D-Wandler
generiert ja nen schönen Interrupt, wenn die Wandlung fertig ist.

Wenn dein Chef die brauchen kann, bin ich gerne bereit, die zu
verkaufen oder gegen mega128 oder ähnliches zu tauschen.

von Bernie Schybulla (Gast)


Angehängte Dateien:

Lesenswert?

Hallo Erdi,

habe gerade mit meinem Chef gesprochen und er will jetzt
wohl auch komplett auf die 128er umsteigen !!!

Ich habe mal die wichtigsten Teile des Codes angefügt. Eigentlich
ganz simpel, es werden zwei analoge Sensorsignale eingelesen und die
Werte zur Hex-Ausgabe auf einem Display umgewandelt. In der aktuellen
Form mit der Pause zwischen dem Aufrauf der Analogwandlungen
funktioniert das Einlesen auch bis auf die Tatsache, daß die Werte
nachher vertauscht sind. Also ist Signal 1 auf dem LCD in der zweiten
Zeile und Signal 2 in der ersten Zeile, was ich auch noch nicht
gecheckt habe.... Irgendwie verzweifel ich gerade daran :o)

von ERDI - Soft (Gast)


Lesenswert?

Welches ist denn dein erster Kanal? Nennt der sich ADC0? Also Kanal 0?
Dann muß deine Initialisierung anders lauten.
Was misst du denn? Hast du nen festen Wert anliegen, den du gerade
abfrägst? Oder ändert sich der Wert? Wenn ja, wie weißt du dann,
welches der richtige Wert für den jeweiligen Kanal ist?

von Bernie Schybulla (Gast)


Lesenswert?

Also ich habe die Signale an PINF0 (Kanal 1) und an PINF1 (Kanal2)
liegen. Wenn ich die Kanäle einzeln abfrage funktioniert alles
einwandfrei, nur nicht, wenn ich Sie hintereinander abfrage. Die SIgnal
liegen normal auf 0 Volt und ändern sich bei Bewegungserfassung bis
maximal 5 Volt. Die Signale beobachte ich dabei am Oscar, deswegen kann
ich überprüfen was eigentlich gerade für ein Wert angezeigt werden
muß.

Problem ist als, wenn ich Sie einzeln abfrage sind sie richtig, frage
ich sie direkt hintereinander ab, wird bei beiden Kanälen der angezeigt
der zuerst aufgerufen wurde, wenn ich eine Pause von 1ms zwischen den
beiden Aufrufen startet, dann werden sie vertauscht angezeigt !!!

Was meinst Du denn mit falscher Initialisierung ???

von Bernie Schybulla (Gast)


Lesenswert?

Also mit dem Interrupt bringt es auch keine Änderung !!!

von Bernie Schybulla (Gast)


Lesenswert?

Hey Erdi, es funktioniert, aber auf unerklärliche Weise !!!

Ich habe den Prescaler auf null gesetzt, daß ist laut Datenblatt aber
eigentlich "Invalid" . Also initalisiere ich den ADCSR mit $C0 und es
funktioniert !!! Kannst Du Dir das erklären ????

von ERDI - Soft (Gast)


Lesenswert?

Wenn du Kanal 0 (PF0) als ersten Kanal hast, muß bei deiner Kanalwahl
(ADMUX) 00h stehen, beim nächsten Kanal 01h.
Du solltest, noch bevor du das ADC-Complete-Bit pollst, den Kanal
wechseln, also folgendermaßen:

Analog_PIR1:

>>>  ldi     Temp,$00   ; Einlesen Kanal 1
  out     ADMUX,Temp

  ldi     Temp,$C5  ; Initialisiere Wandler
  out     ADCSR,Temp

>>>>ldi Temp,$01
>>>>out ADCSR, Temp

Flag_PIR1:
        sbis    ADCSR,4   ; Warte bis Wandlung beendet
  rjmp    Flag_PIR1

        in  Analog_L,ADCL  ; Lese Werte aus
  in  Analog_H,ADCH

  sts  sAnalog_L1,Analog_L  ; Speichere Werte
  sts  sAnalog_H1,Analog_H
  ret

Bei der zweiten Funktion auch. Allerdins solltest du dann sichergehen,
dass auch auf jeden Fall jeweils der nächste Kanal abgefragt wird.

; ******* AD-Wandler Initialisierung *******
    ldi     Temp,$C5     ; Initialisiere Wandler
    out     ADCSR,Temp   ;
>>>    sei         ; Disable Interrupts
Ist kein Interrupt Disable, sondern Enable.

von Bernie Schybulla (Gast)


Lesenswert?

Warum schreibst Du eine $01 in das ADCSR ??? Damit würdest Du doch den
Prescaler setzten ???

Komischerweise funktioniert es mit dem Prescaler auf null, allerding
habe ich dann ein Rauschen drin, deswegen würde ich den Prescaler
lieber auf CLK/32 oder noch tiefer setzen, dann habe ich aber wieder
die Probleme !!!

von ERDI - Soft (Gast)


Lesenswert?

Ups, sorry. Meinte natürlich den ADMUX. (Tja, schon der Lehrer hat immer
gesagt, dass abschreiben nix bringt. :-) )

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.