Forum: Mikrocontroller und Digitale Elektronik AD-Wandler spinnt . . .


von Matthias (Gast)


Angehängte Dateien:

Lesenswert?

Hallo!

ich habe ein Minimalprogramm
für eine AD-Wandlung mit dem 10bit-ADC
des 8535 eingetippt und gebe nun
in einer Schleife die gewandelten Werte von Pin AD0 mit 9600bd auf der 
seriellen SS aus.

Leider scheinen die bits zu klemmen:
Will heißen, dass es in der Anzeige Sprünge von mehr als 1bit gibt, wenn 
ich die Spannung ganz langsam am ADC-Pin hochdrehe.

An der seriellen Ausgabe liegt es nicht:
Wenn ich temp am Ende jedesmal eins hoch-
zähle, so wird das korrekt ausgegeben.

An der Hardware liegt es wohl auch nicht:
Wenn ich das Bascom-Demo für den ADC
laufen lasse, so kommen mit derselben
Hardware alle bits sauber hintereinander
ohne Lücken.

Was ist also verkehrt an dem winzigen
Assemblerprogramm?



Die anhängende Datei enthält den kompletten
Code, den ich zum Test verwendet hatte.
Viel Code darin ist überflüssig. Er wird
jedoch nicht benutzt. Hier der Auszug.


; ADC init: ADC ein,warte noch,free run,
;           INT aus,full speed
  ldi temp,0b10100000
  out ADCSR,temp


  ldi temp,0x00
  out ADMUX,temp ;Eingang AD0

  sbi ADCSR,ADSC ;StartADC im free run


loop_adc:

    ;hole aktuellen ADC-Wert
  in temp,ADCL    ; ADC lo
  in temp1,ADCH    ; ADC hi

  push temp    ;

    ; obere 2 bit
  mov temp,temp1    ; obere 2bit
  rcall hexascii
  rcall serout

    ; untere 8 bit
    ; erst oberes Halbbyte
  pop temp    ; lo-byte
  push temp    ;

  swap temp    ;
  andi temp,0b00001111  ;
  rcall hexascii
  rcall serout

  pop temp    ;
  push temp

  andi temp,0b00001111  ;
  rcall hexascii
  rcall serout

    ; sende CR
  ldi temp,0x0d
  rcall serout

  pop temp
  ;inc temp
  rcall delay100ms
  rjmp  loop_adc  ;

;--- schicke Zeichen auf serielle SS raus
; Zeichen aus:  temp
; veraendert:   SREG
serout:
  sbis USR,UDRE    ; UDR leer?
  rjmp serout
  out UDR,temp
  ret


;--- hex to Ascii-Wandlung -------
; Zeichen aus: temp
; veraendert:  SREG
hexascii:
  cpi temp,0x0a  ;
  brsh buchstabe  ;
  ;add temp,0x30  ; aus 0-9 wird 30-39
  subi temp,-48
  ret

buchstabe:
  ;add temp,55  ; aus a wird 65
  subi temp,-55
  ret

von Jonas Diemer (Gast)


Lesenswert?

zu dem thema gabs mal nen thread, weiß aber nicht, obs da ne lösung gab:

http://www.mikrocontroller.net/forum/read.php?f=1&i=1291&t=1291


is ja recht komisch, wenn das bascom programm einwandtfrei funzt... nen 
fehler hab ich in deinem prog auch nicht gefunden.

von Henning (Gast)


Lesenswert?

Vielleicht schwingt dein AD-Wandler . Ein Kondensator am Eingang kann da 
vielleicht helfen.

Gruß
Henning

von Jonas Diemer (Gast)


Lesenswert?

dann müsste das bascom programm ja auch spinnen...

von Matthias (Gast)


Lesenswert?

Danke für Eure wertvollen Tipps!
Mir haben sie ein gutes Stück weit geholfen!

Herzlichen Dank an Jonas für den Link!

Der eine Fehler lag an der zu hohen Taktrate
des ADC. Wenn ich den Teilerfaktor zu 64 oder
gar 128 wähle, so lande ich im zulässigen
Bereich des ADC von 50-200kHz.

; ADC init: full speed  -> /64
    ldi temp,0b10100000 -> 0b10100110
    out ADCSR,temp

Beim Bascom macht das der Befehl Prescaler Auto wohl selber richtig.

Viele bits sind nun ok. An manchen Stellen (z.B. 999->1003 o.ä.) 
springen sie aber immer noch. Manchmal sogar gleich um 3-4lsb. Und das 
reproduzierbar! So als ob der
Wandler hier missing codes hätte.

Solch ähnliches passiert allerdings auch beim BASCOM bei Prescaler Auto.

Schaut also nach einem Aufbaufehler oder
Chipgenauigkeitsfehler aus.

Entstör-C`s 100n habe ich dicht am Chip dran.
Zwischen Vcc und GND und auch Vref und AGND.
AGND und GND sind über eine kurze Leitung
verbunden. Von VCC habe ich eine Drossel
nach Vref.

Am AD0-Eingang hängt direkt ein 100nF-
Block-C nach AGND und ein Vorwiderstand.

Manche bits zählt er klaglos sauber einzeln hoch, bei anderen dann 
springt er plötzlich sauber reprozierbar.
Erstaunlicherweise sind die Sprünge bei Bascom dann wieder an einer 
anderen Stelle.

Mysteriös! Ich habe keine Massefläche. Der Eingang lag zwischen GND und 
AD0.
(Sollte aber wohl AGND und AD0 sein, ist mir mittlerweile klar!).

Ob da zwischen GND und AGND solch hohe transiente Ausgleichströme 
fließen, daß der
Fehler von 2-3 LSB daher kommt?

Diffizile Materie . . .

Das kann ich noch mal probieren . . .

von Günter König (Gast)


Lesenswert?

Moin Matthias,
schalte vom Eingang ADC parallel zu deinem 100nF noch mal einen Elko von 
2,2µF - 22µF.
Dann dürfte es nicht mehr springen.
Gruß,
Günter

von Matthias (Gast)


Lesenswert?

Hallo Günter,

mit solch großen Kapazitäten wird der ADC
natürlich recht träge, falls sich die
Eingangsspannung ja doch einmal ändern
sollte . . .

Und gerade eine schnelle Einschwingzeit
ist mir ja wichtig.

Trotzdem Danke für die Idee.

von Günter König (Gast)


Lesenswert?

Im Prinzip hast du recht Matthias, aber soooooo träge wird der selbst 
mit 22µF noch nicht. Aber bremsen sollte man ihn schon. Und ich kann mir 
nicht vorstellen, das du jeden Peak auf der Spannung messen willst. Ein 
bisschen Glättung tut gut.

in diesem Sinne,
Günter

von Jonas Diemer (Gast)


Lesenswert?

irgendwo im avr manual stehen noch ein paar tipps, um die genauigkeit zu 
verbessern. man kann zB den µc beim wandeln in eine art sleep modus 
schicken, dann stört er die messung nicht...

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.