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