Hallo Wie baut man am besten mit einem ATMEGA8 in Assembler einen Ringspeicher auf, so dass aus je 16 Messwerten (24bit) ein Mittelwert berechnet und dann ausgeben/gespeichert wird. Es soll bei jedem Durchlauf ein neuer Messwert hinzukommen und ein alter herausfallen. Vielen Dank für Vorschläge Moin
Ich würde es mit einem umlaufenden Pointer machen, dann muß man keine Speicherinhalte verschieben.
Wo ist das Problem??? im Ram die Register definieren und ueber einen Pointer laufen lassen.. Wert schreiben, Pointer ein hoch Wert schreiben, Pointer ein hoch Wert schreiben, Pointer ein hoch Wert schreiben, Pointer ein hoch ... .. Wert schreiben, Pointer ein hoch Wenn Pointer = X + 16 Dann Pointer = X + 0 sollte doch nciht so schwer sein ;)
Geht auch Mittelwert über 256 Messungen? Dann wirds billiger und braucht nur 2 (und 1 temp.) Register... in tmp,adch ;ADC lesen sub awl,awh ;1/256 subtrahieren, um Platz für sbc awh,null ;den neuen Messwert zu machen add awl,tmp ;Neuen Wert zum alten Wert addieren adc awh,null ;Übertrag auch ...
@...HanneS..., wärst Du so lieb und würdest Du mir die Routine kurz erläutern ? So richtig komm ich da nicht durch :( Gruß Dennis
Hi Dennis... Ich dachte, es wäre ausreichend kommentiert... Diese Routine läuft bei mir im Tiny15 in einer Spannungsüberwachung. ;awh enthält den ganzzahligen Anteil des Mittelwertes. ;Dieser wird in der Reset-Routine auf einen Startwert gesetzt. ;Bei mir macht das die erste ADC-Messung vor "Scharfschaltung" der ;Spannungsüberwachung. ;awl enthält den "Nachkomma-Anteil" des Mittelwertes, also ;ein 256tel der Wertigkeit von awh. ;Die Bezeichnungen awh und awl kommen von AnalogWert H/L, da ;es bei mir nunmal (außerhalb des MC) Analogwerte waren. ;Der Neuwert wird nach temp eingelesen, wo der herkommt, ist ;eigentlich egal. In meinem Beispiel ist es ein 8-Bit-Wert vom ADC. in tmp,adch ;ADC lesen ;Der Neuwert soll mit einer Wertigkeit von 1/256 in den ;Mittelwert eingehen. Dazu ist aber zuerst Platz für ihn zu machen, ;indem man 1/256 des momentanen Mittelwertes vom Mittelwert ;subtrahiert. Nun könnte man den (16-Bit-) Mittelwert durch 256 ;teilen indem man ihn um 8 Stellen nach rechts schiebt. Dann wäre ;das obere Byte leer und das untere Byte enthält den Wert des ;oberen Bytes. Also kann ich gleich das obere Byte von den beiden ;Bytes subtrahieren, aber um 8 Bits (1 Byte) nach rechts versetzt. ;Da dabei der Subtrahend nicht verändert wird, kann man gleich das ;H-Byte vom L-Byte (mit Übertrag) subtrahieren. sub awl,awh ;1/256 subtrahieren, um Platz für ;Da hier ein Übertrag auftreten kann, muss dieser behandelt werden. ;dazu wird das Carry vom H-Byte subtrahiert. Dies geschieht über ;ein (unteres, "billiges") Register, welches immer 0 enthält und ;demnach "null" genannt wird. sbc awh,null ;den neuen Messwert zu machen ;Nun wird 1/256 des Neuwertes zum Mittelwert (dem jetzt 1/256 seines ;Wertes fehlt) addiert. Anstatt ihn nun durch 8 mal rechtsschieben ;durch 256 zu teilen, wird er einfach um 8 Stellen nach rechts ;versetzt addiert, also in den Nachkommabereich (L-Byte). add awl,tmp ;Neuen Wert zum alten Wert addieren ;Da auch hier ein Übertrag entstehen kann, muss das Carry zum ;H-Byte addiert werden. Dies geschieht wieder durch Addition von ;Null mit Carry. adc awh,null ;Übertrag auch ;Nun steht der neue Mittelwert im H-Byte. Diese Routine ist sehr sparsam mit Ressourcen (Programmspeicher, Datenspeicher, Rechenzeit) und filtert in meiner Spannungsmessung wirkungsvoll Störungen aus. Um das auf 16-Bit-Werte zu ergänzen, musst du 3 Bytes nutzen. Die oberen 2 Bytes stellen den Mittelwert dar, das untere den Nachkomma-Anteil. Man subtrahiert dann die oberen 2 Bytes um ein Byte nach rechts versetzt vom Mittelwert (mit Übertrag ins obere Byte) und addiert den 16-Bit-Neuwert in die unteren beiden Bytes (mit Übertrag ins Obere). Das wars eigentlich schon. ...HanneS...
Hier die 16-Bit-Version... Es genügen untere Register: .def null=r2 ;immer Null (braucht man immer) .def mwh=r3 ;Mittelwert High .def mwl=r4 ;Mittelwert Low .def mw0=r5 ;Nachkommastellen des Mittelwertes .def nh=r6 ;Neuwert High .def nl=r7 ;Neuwert Low mittelwert: sub mw0,mwl ;1/256 des Mittelwertes sbc mwl,mwh ;vom Mittelwert sbc mwh,null ;subtrahieren add mw0,nl ;1/256 des Neuwertes adc mwl,nh ;zum Mittelwert adc mwh,null ;addieren Benötigt 6 Worte im Flash und 6 Takte zur Ausführung. ...
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.