Forum: Mikrocontroller und Digitale Elektronik dsPIC33Fj06GS202 - Floating Point Berechnung


von Matthias N. (matt90)


Lesenswert?

Hallo Zusammen,

ich müsste einen PID Regler in einen dsPIC33Fj06GS202 implementieren. 
Dieser läuft mit 8 MHz und die Regelung sollte mit ~70 KHz laufen. Das 
bedeutet das 100 Takte für die Berechnung zur Verfügung stehen in denen 
~10 Multiplikationen durchgeführt werden müssten. Dabei bin ich aber auf 
ein Problem gestoßen.. Ich habe Werte von 0.00001 bis 400 die in der 
Berechnung vorkommen. Floating Point scheidet natürlich aus, da der µC 
für eine einfache Multiplikation schon über 100 Takte braucht. Es wäre 
ja mathematisch Möglich ein Long Variable zu verwenden (also 
Rechenbereich um 10^5 verschieben).. Aber laut meinen Rechnungen ist 
auch das zu langsam dafür..


Meine Frage ist nun an euch als Profis gibt es eine performante 
Möglichkeit das zu lösen? Der µC hat ja einen 8x8 Hardwaremultiplier an 
Bord.


Danke schon mal im voraus und mit freundlichem Gruß

MaTT90

von holger (Gast)


Lesenswert?

>Meine Frage ist nun an euch als Profis gibt es eine performante
>Möglichkeit das zu lösen?

>Dieser läuft mit 8 MHz

Dreh den Prozessortakt hoch;) Der kann doch wesentlich mehr als 8MHz.

von Matthias N. (matt90)


Lesenswert?

Hallo,

danke für deine Antwort. Aber selbst wenn der Prozessortakt auf 16Mhz 
gesetzt würde wären "200 Takte" immer noch zu wenig! Zu Testzwecken wäre 
das eine Option, später soll er jedoch ohne externe Beschaltung 
auskommen.

Mfg

MaTT90

von Ingo (Gast)


Lesenswert?

70kHz Regeln is schon sportlich, auch für dsPIC. Welche 
Programmiersprache?

von holger (Gast)


Lesenswert?

>danke für deine Antwort. Aber selbst wenn der Prozessortakt auf 16Mhz
>gesetzt würde wären "200 Takte"

Sach mal raffst du das nicht? Das Teil hat ne eingebaute
PLL mit der du den internen Takt auf 100MHz-200MHz bringst.

>später soll er jedoch ohne externe Beschaltung
>auskommen.

Um dann möglichst ungenau zu arbeiten? Quarz dran und gut.

von ... (Gast)


Lesenswert?

Also der Mikrocontroller schafft 40 MIPS und kann eine 16 Bit 
Multiplikation mit Addition in einem Taktzyklus machen. Könnte 
funktionieren.

von Klaus (Gast)


Lesenswert?

Matthias N. schrieb:
> Dieser läuft mit 8 MHz

Irgendwie kann ich deine Werte nicht nachvollziehen. Schon auf der 
Übersichtsseite kann man finden:

> Internal oscillator and Phase-Locked Loop (PLL) with 120 MHz VCO

Aber möglicherweise solltest du was neueres nehmen, wie z.B. einen aus 
dieser Familie, über die ich gerade gestolpert bin: dsPIC33EPXXXGP50X / 
PIC24EPXXXGP/MC20X. Da bekommt man 140MHz (70 Mips) und bis zu 512k 
Flash und 48k RAM, da muß man nicht knausern. Vielleicht gibts sogar was 
Pinkompatibles.

MfG Klaus

von Ingo (Gast)


Lesenswert?

Mal eine. STM32F4 angeschaut, der lässt den dsPIC aber alt aussehen. 
Gut, is n 32 Bitter...

von Matthias N. (matt90)


Lesenswert?

Hallo,

danke für die ganzen Antworten. Ihr habt natürlich recht der Interne 
Takt müsste weitaus höher sein. Vllt. habe ich da schon einen Fehler in 
der Berechnung gemacht.

Das ist meine PLL Configuration evtl. ist da etwas falsch.
8 Mhz -> Nach PLLPRE 4 MHz -> Fvco=4Mhz*40=160MHz -> Fosc=80Mhz

1
#pragma config FNOSC = FRCPLL;   // Internal with PLL
2
CLKDIVbits.FRCDIV    = 0b000;    // Internal Fast RC Oscillator          
3
CLKDIVbits.PLLPOST   = 0b00;     // PLL VCO Output Divider Select 
4
CLKDIVbits.PLLPRE    = 0b00000;   // PLL Phase Detector Input Divider bits
5
PLLFBDbits.PLLDIV    = 0b0000101000;  // PLL Feedback Divisor bits

von Master S. (snowman)


Angehängte Dateien:

Lesenswert?

1. gehe davon aus, dass dein DSP mit 40MIPS läuft!
2. nimm einen timer, generier damit alle 0.5 sec einen interrupt, bei 
dem du eine LED ein/ausschaltest
3. miss die zeit
4. wenn die zeit nicht stimmt, dänn ändere die PLL-konfiguration!

lade dir das datenblatt runter, und führe es dir zu gemüte. darum kommst 
du nicht, ob du willst oder nicht.
http://www.microchip.com/wwwproducts/Devices.aspx?dDocName=en537161
schau dir das kapitel 8 an. bei Microchip hast du den grossen vorteil, 
dass wenn du ein register beschreiben willst, kanns du das einfach mit 
einem unterstrich + registernamen machen und musst dich nicht kümmern, 
wie du auf das sonst zugreifen müsstest resp. in welchem 
"gesamt"register das zu suchen ist. z.b. _FRCDIV = 0

edit: wie es scheint, hast du noch nicht viel (keine?) ahnung mit 
mikrokontrollern/DSP, und du machst das von deiner ausbildung wegen. 
dann lass dir doch einer mit mehr RAM, Flash und leistung (MIPS) als 
samples von Microchip zukommen (geht allerdings etwa 3-4 wochen, dafür 
gratis, dafür bekommst du gleich 3 stück). lieber zu viel von all dem 
als nachher merken, dass du doch wechseln musst: 
http://www.microchip.com/productselector/MCUProductSelector.html

von Master S. (snowman)


Lesenswert?


von Klaus (Gast)


Lesenswert?

Master Snowman schrieb:
> dann lass dir doch einer mit mehr RAM, Flash und leistung (MIPS) als
> samples von Microchip zukommen (geht allerdings etwa 3-4 wochen, dafür
> gratis, dafür bekommst du gleich 3 stück). lieber zu viel von all dem
> als nachher merken, dass du doch wechseln musst:

Selbst wenn man die gegen Geld von www.microchipdirect.com bestellt, muß 
man höchstens ein paar Wochen auf den "extra Käse" auf der Pizza 
verzichten (tut auch der Figur gut).

MfG Klaus

von Matthias N. (matt90)


Lesenswert?

Hallo,

danke Master Snowman (snowman)!

> wie es scheint, hast du noch nicht viel (keine?) ahnung mit
> mikrokontrollern/DSP, und du machst das von deiner ausbildung wegen.

Mit PICs habe ich noch garnichts gemacht bis jetzt!

> 1. gehe davon aus, dass dein DSP mit 40MIPS läuft!
> 2. nimm einen timer, generier damit alle 0.5 sec einen interrupt, bei
> dem du eine LED ein/ausschaltest
> 3. miss die zeit
> 4. wenn die zeit nicht stimmt, dänn ändere die PLL-konfiguration!

Der Controller läuft mit 40Mips die Frequenz von ~71KHz wird bereits 
über einen Timer ausgegeben den ich Berechnet habe.

> schau dir das kapitel 8 an. bei Microchip hast du den grossen vorteil,
> dass wenn du ein register beschreiben willst, kanns du das einfach mit
> einem unterstrich + registernamen machen und musst dich nicht kümmern,
> wie du auf das sonst zugreifen müsstest resp. in welchem
> "gesamt"register das zu suchen ist. z.b. _FRCDIV = 0

Das wusste ich auch noch nicht. Erspart mir auf jeden Fall Zeit! Danke.

> http://ww1.microchip.com/downloads/en/DeviceDoc/51459b.pdf

Wenn ich das jetzt richtig Verstehe.
40MIPs/70KHz => 571 Instructions(Cylces) => Wären dann ca. 5 
Multiplikationen?

Ein anderen µC ist vorerst nicht möglich da es ein Projekt ist und ich 
erst später eingestiegen bin...

von seennoob (Gast)


Lesenswert?

Hallo Matthias,

brauchst du wirklich Gleitkommawerte ?

Wenn du die ganze berechnung mit Fixpunktwerten machst kannst du einiges 
an Leistung und Genauigkeit heraus holen!

Float hat nur eine genauigkeit von so 7 oder 8 Stellen.
Bei Fixedpoint Variablen vom Typ long (32 bit ) hast du 10 Stellen.
Aber muss sich gdanken über die Skalierung machen usw.


Mfg

von Matthias N. (matt90)


Lesenswert?

Hallo,

ich habe heute Versucht Fixed Point zu verwenden, jedoch ist die 
Dokumentation darüber für mich nicht ganz verständlich.

Gibt es eine andere Bibliothek also die <libq.h>? Weil wenn ich das 
Richtig verstehe habe ich da mit _Q16 nur eine Aufteilung von 16 Bit 
"Integer" und 16 Bit "Fraktion"?
Weiterhin würde ich gerne Wissen wie es mit der Performance von Fixed 
Point aussieht? Gibt es da auch eine so schöne Tabelle wo ich so etwas 
rauslesen kann?

Danke und mit freundlichem Gruß

MaTT90

von Master S. (snowman)


Lesenswert?

a = b*c + d;  // wobei alles fixed point sind
macht der dsPIC in einem taktzyklus, dafür brauchst du keine tabelle ;-)
ps: fixed point sind normale integer (ganzzahlen) also nix 
"komma-zahlen"

von Matthias N. (matt90)


Lesenswert?

Hallo,
+ und - gehen ganz normal ok! Aber bei mal und geteilt brauche ich dann 
ja eine Routine.

Wenn ich das also richtig Verstanden habe dann geht das also so?
Als Zahlenformat nehme ich uint32_t

Dann wähle ich in 10.22 Fixed Point Format. Dann funktionieren Folgende 
Operationen so?? Also sehe ich das Richtig? Und wenn ja ist da nicht die 
Umwanldung von anderen Formaten wieder aufwendig???

Addition:
1
y=a+b;

Subtraktion:
1
y=a-b;

Multiplikation:
1
y=(a*b)>>20;

Danke MFG

MaTT90

von Olli (Gast)


Lesenswert?

Ich bin mir nicht ganz sicher, aber musst du nich um 22 Stellen shiften?

von Matthias N. (matt90)


Lesenswert?

OH ja 22 meinte ich..

von Matthias N. (matt90)


Lesenswert?

Also ich komm iwie nicht zurecht..


Wenn ich es so mache fehlen mir die oberen Werte und es dauer 30 cycles
1
uint32_t fixedmul (uint32_t a, uint32_t b){
2
    return (a * b >>22);
3
}


Wenn ich dann Einen Wert eben 64bit gebe um überlauf zu verhindern 
dauert die Berechnung wieder über 100 cycles
1
uint32_t fixedmul (uint64_t a, uint32_t b){
2
    return (a * b >>22);
3
}

von Michael H. (morph1)


Lesenswert?

Hast du dir das fractal-format angesehen? ich weiß nicht obs für dich 
passt, ist aber sehr bequem.

geht von -1 bis +1 (im prinzip 16bit integer), dafür erzeugen aber 
multiplikative rechenoperationen keinen überlauf. und der PIC kann das 
innerhalb weniger taktzyklen im DSP-mode.

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.