Forum: Mikrocontroller und Digitale Elektronik STM32F4 Float Problem


von Li W. (kwilly_d)


Lesenswert?

Hallo!

auf dem STM32F4 Discovery Board messe ich Encodersignale vom Motor. Für 
meine Anwendung ist die Encodersignale bisschen verrauscht so dass 
wollte ich diese mit einem Tiefpassfilter glättern.

Da habe ich unerwartetes Problem.
1
 
2
float sampleT = 0.01f;
3
4
MotorAngle1 = ((float)EncoderCounter1)*6.2831f/1920.f; // [rad]
5
MotorAngle2 = ((float)EncoderCounter2)*6.2831f/1920.f; // [rad]
6
    
7
angleW1 = (((float)(EncoderCounter1 -oldEncoderCounter1))*6.2831f/1920.f)/sampleT; // [rad/s]
8
angleW2 = (((float)(EncoderCounter2 - oldEncoderCounter2))*6.2831f/1920.f)/sampleT; // [rad/s]
9
    
10
    /* Reset Encoder Counter */
11
    
12
oldEncoderCounter1 = EncoderCounter1;
13
oldEncoderCounter2 = EncoderCounter2;


bis hier funktioniert alles gut.
jetzt sollte mein gebastelte Tiefpassfilter angleW1 und angleW2 filtern
1
    /* Tiefpass Filter */
2
float TmW = 0.03f;
3
_angleW1 = (angleW1 - old_angleW1)*(sampleT/TmW) + old_angleW1;
4
_angleW2 = (angleW2 - old_angleW2)*(sampleT/TmW) + old_angleW2;
5
6
old_angleW1 = _angleW1;
7
old_angleW2 = _angleW2;

Das Code ist auf dem AVR ohne Problem funktioniert.
über USART messe ich gefiltertes _angleW1 und _angleW2 seltsamerweise so
1
_angleW1 = 2147483647.2147483647; 
2
_angleW2 =  2147483647.2147483647;
sieht nach 2^31 -1 komma 2^31 -1 aus.

Wie kann ich dieses Verhalten umgehen?

Grüße Wang!

von Dirk H. (dirk_h)


Lesenswert?

Hi,

hast du die float.h inkludiert und dem Linker gesagt wo er die richtige 
math lib findet? Welche math lib verwendet werden muss ist abhängig 
davon ob du die FPU nutzt!

Nutzt du sie? Wenn ja muss das zumindest bei CooCox (meine IDE) auch 
eingestellt werden.

Grüße
Dirk H.

: Bearbeitet durch User
von Li W. (kwilly_d)


Lesenswert?

Dirk H. schrieb:
> Hi,
>
> hast du die float.h inkludiert und dem Linker gesagt wo er die richtige
> math lib findet? Welche math lib verwendet werden muss ist abhängig
> davon ob du die FPU nutzt!
>
> Nutzt du sie? Wenn ja muss das zumindest bei CooCox (meine IDE) auch
> eingestellt werden.
>
> Grüße
> Dirk H.

ist das wirklich nötig? float.h ist schon inkludiert. wie tut man den 
linker merken? im makefile nötige flags reintun?

von Dirk H. (dirk_h)


Lesenswert?

Hallo Wang,
ich kenn mich leider mit Makefiles nicht so aus.. das lass ich meine IDE 
machen ;). Aber soweit ich weiss wird das im makefile mitgeteilt - ja.

Also der relevante Teil meines "Linker Control Strings" (so heißt das in 
CooCox, hoffe es hilft dir) ist
-L..\..\..\gcc\arm-none-eabi\lib\armv7e-m\fpu\;

WEnn du keine FPU verwendest gibt es im armv7e-m Ordner dazu auch den 
passenden Unterordner "softfp".

In meinem compiler control string habe ich diese Flags drin
-mfpu=fpv4-sp-d16; -mfloat-abi=hard;

Wenn du die weg lässt nimmt er GLAUBE ich die FPU nicht (softfp).

Wie gesagt mit den obigen Einstellungen funktioniert es bei mir. bevor 
ich die math lib nicht verlinkt hatte, hatte ich genau das selbe Problem 
das beim Float rechnen müll raus kam. -> Insofern scheint das wohl nötig 
zu sein ;)

Grüße
Dirk H.

von Dr. Sommer (Gast)


Lesenswert?

Zeige mal einen vollständigen Code, damit man das nachvollziehen kann. 
Ich habe zwar keine Ahnung von Filtern, aber dafür vom GCC und vom 
STM32F4. Schreibe mal bei jedem Rechen-Schritt dran was du erwartest und 
was bei dir rauskommt.
Mit solchen kleinen Codestückchen kann dir keiner helfen!

Dirk H. schrieb:
> In meinem compiler control string habe ich diese Flags drin
> -mfpu=fpv4-sp-d16; -mfloat-abi=hard;
>
> Wenn du die weg lässt nimmt er GLAUBE ich die FPU nicht (softfp).
Ja, stimmt genau.

Dirk H. schrieb:
> Also der relevante Teil meines "Linker Control Strings" (so heißt das in
> CooCox, hoffe es hilft dir) ist
Das braucht man eigentlich gar nicht anzugeben, das findet der Compiler 
selber heraus. Man braucht nur "-mthumb -mcpu=cortex-m4 
-mfpu=fpv4-sp-d16; -mfloat-abi=hard" beim Compilen & Linken.

von Thomas K. (rlyeh_drifter) Benutzerseite


Lesenswert?

Ist die FPU aktiviert?

wird meist in system_stm32f4xx.c gemacht:
1
  /* FPU settings ------------------------------------------------------------*/
2
  #if (__FPU_PRESENT == 1) && (__FPU_USED == 1)
3
    SCB->CPACR |= ((3UL << 10*2)|(3UL << 11*2));  /* set CP10 and CP11 Full Access */
4
  #endif

Für den Filter kannst dir auch arm_fir_f32(...) anschauen.

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.