Michael D. wrote:
> HI Ich arbeite gerade das Toturial durch und es kalppt auch ganz gut.
> Nur habe ich jetzt das Problem, dass ich den Sourcecode aus dem
> ADC-Kapitel nicht vollstandig verstehe,was den andere Anfängern wohl
> auch so gehen dürfte.
>
> Hier die betreffende Passage:
>
>
1 | > cpi temp2,128 ; "Kommastelle" kleiner als 128 ?
|
2 | > brlo no_round ; ist kleiner ==> Sprung
|
3 | >
|
> Welche Kommastelle ist hier gemeint?
Es geht um Folgendes.
Angenommen du liest vom ADC 10 mal ein und summierst
die Ergebnisse auf und kriegst als Ergebnis eine Summe
von 127.
Dann wäre ja der Mittelwert, also der Wert der bei einer
enzigen Messung herauskommt, 12.7
Nun kannst du aber 12.7 nicht in einem Ganzzahl Register
speichern. Das Ergebnis kann entweder 12 oder 13 sein.
Bei 12.7 wirst da als Ergebnis 13 haben wollen, da 12.7
gerundet ja 13 ergibt.
Nur kannst du diese Rundung nicht mehr nach der Division
machen. 127 durch 10 ergibt 12 (Keine Kommastellen!) Ergo
musst du die Rundung vor der Division machen. Das was nach
der Division als Kommastelle auftauchen würde, ist aber
vor der Division die Einerstelle, weil du ja durch 10
dividieren wirst. Insofern ist es diese 'Kommastelle'
die dir verrät ob, du das Ergebnis nun 12 oder 13 sein
soll.
Du betrachtest ganz einfach die Einerstelle und siehst
nach ob sie größer oder kleiner als 5 (die Hälfte von
10, durch die später dividiert wird) ist. Ist sie
größer, dann wird aufgerundet. Bei kleiner wird abgerundet.
Zurück zum konkreten Beispiel. Hier werden nicht 10 Ergebnisse
aufaddiert, sondern 256. Um den Mittelwert zu erhalten, wird
daher auch durch 256 dividiert. Das geht besonders einfach,
weil nämlich nicht dividiert werden muss, sondern das nieder-
wertigste Byte weggeworfen wird, und die beiden höherwertigen
Bytes um 1 Stelle nach rechts rücken.
Aber: Das ändert nichts am Runden. Wieder wird der Teil, der
nach der Division als Kommastelle auftauchen wird untersucht
(in völliger Analogie zu oben) und entschieden, ob auf oder
abgerundet werden soll.
>
>
1 | > ; Aufrunden
|
2 | > subi temp3, low(-1) ; addieren von 1
|
3 | > sbci temp4, high(-1) ; addieren des Carry
|
4 | >
|
> Was bedeutet hier das "low(-1)" bze. gigh(-1)? Wie iwrd aufgerundet?
Um wieder bei 127 zu bleiben.
Aufgerundet wird in diesem Fall, indem 10 addiert wird.
127 + 10 macht 137. Nach der Division durch 10 ergibt sich
13, das gerundete Ergebnis.
Im Code passiert auch nichts anderes. Nur wird hier 256 addiert.
Weil ja 256 Ergebnisse aufsummiert wurden und durch 256 dividiert
wird.
Der Schluessel im Code besteht jetzt darin, dass die Summe byteweise
in 3 Registern gebildet wird:
temp2 das niederwertigste Byte (welches nach der 'Division'
wegfällt. Es entspricht in gewisser Weise der 7 in den 127
temp3 das mittlere Byte
temp4 das höherwertigste Byte
Eine Addition von 256 entspricht daher der Addition
temp4 temp3 temp2
+ 00 01 00 (hex)
Zu temp2 braucht man aber keine 0 addieren, das ändert nichts
an temp2.
>
> [avrasm]
> ;in ASCII umwandeln
> outp:
> ldi temp5, -1 + '0'
> Was hat es mit der 10000 auf sich und warum wrid mal addiert und mal
> subtrahiert?
Weil festgestellt werden soll wieviele 10000 sich in der Zahl
verbergen.
Es geht darum eine Zahl, nehmen wir mal 837, in die
einzelnen Stellen zu zerlegen: 8, 3 und 7
um die erste Stelle zu erhalten, musst du feststellen wieviele
Hunderter in der Zahl enthalten sind. Das kann man mit einer
Division machen: 837 / 100 ergibt 8.
Nur leider sind Divisionen aufwändig. Es ist einfacher von der
Zahl in einer Schleife immer 100 abzuziehen und mitzuzählen
wie oft das ging, bevor die Zahl negativ wurde
Zahl Zähler
837 0 -> -100
737 1 -> -100
637 2 -> -100
537 3 -> -100
437 4 -> -100
337 5 -> -100
237 6 -> -100
137 7 -> -100
37 8 -> -100
-63 -> Zahl ist negativ, fertig
Also lautet die erste Stelle 8.
Um die nächste Stelle zu bestimmen, kann man jetzt wieder 100
addieren und das ganze Spielchen mit einer Subtraktion von
10 wiederholen.
Man kann aber auch anders vorgehen: Man belässt es bei der
negativen Zahl und addiert immer 10. Nur muss man dann allerdings
den Zähler von 9 herunterzählen anstatt von 0 beginnend hinaufzählen:
-63 9 -> +10
-53 8 -> +10
-43 7 -> +10
-33 6 -> +10
-23 5 -> +10
-13 4 -> +10
-3 3 -> +10
7 -> Zahl ist positiv, fertig
Die nächste Stelle lautet also 3
Die Einerstelle steht bleibt dann übrig.
Die Zerlegung von 837 in die einzelnen STellen lautet also
8, 3 und 7
Da eine 16 Bit Zahl aber nicht nur Zahlen bis 999 darstellen kann,
sondern bis hinauf zu 65536 geht, wird dasselbe Schema angewandt,
nur beginnt die Zerlegun mit der 10000-er Stelle.
> Ich denke ich frage hier im Interesse einiger,die das Toturial
> bearbeiten.
>
> Mfg Michael