Gute Abend miteinander,
seit heute Mittag schreibe ich ein kleines Programm, was den ADC
ausließt und bei einem Bestimmten Wert Lämpchen leuchten lassen soll.
Dies habe ich in ASM für einen Atmega8 geschrieben.
Das Programm selber läuft nun ohne Probleme, Allerdings habe ich unter
bestimmten Umständen einen recht seltsamen Fehler.
Mir genügt eine Auflösung von 8 Bit. Deshalb lese ich zwar beide Bytes
des ADC aus (High und Low), verwende aber nur das Low Byte.
Hierbei habe ich folgenden Fehler:
Die Anweisungen (wtr0 bis wtr7) werden viel zu früh ausgeführt.
Die Anweisungen werden bei etwa einem Drittel der Spannung ausgeführt
bei der sie es eigentlich sollten. Erhöhe ich die Spannung weiter, geht
es wider von vorne los. Sprich von wtr0 bis wtr7. Einen Dritten
Durchlauf gibt es dann noch, dann ist PortD komplett auf 1.
Ich habe das Problem nun wie folgt (so wie es auch im Code unten steht)
behoben: Mit setzen des ADLAR Bits vertausche ich das High und das Low
Byte aus. Ich lese wie davor auch beide Bytes aus, verwende nun aber das
High Byte. So leuchten die LEDs nun bei der Spannung bei der sie es auch
sollen. Im Grunde genommen ist nichts anders, zumindest der Wert der
ausgelesen wird nicht. Nur das Register unterscheidet sich.
Wenn ich allerdings anstatt den Anweisungen (wtr0 bis wtr7) den Wert des
ADC direkt binär auf meine LEDs ausgebe, macht es nun keinen Unterschied
ob ich direkt das Low Byte verwende, oder das High mit dem Low tausche
und dann das High Byte benutze.
Welchen Hintergrund hat der Fehler nun?
K. M. schrieb:> sbi ADCSRA, ADSC> in temp2, ADCL> in temp, ADCH
Sollte man nicht warten bis die Messung beendet ist und dann erst die
Messwerte verwenden? Du liest sie sofort nach Start der Messung aus.
Du musst vor dem abholen der Messwerte das Bit ADSC im Register ADCSRA
abfragen. Erst wenn das 1 ist, ist die ADC-Wandlung auch abgeschlossen.
Des Weiteren sollte man nach dem Einschalten einmal eine Wandlung
durchführen, da bei dieser ersten Messung nur Murx rauskommt.
K. M. schrieb:> Ich habe das Problem nun wie folgt (so wie es auch im Code unten steht)> behoben: Mit setzen des ADLAR Bits vertausche ich das High und das Low> Byte aus.Nein, tust du nicht.
Du schiebst nur den Wert ganz nach links, somit hast du in High Byte
8 bit Wert und nur die niederwertigen 2 bits bleiben im Low Byte.
> Welchen Hintergrund hat der Fehler nun?
Welcher Fehler ?
Kein Fehler vorhanden, ausser dass du die entsprechenden bits in
ADCSRA nicht abfragst.
Hi
Schau mal ganz oben links unter Home steht AVR und in dieser Rubrik
findest du AVR-Tutorials, die beschreiben, wie der AD-Wandler benutzt
werden kann.
Gruß oldmax
Hier noch ein kleiner Tipp, um die endlose Vergleichsorgie zu
beschleunigen. Du hast 8 Zustände, kannst also aus dem ADC Ergebnis
einfach durch ein wenig Swappen und Rollen einen Zeiger in eine Tabelle
zusammenbasteln:
Genuaso könntest du auch schon mal den ADC starten und währendessen die
o.a. Routine durchackern lassen, während der ADC noch wandelt. Puristen
könnten dann allerdings einwenden, das das schalten der LED mögl. den
ADC beeinflusst.
Ich vermute, dass das dein Problem ist:
>Mir genügt eine Auflösung von 8 Bit. Deshalb lese ich zwar beide Bytes>des ADC aus (High und Low), verwende aber nur das Low Byte.
Was du eigentlich brauchst sind die zwei Bit aus dem highByte und die
höchsten 6 Bit aus dem lowByte.
Man kann einen right und einen left adjusted mode für den ADC
einstellen. Ich weiß nicht mehr, welchen man benutzt, wenn man nur die 8
Bit braucht.
Das steht explizit im Datenblatt beschrieben.
Ich tippe mal, dass dein lowByte logierweise ein paar Mal überläuft,
wenn du die Eingangsspannung am ADC hochdrehst.
Hi
Maude schrieb:> Man kann einen right und einen left adjusted mode für den ADC> einstellen. Ich weiß nicht mehr, welchen man benutzt, wenn man nur die 8> Bit braucht.
Man nimmt bei Leftadjust das Highbyte, da die niederwertigen Bits im
Lowbyte 6 und 7 sind,
right adjust: 00000011 11111111
left adjust: 11111111 11000000
Läßt man das Low-Byte weg, bleiben nur die höherwertigen Bits und ein
digitalisierter Wert zwischen 0 und 255 übrig.
Zum Programmierstil hab ich absichtlich noch nichts gesagt. Klar, es
gibt immer Ansichten, wie es besser gemacht werden kann und klar, man
wächst mit der Zeit. Auch wird man erkennen, das es vielleicht sinn
macht, das Einlesen und das Auswerten der Analogwerte n eigenen Routinen
durchzuführen. Auch Einrücken von Zeilen macht gelegentlich Sinn. Und
Kommentare. Auch wenn man glaubt, es tut nicht not, nach einem Monat ist
oft der Faden gerissen und ohne Kommentare aufarbeiten wird dann
zeitraubend. Wie sowas aussehen kann ist ja bereits mehrfach
beschrieben. Dann ist Assembler auch lesbar.
Gruß oldmax
Maude schrieb:>> Ich weiß nicht mehr, welchen man benutzt, wenn man nur die 8> Bit braucht.> Das steht explizit im Datenblatt beschrieben.> Ich tippe mal, dass dein lowByte logierweise ein paar Mal überläuft,> wenn du die Eingangsspannung am ADC hochdrehst.
Also ich habe mir das Datenblatt mal angeschaut und auf Seite 195 wird
man darauf hingewiesen, dass es ausreicht bei 8bit Genauigkeit das High
Byte zu lesen. Es heißt dort "ausreichend". Sollte wohl in "muss"
geändert werden.
Danke für die Info :).
Hi
Ja, es reicht, das Highbyte zu lesen, wenn du die Bits entsprechend
gesetzt hast. Highbyte hat sonst eben nur die zwei höchstwertigen Bits,
von daher ist deine Aussage ohne den Bezug auf die Ausrichtung falsch.
Das Bit ADLAR muss gesetzt sein.
>The ADLAR bit in ADMUX, and the MUXn bits in ADMUX affect the way the >result is
read from
>the registers. If ADLAR is set, the result is left adjusted. If ADLAR is >cleared
(default), the result
>is right adjusted.
Gruß oldmax