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...