AD-Wandler spinnt . . .

Gast #4450
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
Angehängte Dateien:
Gast #4454
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 . . .
Gast #4455
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
Gast #4456
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.
Gast #4457
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
Gast #4458
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...

Antwort schreiben

Eine eigene Frage? Dieser Thread ist über 24 Jahre alt. Stell sie in einem eigenen Thread – dort lesen mehr Leute mit, und sie wird öfter und schneller beantwortet.

Neuen Thread starten

Eine Lösung, Ergänzung oder Rückmeldung zu diesem Thread? Dann antworte hier.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.