Guten Abend, ich suche nach einer Mathe-Bibliothek (mit Cos/Sin/e) für den STM8S(003F3), kann ich da jede beliebige C-Bibliothek nehmen? Welche würdet ihr empfehlen? Grüße
Ich vermute mal, dass SDCC passende Routinen enthält, aber ziemlich sicher nur mit einfacher Genauigkeit.
sdcc/include/math.h bietet:
1 | /* Trigonometric functions */
|
2 | float sinf(float x) _FLOAT_FUNC_REENTRANT; |
3 | float cosf(float x) _FLOAT_FUNC_REENTRANT; |
4 | float tanf(float x) _FLOAT_FUNC_REENTRANT; |
5 | float cotf(float x) _FLOAT_FUNC_REENTRANT; |
6 | float asinf(float x) _FLOAT_FUNC_REENTRANT; |
7 | float acosf(float x) _FLOAT_FUNC_REENTRANT; |
8 | float atanf(float x) _FLOAT_FUNC_REENTRANT; |
9 | float atan2f(float x, float y); |
10 | |
11 | /* Hyperbolic functions */
|
12 | float sinhf(float x) _FLOAT_FUNC_REENTRANT; |
13 | float coshf(float x) _FLOAT_FUNC_REENTRANT; |
14 | float tanhf(float x) _FLOAT_FUNC_REENTRANT; |
15 | |
16 | /* Exponential, logarithmic and power functions */
|
17 | float expf(float x) _FLOAT_FUNC_REENTRANT; |
18 | float logf(float x) _FLOAT_FUNC_REENTRANT; |
19 | float log10f(float x) _FLOAT_FUNC_REENTRANT; |
20 | float powf(float x, float y); |
21 | float sqrtf(float a) _FLOAT_FUNC_REENTRANT; |
22 | |
23 | /* Nearest integer, absolute value, and remainder functions */
|
24 | float fabsf(float x) _FLOAT_FUNC_REENTRANT; |
25 | float frexpf(float x, int *pw2); |
26 | float ldexpf(float x, int pw2); |
27 | float ceilf(float x) _FLOAT_FUNC_REENTRANT; |
28 | float floorf(float x) _FLOAT_FUNC_REENTRANT; |
29 | float modff(float x, float * y); |
Danke für eure Hilfe, kann man die Bibliothek vom SDCC mit dem IAR-Compiler auch benutzen?
:
Bearbeitet durch User
Warum nimmst du nicht einfach die Bibliothek vom IAR, wenn du den sowieso schon nutzt?
Ich wusste nicht, dass es eine IAR C-Bibliothek gibt? Wo finde ich die?
Wenn du einen C-Compiler hast, dann hast du auch eine C-Standardbibliothek. Ohne die funktionieren nämlich viele Funktionen, die der C-Standard vorschreibt, nicht.
> Wo finde ich die?
stm8/lib
Eigentlich sollte hier mal was stehen.
Aber wer zu faul ist, die Doku* mal selber zu lesen...
Dem schreib ich das hier nicht nochmal ab.
*) doc/EWstm8_DevelopmentGuide.pdf
Durch Verwendung der IAR eigenen Bibliothek hast du über die Linker Options zudem den Vorteil zwischen diversen Implementierungsvarianten (auf Größe optimiert, auf Speed optimiert...) der Funktionen wählen zu können.
... wenn du die math - library nicht einbinden magst, vielleicht hilft dir das ?!? Sinus / Cosinus über Taylorreihenentwicklung. Ich hatte es hier vor geraumer Zeit auch davon (allerdings primär für einen STM32F030). Ein Forumsmitglied hatte hier eine geniale Festkommabibliothek gepostet (nicht von ihm), die ich allerdings noch nicht auf einen STM8 portiert habe (gibt Schwierigkeiten bzgl. int32 Variablen). Die folgenden Funktionen funktionieren auf STM8 und MCS51:
1 | /* --------------------------------------------------------
|
2 | wenn stdarg.h NICHT eingebunden ist, dann ist die
|
3 | Auskommentierung fuer abs aufzuheben !
|
4 | -------------------------------------------------------- */
|
5 | /*
|
6 | float abs(float value)
|
7 | {
|
8 | if (value< 0.0f) return (value * -(1.0f));
|
9 | else return value;
|
10 | }
|
11 | */
|
12 | |
13 | #define MY_PI 3.14159265359f
|
14 | |
15 | /* --------------------------------------------------------
|
16 | tiny_pow
|
17 | |
18 | bestimmt den Wert fuer value hoch n ( value ^ n)
|
19 | Der Exponent n muss (leider) eine Ganzzahl (integer)
|
20 | sein
|
21 | -------------------------------------------------------- */
|
22 | float tiny_pow(int n, float value) |
23 | {
|
24 | float tmp; |
25 | int i; |
26 | |
27 | tmp= value; |
28 | for (i= 0; i < n-1; i++) |
29 | {
|
30 | tmp= tmp*value; |
31 | }
|
32 | return tmp; |
33 | }
|
34 | |
35 | /* --------------------------------------------------------
|
36 | tiny_sin
|
37 | |
38 | bestimmt den Sinus von value im Bogenmass. Die Be-
|
39 | rechnung erfolgt mittels Taylorreihe
|
40 | Eine Umrechnung in Grad kann mittels:
|
41 | sin(wert * (MY_PI / 180.0f) erfolgen
|
42 | -------------------------------------------------------- */
|
43 | float tiny_sin(float value) |
44 | {
|
45 | float degree; |
46 | float p3; |
47 | float p5; |
48 | float p7; |
49 | float sinx; |
50 | |
51 | int mflag= 0; |
52 | |
53 | while (value > (2*MY_PI)) value -= (2*MY_PI); |
54 | if (value > MY_PI) |
55 | {
|
56 | mflag= - 1; |
57 | value -= MY_PI; |
58 | }
|
59 | |
60 | if (value > (MY_PI /2)) value = MY_PI - value; |
61 | |
62 | degree= value; |
63 | |
64 | p3 = tiny_pow(3, degree); |
65 | p5 = tiny_pow(5, degree); |
66 | p7 = tiny_pow(7, degree); |
67 | |
68 | // Taylor-Reihenentwicklung
|
69 | // 6 = fak(3); 120 = fak(5); 5040= fak(7)
|
70 | sinx= (degree - (p3/6.0f) + (p5/120.0f) - (p7/5040.0f)); |
71 | |
72 | if (mflag) sinx = sinx * (-1); |
73 | |
74 | return sinx; |
75 | }
|
76 | |
77 | /* --------------------------------------------------------
|
78 | tiny_cos
|
79 | |
80 | Bestimmt den Cosinus von Value im Bogenmass
|
81 | -------------------------------------------------------- */
|
82 | float tiny_cos(float value) |
83 | {
|
84 | return tiny_sin(value - (MY_PI / 2.0f)) * -1.0f; |
85 | }
|
Na, das mit dem "tiny_pow" ist aber so ziemlich die ärgste Resoucenverschwendung, Stichwort Horner-Schema. Spart VIELE Multiplikationen gegenüber der Trivial-Variante bei der Polynomauswertung: a_n*x^n+a_{n-1}*x^{n-1}+...+a_1*x+a_0 =(...(a_n*x+a_{n-1})*x+a_{n-2})*x+a_{n-3})...)*x+a_0 Da wird also nur fortwährend mit x multipliziert und der nächstniedrigere Koeffizient dazu addiert. Wenn man weiß, dass nur ungerade (oder nur gerade) Potenzen auftauchen, modifiert man das natürlich, dass man laufend mit x^2 multipliziert. Die Zahl der Multiplikationen ist bei der Trivial-Variante von der Größenordnung n^2, beim Horner-Schema nur n. Außerdem: Taylor-Entwicklung ist nicht so das Gelbe vom Ei, wenn man ein relativ großes Intervall betrachtet. In der Nähe des Entwicklungspunktes (hier: 0) zwar nicht schlecht, aber die Qualität sinkt mit zunehmendem Abstand rapide ... Und [0,pi] ist schon ziemlich groß. (Übrigens ist das oben nicht "mit Taylor-Reihe", sondern "mit Taylor-Polynom".) Besser: Entwicklung nach Legendre- oder Tschebyschow-Polynomen, damit erzielt man eine halbwegs gleichmäßige Approximationsgüte auch bei einem längeren Intervall. Und es kommt trotzdem wieder ein Polynom (auch ungerade bzw. beim Kosinus gerade) heraus, der Rechenaufwand ist also derselbe. Die Implementierung oben liefert übrigens bei negativen Winkeln ... ?! Und wenn schon Taylor, sollte man ein möglichst kleines Intervall nehmen, es böte sich also an, auch noch die Symmetrie von [0,pi/2] zu [pi/2,pi] zu nutzen.
... absolut alles richtig was du sagst. Allerdings hatten diese Funktionen schlicht funktioniert und es war noch ausreichend Platz. Grundsätzlich war das etwas schnelles und bei anderen Controllern hatte ich die math hinzugelinkt. Dann, wenn der Platz gering wird, verwende ich die Festkomma-Software die hier ein Forumsmitglied gepostet hat. Bei der Taylorreihenentwicklung sieht man allerdings auch sehr schön, wie das aufgebaut ist... und (ich weiß das ist nicht wirklich ein Argument) die Quelldateien bleiben schön klein und übersichtlich ! (Allerdings - wie du absolut richtig angemerkt hast: ungenau und resourcenverschwendend)
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.