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
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.
Vielleicht schwingt dein AD-Wandler . Ein Kondensator am Eingang kann da vielleicht helfen. Gruß Henning
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 . . .
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
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.
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
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.