Forum: Mikrocontroller und Digitale Elektronik Mathebibliothek für STM8S


von Max M. (maxmicr)


Lesenswert?

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

von S. R. (svenska)


Lesenswert?

Ich vermute mal, dass SDCC passende Routinen enthält, aber ziemlich 
sicher nur mit einfacher Genauigkeit.

von pegel (Gast)


Lesenswert?

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);

von Max M. (maxmicr)


Lesenswert?

Danke für eure Hilfe,

kann man die Bibliothek vom SDCC mit dem IAR-Compiler auch benutzen?

: Bearbeitet durch User
von S. R. (svenska)


Lesenswert?

Warum nimmst du nicht einfach die Bibliothek vom IAR, wenn du den 
sowieso schon nutzt?

von Max M. (maxmicr)


Lesenswert?

Ich wusste nicht, dass es eine IAR C-Bibliothek gibt? Wo finde ich die?

von S. R. (svenska)


Lesenswert?

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.

von (º°)·´¯`·.¸¸.·´¯`·.¸¸.·´¯`·.¸¸.·´¯`·.¸¸.·´¯`·.¸¸.· (Gast)


Lesenswert?

> 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

von Sebastian K. (sek)


Lesenswert?

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.

von Ralph S. (jjflash)


Lesenswert?

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

von A. B. (Gast)


Lesenswert?

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.

von Ralph S. (jjflash)


Lesenswert?

... 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
Noch kein Account? Hier anmelden.