Download:
|

libsm16: Stack- und Integerarithmetik-Library
für ATmega Controller
Version 0.20 (c) 2006 Jörg Wolfram (joerg@jcwolfram.de)
1 Allgemeines
Die Library unterliegt der LGPL (GNU Lesser General Public Licence)
Version 2 oder höher, jede Nutzung der Software/Informationen nonkonform
zur GPL oder ausserhalb des Geltungsbereiches der LGPL ist untersagt!
Die Veröffentlichung dieses Programms erfolgt in der Hoffnung, daß
es Ihnen von Nutzen sein wird, aber OHNE IRGENDEINE GARANTIE, auch
ohne die implizite Garantie der MARKTREIFE oder der VERWENDBARKEIT
FÜR EINEN BESTIMMTEN ZWECK.
2 Definitionen und Ressourcen
Um mit der Library zu arbeiten, muss die maximale Stackadresse (root)
libsm16_ros und die minimale Stackadresse festgelegt werden. Zusätzlich
werden noch 8 Bytes im RAM zum Sichern von Registern benötigt, die
Adresse dafür ist libsm16_vram. Und, letztendlich werden noch 8 Bytes
Prozessorstack (incl. Aufruf) benötigt.
Fast alle Funktionsaufrufe sind mit bedingter Assemblierung geklammert.
Das dient dazu, daß das Tool avr_autolib.pl nur die benötigten
Routinen freigibt.
3 Registernutzung
bis auf die unten aufgelisteten Ausnahmen sichern die Library-Funktionen
benötigte Register entweder auf dem Stack oder im Speicherbereich
libsm16_vram. Wichtig ist, dass der Stackpointer (also das
Y-Register) zu Beginn initialisiert wird (Funktionsaufruf) und nicht
von anderen Programmteilen geändert werden darf, solange er als Stackpointer
für die Library-Funktionen benutzt wird. Das X-Register liefert immer
den obersten Stackeintrag zurück (außer bei libsm16_init, in diesem
Fall wird 0x0000 zurückgeliefert).
Die Library nutzt folgende Register:
|
Register |
Funktion |
|
r0,r1 |
werden für Multiplikationen und temporär genutzt |
|
byte0 |
beliebiges Register, welches mit 0x00 vorbelegt ist |
|
byte1 |
beliebiges Register, welches mit 0x01 vorbelegt ist |
|
XL,XH |
Ein-/Ausgabe von Daten, temporär genutzt |
|
YL,YH |
Stackpointer |
|
ereg |
beliebiges Register aus dem oberen Registerbereich, liefert Fehlercode |
|
|
4 Fehlercodes
Nach jedem Funktionsaufruf wird in ereg-Register ein Wert zurückgegeben,
der zeigt ob ein Fehler aufgetreten ist. War alles in Ordnung, so
ist der Rückgabe-wert 0. Ansonsten ist einer der folgenden Fehler
aufgetreten:
|
ereg |
Fehler |
|
1 |
Überlauf, der gültige Zahlenbereich (+- 32768) wurde über- oder unterschritten |
|
2 |
Division durch Null |
|
3 |
Es wurde versucht, aus einer negativen Zahl die Quadratwurzel zu ziehen |
|
4 |
Stackunterlauf, für diese Operation befinden sich nicht genügend Werte
auf dem Stack |
|
5 |
Stacküberlauf, es befinden sich zu viele Werte auf dem Stack |
|
|
5 Funktionsreferenz
Die Funtionsreferenz gibt eine Übersicht über die einzelnen Funktionen. Die angegebenen Taktzahlen
sind Maximalwerte und durch manuelles Auszählen aus dem Quelltext entstanden. Sie beziehen sich auf
ungesetztes libsm16_storesp, Dabei darf der Wert des Y-Registers zwischen zwei
Funktionsaufrufen nicht verändert werden. Setzt man den Wert libsm16_storesp, so wird
das Y-Register vor jeder Operation aus dem SRAM geladen und danach wieder zurückgespeichert. Dafür
werden aber 8 zusätzliche Takte (ausser bei libsm16_init 4) benötigt.
5.1 Stackfunktionen
Die Funktion libsm16_init muss aufgerufen worden sein, bevor eine andere Funktion
aufgerufen werden kann, sie dient auch zur Neuinitialisierung des Stacks.
|
Funktion |
Takte |
Stack |
Stack nach Ausführung |
Beschreibung |
|
libsm16_init |
12 |
undefiniert |
leerer Stack |
Initialisierung des Stacks |
|
libsm16_push |
24 |
[...] |
[...][X] |
legt den Inhalt von X auf dem Stack ab |
|
libsm16_pop |
29 |
[...][a] |
[...]X=a |
holt X vom Stack |
|
libsm16_dup |
40 |
[....][a] |
[...][a][a] |
dupliziert den obersten Stackeintrag |
|
libsm16_2dup |
44 |
[...][a][b] |
[...][a][b][a][b] |
dupliziert die beiden obersten Stackeinträge |
|
libsm16_swap |
37 |
[...][a][b] |
[...][b][a] |
vertauscht die beiden obersten Stackeinträge |
|
libsm16_nip |
29 |
[...][a][b] |
[...][b] |
löscht den zweitobersten Stackeintrag |
|
libsm16_over |
40 |
[...][a][b] |
[...][a][b][a] |
kopiert den zweitobersten Stackeintrag |
|
|
5.2 Arithmetikfunktionen
Bei den unten aufgeführten Arithmetikfunktionen fallen zwei etwas
aus der Reihe: libsm16_dmul und libsm16_mdiv.
Hier handelt es sich um Funktionen, bei denen intern mit 24 Bit gerechnet
wird. Das ist vor allen Dingen bei Meßwertskalierungen sinnvoll, um
zum Beispiel einen Wertebereich von 0-650 auf 0-1023 zu normalisieren.
In diesem Falle muß nur der Meßwert mit gerundeten 403 ($1024*256/650$)
multipliziert werden. Und da die ATmega-Serie einen Hardwaremultiplizierer
mit an Bord haben, geht das auch recht schnell vonstatten.
|
Funktion |
Takte |
Stack |
Stack nach Ausführung |
Beschreibung |
|
libsm16_abs |
49 |
[...][a] |
[...][|a|] |
Absolutbetrag |
|
libsm16_inv |
47 |
[...][a] |
[...][-a] |
Vorzeichenwechsel |
|
libsm16_sign |
54 |
[...][a] |
[...][-1,0,+1] |
Vorzeichen |
|
libsm16_add |
67 |
[...][a][b] |
[...][a+b] |
Addition |
|
libsm16_sub |
77 |
[...][a][b] |
[...][a-b] |
Subtraktion |
|
libsm16_mul |
137 |
[...][a][b] |
[...][a{*b] |
Multiplikation |
|
libsm16_dmul |
148 |
[...][a][b] |
[...][a{*b/256] |
erweiterte Multiplikation |
|
libsm16_div |
396 |
[...][a][b] |
[...][a/b] |
Division |
|
libsm16_mod |
398 |
[...][a][b] |
[...][a%b] |
Modulo (Rest) |
|
libsm16_mdiv |
624 |
[...][a][b] |
[...][a+b] |
erweiterte Division |
|
libsm16_sqrt |
1517 |
[...][a] |
[...][sqrt(a)] |
Quadratwurzel |
|
|
5.3 Vergleichsfunktionen
Die Vergleichsfunktionen ergeben 0 oder 1, entsprechend für "falsch"
und "wahr".
|
Funktion |
Takte |
Stack |
Stack nach Ausführung |
Beschreibung |
|
libsm16_eq |
57 |
[...][a][b] |
[...][1, wenn a=b] |
Test auf Gleichheit |
|
libsm16_ne |
57 |
[...][a][b] |
[...][1, wenn a<>b] |
Test auf Ungleichheit |
|
libsm16_gt |
57 |
[...][a][b] |
[...][1, wenn a>b] |
Test auf "Größer als" |
|
libsm16_lt |
57 |
[...][a][b] |
[...][1, wenn a<b] |
Test auf "Kleiner als" |
|
libsm16_not1 |
39 |
[...][a] |
[...][1-a] |
gilt nur für 0 und 1 |
|
|
5.4 Logikfunktionen
Die Logikfunktionen wirken auf alle 16 Bit, dadurch können u.U.
Vorzeichenwechsel auftreten, falls das Ergebnis in arithmetischen
Funktionen weiterverarbeitet wird.
|
Funktion |
Takte |
Stack |
Stack nach Ausführung |
Beschreibung |
|
libsm16_not |
38 |
[...][a] |
[...][65535-a] |
invertiert alle Bits |
|
libsm16_and |
51 |
[...][a][b] |
[...][a and b] |
logisches AND |
|
libsm16_or |
51 |
[...][a][b] |
[...][a or b] |
logisches OR |
|
libsm16_xor |
51 |
[...][a][b] |
[...][a xor b] |
logisches XOR |
|
|
5.5 Regelungstechnische Funktionen
Die Regelungsfuktionen sind im Laufe der Zeit dazugekommen und dienen hauptsächlich zur
Realisierung von Regelungsalgorithmen. Die Funktionen libsm16_mean(n) sind Tiefpässe
(Mittelwertbildner) mit verschiedenen Wichtungen. Je größer der Wert n ist, um so
langsamer folgt das Resultat dem Eingangswert. Mit der Limit-Funktion libsm16_limit
lässt sich das Ergebnis auf einen Wert begrenzen, während die Unterdrückungsfunktion
libsm16_surp Werte unterhalb einer Grenze als Null zurückgibt. Die beiden psc-Funktionen
wandeln den obersten Stackwert derart um, dass im LOW-Byte der auf 255 skalierte oder begrenzte
Absolutwert und in den beiden niederwertigesten Bits des HIGH-Bytes die Steuerbits für
positives und negatives Vorzeichen stehen.
|
Funktion |
Takte |
Stack |
Stack nach Ausführung |
Beschreibung |
|
libsm16_mean2 |
57 |
[...][a][b] |
[...][(a+b)/2] |
Tiefpass mit der Wichtung 1:1 |
|
libsm16_mean4 |
99 |
[...][a][b] |
[...][(3*a+b)/4] |
Tiefpass mit der Wichtung 1:3 |
|
libsm16_mean8 |
112 |
[...][a][b] |
[...][(7*a+b)/8] |
Tiefpass mit der Wichtung 1:7 |
|
libsm16_mean16 |
125 |
[...][a][b] |
[...][(15*a+b)/16] |
Tiefpass mit der Wichtung 1:15 |
|
libsm16_mean32 |
138 |
[...][a][b] |
[...][(31*a+b)/32] |
Tiefpass mit der Wichtung 1:31 |
|
libsm16_limit |
97 |
[...][a][b] |
[...][a im Bereich 0...b] |
Begrenzung des Wertebereiches auf |b| |
|
libsm16_surp |
99 |
[...][a][b] |
[...][a=0 if |a|<|b|] |
Unterdrückung von Werten <|b| |
|
libsm16_psc |
60 |
[...][a] |
[...][l=betrag, h=0,1,2] |
Aufbereitung für PWM, Skalierung auf 255 |
|
libsm16_psc8 |
60 |
[...][a] |
[...][l=betrag, h=0,1,2] |
Aufbereitung für PWM, Begrenzung auf 255 |
|
|
erzeugt mit latex2web.pl v0.4 © 2006 Joerg Wolfram
|