Forum: Mikrocontroller und Digitale Elektronik dsPIC zu langsam?


von Ge E. (re_n)


Lesenswert?

Folgendes: Ich benutze einen dsPIC33EP256MC202 dieser hat bekanntlich 70 
MIPS und Taktet intern mit 140MHz. Ich habe ein Programm geschrieben in 
dem es Notwendig ist das der Timer Interrupt 20 Mio. mal pro Sek. 
aufgerufen wird. Dachte mir das sollte der mit 70MIPS locker schaffen, 
leider falsch gedacht. Über 5Mio./s kommt der leider nicht. Am Clock 
Ausgang des PICs messe ich ca 66MHz, die PLL läuft also. Ich kann mir 
atm beim besten Willen nicht erklähren warum er so langsam arbeitet. Zum 
Test habe ich mal einen Port ein/aus Schalten lassen in einer Schleife.. 
Selbes Ergebniss. Das Oszi sagt 2,5MHz (sprich 5 Mio. Umschaltungen/s) 
Übersehe ich irgend etwas? Unter der Angabe "MIPS" verstehe ich 
"Millionen Rechenoperationen pro Sek." aber davon ist er anscheinen 
Meilenweit entfernt.

von holger (Gast)


Lesenswert?

>Taktet intern mit 140MHz. Ich habe ein Programm geschrieben in
>dem es Notwendig ist das der Timer Interrupt 20 Mio. mal pro Sek.
>aufgerufen wird.

Interrupt innerhalb 7 Taktzyklen abarbeiten?
Du solltest besser Pizzabäcker werden.

von Max H. (hartl192)


Lesenswert?

> Unter der Angabe "MIPS"
> verstehe ich "Millionen Rechenoperationen pro Sek."
MIPS = Mega Instructions Per Second
70 MIPS bedeutet also dass der µC 70 Millionen ASM-Befehle (abgesehen 
von denen die zwei Maschinenzyklen lang sind) pro Sekunde ausführen 
kann.

Bei 20 Mio. Interrupts pro Sekunde hast du nur 3.5 Befehlszyklen pro 
Interrupt, und alleine die Kontextsicherung und das retfie Brauch schon 
4 davon.

Re Né schrieb:
> Zum
> Test habe ich mal einen Port ein/aus Schalten lassen in einer Schleife..
Wie sah die schleife aus?
Vllt. so?
1
loop:
2
btg LATC,#4
3
bra loop
oder doch ein paar Befehle mehr?

: Bearbeitet durch User
von Ste N. (steno)


Lesenswert?

Re Né schrieb:
> Ich habe ein Programm geschrieben in
> dem es Notwendig ist das der Timer Interrupt 20 Mio. mal pro Sek.
> aufgerufen wird.

Wie willst Du das denn mit 70 Mio. Instruktionen pro Sek. schaffen? 
Rechne doch mal selbst, dir bleiben pro Interrupt 3,5 Zyklen. Was soll 
denn in dem Int. passieren? Selbst mit einem 200MHz Prozessor ist das 
praktisch nicht möglich, wenn Du nebenher noch was anderes machen 
willst...

von Ge E. (re_n)


Lesenswert?

@Holger: Klar das der Interrupt nicht nach einem Zyklus da ist. Es 
ergibt trotzdem keinen Sinn. Mittels folgendem simplen Code lasse ich 
einen Port Pin umschalten.

###########################
Main:
call switch
goto Main

switch:
btss LATB,#6
goto seton

btsc LATB,#6
goto setoff

seton:
bset LATB,#6
return

setoff:
bclr LATB,#6
return
##############################

Wie kann es sein das der PIC den Port Pin nur 5Mio/Sek umschaltet??

von Max H. (hartl192)


Lesenswert?

Re Né schrieb:
> Wie kann es sein das der PIC den Port Pin nur 5Mio/Sek umschaltet??

Main:
call switch    2 Zyklen

switch:
btss LATB,#6   1 Zyklen
goto seton     2 Zyklen

seton:
bset LATB,#6   1 Zyklus
return         2 Zyklen


goto Main      2 Zyklen

von Ge E. (re_n)


Lesenswert?

ok dank euch. Das klingt schon einleuchtend. Da habe ich mich wohl etwas 
vertahn. Habe mir bisher nie gedanken über die Geschwindigkeit machen 
müssen da diese bisher nicht so kritisch war. Damit kann ich die Idee 
wieder an den Nagel hängen ^^

von holger (Gast)


Lesenswert?

>Wie kann es sein das der PIC den Port Pin nur 5Mio/Sek umschaltet??

Glaubst du das deine gotos und calls dich gar nichts kosten?
Lies das verdammte Datenblatt und zähl die Zyklen für
die Befehle zusammen. Oder kannst du das auch nicht?

von Ste N. (steno)


Lesenswert?

Re Né schrieb:
> Wie kann es sein das der PIC den Port Pin nur 5Mio/Sek umschaltet??

Ist doch Super, der Pic benötigt für die Schleife nur 14 Taktzyklen. 
Dabei muß er 2 mal ein Bit testen und mehrmals springen. Versuch doch 
mal der Vorschlag von Max.

von Max H. (hartl192)


Lesenswert?

Durchschnittlich noch schneller würde es mit
1
loop:
2
repeat #16383
3
btg LATB,#6
4
bra loop
gehen

: Bearbeitet durch User
von Ge E. (re_n)


Lesenswert?

Max H. schrieb:
> Durchschnittlich noch schneller würde es mit
>
1
> loop:
2
> repeat #16383
3
> btg LATC,#4
4
> bra loop
5
>
> gehen

Stimmt da hast du natürlich Recht ;) Auf die Idee hätte ich auch kommen 
müssen ^^ Aber die Idee nen Sinus (bestehend aus 16 Punkten) zwischen 
20kHz-130kHz mittels PWM zu Modulieren hat sich damit erledigt.

von Dario B. (Gast)


Lesenswert?

und denk drann: bei den pics dauert ein maschinenzyklus ganze vier 
takte, d.h. du kannst die requenz, mit der die cpu taktet, erst mal 
durch vier dividieren.....

von Max H. (hartl192)


Lesenswert?

Wieso? 130kHz*16=2.08MHz. Damit hättest du fast 35 Befehlstyklen pro 
Wert. PWM kann der PIC ja in Hardware und du musst nur mehr den Duty 
Cycle ändern.

Dario B. schrieb:
> und denk drann: bei den pics dauert ein maschinenzyklus ganze vier
> takte
Wenn man nur 8bit PICs gesehen hat kann das so aussehen.

: Bearbeitet durch User
von Ste N. (steno)


Lesenswert?

Dario B. schrieb:
> und denk drann: bei den pics dauert ein maschinenzyklus ganze vier
> takte, d.h. du kannst die requenz, mit der die cpu taktet, erst mal
> durch vier dividieren.....

Man, man, man... nur weil es bei den Pic16, 18 und Anfangs bei den 
dsPic30 so war? Die modernen 16bit Pics benötigen genau 2 Takte pro 
Maschinenzyklus!

: Bearbeitet durch User
von Ge E. (re_n)


Lesenswert?

Jain das Stimmt zwar so,allerdings brauche ich eine Schrittauflösung von 
30-100Hz. Die PWM Frequenz beträgt 800kHz soweit klappt das alles Prima. 
Ich wollte es Folgendermaßen realisieren. Einer 16er sinetable (feste 
Werte) mit Variablen Pausenzyklen (50ns/Pauseneinheit) zwischen jedem 
einzelnen Sinus Wert liegen in meinem Timer INT. Um entsprechend auf 
meine Frequenz bei gleichzeitig gewünschter Schrittauflösung zu kommen 
muss der T1 INT 20Mio mal /s frequentiert werden.

von Max H. (hartl192)


Lesenswert?

Wieso änderst du die Schrittweite nicht über die Interrupt Frequenz? Du 
nimmst einfach fix 16 Interrupts pro Periode und anderst die Zeit 
zwischen den Interrupts.

von Ge E. (re_n)


Lesenswert?

Max H. schrieb:
> Wieso änderst du die Schrittweite nicht über die Interrupt Frequenz? Du
> nimmst einfach fix 16 Interrupts pro Periode und anderst die Zeit
> zwischen den Interrupts.

Interessanter Lösungsansatz ich denk mal kurz darüber nach. Das klingt 
machbar ;)

von Michael H. (morph1)


Lesenswert?

Und wenn mans richtig schlau macht, dann triggert man mit einem 
Timer-Interrupt-Flag nen DMA-Kanal der dann das PWM-Modul füttert.

Und schon hat man 0% CPU Last :)

von Ge E. (re_n)


Lesenswert?

Habe da meine Bedenken, da der Timer INT nur 16Bit breit ist. Bzw. das 
Timer Preload Register. Bei den höheren Frequenzen währe die Auflösung 
sicher zu grob. Der müsste bei 130kHz immerhin alle 500ns einen INT 
Aufrufen und dann auch noch das PWM Verhältniss ändern. Um ganz sicher 
zu gehen werde ich es aber morgen mal praktisch testen, den Versuch ist 
es allemal wert :)

von Ge E. (re_n)


Lesenswert?

Michael H. schrieb:
> Und wenn mans richtig schlau macht, dann triggert man mit einem
> Timer-Interrupt-Flag nen DMA-Kanal der dann das PWM-Modul füttert.
>
> Und schon hat man 0% CPU Last :)

Klingt auch interresant werde ich morgen gleich mal testen. Mit DMA im 
Zusammenhang mit den dsPICs habe ich mich bisher noch nicht beschäftigt

von Max H. (hartl192)


Lesenswert?

Re Né schrieb:
> Habe da meine Bedenken, da der Timer INT nur 16Bit breit ist. Bzw.
> das Timer Preload Register. Bei den höheren Frequenzen währe die
> Auflösung sicher zu grob.
Bei den tiefen Frequenzen hast du ja zeit um auf ein paar Interrupts zu 
warten bevor du den PWM Wert aktualisierst.

von Ge E. (re_n)


Lesenswert?

Max H. schrieb:
> Re Né schrieb:
>> Habe da meine Bedenken, da der Timer INT nur 16Bit breit ist. Bzw.
>> das Timer Preload Register. Bei den höheren Frequenzen währe die
>> Auflösung sicher zu grob.
> Bei den tiefen Frequenzen hast du ja zeit um auf ein paar Interrupts zu
> warten bevor du den PWM Wert aktualisierst.

Ja schon, allerdings wird es mir so nicht möglich sein zB von 110kHz nen 
Step auf 110,1kHz zu machen da dort ja schon einige 10-100ns eine Rolle 
spielen. Ich werde es trotzdem einfach mal versuchen.

Eine andere Idee ist mir noch gekommen, bzw hatte ich die am Anfang des 
Projekts schonmal: Ich generiere eine 40er Sinustabelle (worst case 
20kHz) und aktualisiere die Pulse Breite alle 1,25µs. Oder mache ich da 
gerade einen Denkfehler?

: Bearbeitet durch User
von Ge E. (re_n)


Lesenswert?

Ich glaube DMA kann ich abhaken leider -.-
Das dsPIC PWM Modul hat keinen DMA Kanal. Nur so Sachen wie SPI, ADC usw

von Ge E. (re_n)


Lesenswert?

Ok die Sache mit der Timer INT verzögerung habe ich probiert. Maximal FQ 
des Sinus komme ich nur auf rund 100kHz und die Schritt-Auflösung im 
oberen Bereich ist.. naja. Werde jetz mal die nächste Methode probieren

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.