Hallo Ich benutze einen PIC18f4420 mit C18-Compiler. Über den Timer3 und das OutputCompare2-Register generiere ich eine variable Frequenz an CCP2. Dabei muss ich jedes mal beim Compare-Interrupt das Register um die gewünschte Periode erhöhen. Dies funktioniert soweit wunderbar bis ca. 40kHz. Problem: Sobald ich irgendwo in einer Funktion eine Multiplikation, Divison oder ähnlich programmiere, werden die Interrupts bereits bei 10kHz verpasst!! Völlig schleierhaft: dies geschiet sogar wenn die Funktion noch nicht einmal aufgerufen wird. Kennt jemand das Problem? (Der Prozessor läuft berits mit maximaler Taktfrequenz. Ausweichen auf +- funktioniert auch nicht, da x+=x ebenfalls die Multiplikationsroutinen aufruft.)
@ gast (Gast) >Compare-Interrupt das Register um die gewünschte Periode erhöhen. >Dies funktioniert soweit wunderbar bis ca. 40kHz. Das ist ja schon recht flink, 25us. Da hat man ein 20 MHz Quarz auf dem PIC gerade mal 5 MHz Systemtakt, macht 125 Takte zwischen den Interrupts. >Sobald ich irgendwo in einer Funktion eine Multiplikation, Divison oder >ähnlich programmiere, werden die Interrupts bereits bei 10kHz verpasst!! Tja, schon mal überlegt wie lange so eine Multiplikation, und erst recht ein DIVISON dauert? >Völlig schleierhaft: dies geschiet sogar wenn die Funktion noch nicht >einmal aufgerufen wird. ??? >(Der Prozessor läuft berits mit maximaler Taktfrequenz. Ausweichen auf Die da wäre? >+- funktioniert auch nicht, da x+=x ebenfalls die >Multiplikationsroutinen aufruft.) Glaub ich nicht. MfG Falk
Danke für die Antwort... >Tja, schon mal überlegt wie lange so eine Multiplikation, und erst recht >ein DIVISON dauert? Ist mir völlig egal wie lang das dauert. Die Frequenz benötige ich nach der Berechnung und der Interrupt geht vor. Der PIC18F ist auch sehr schnell mit Multiplikationen. Das ist nicht das Problem. >>??? :-) Betreibe den PIC mit den internen 8Mhz mitt eingeschaltenem PILL = 32MHz. Der Systemtakt beträgt dann 8MHz. Allein das schreiben eines / oder * Zeichens irgendwo im Programm (auch wenn es nicht ausgeführt wird) verursacht eine miese Latenzzeit bei den Interrupts. Der Zähler rennt aber normal mit 8Mhz. Keine Ahnung wiso. Ich weiss nur dass dann die Routinen für "/* float" in mein Programm geschrieben werden. (Bin mit C18 noch nicht allzu versiert). Wird irgend eine Einstellung verändert? >>Glaub ich nicht. Der Compiler erzeugt einen CALL zu einer solchen Subrutine. Leider. Mfg MICHI
Wer benutzt float in einem uC ohne FPU? Dann ist klar dass man absolut verloren hat.
Ich :D na ja alle 5 s kann man ja mal eine machen... solangs ned ständig ist :)
Hallo 1. werf Float raus und rechne mit Integer Arithmetik , Links dazu gibt es genug. Die Genauigkeit ist nicht schlechter als mit Float , anhängig von deiner Implementierung, spart aber sehr viel Resourcen. 2. Sieh dir den von Compiler erzeugten Assemblercode an, besonderst den in den Interruptroutinen. Dann rechne nach wie lange dein PIC für die Bearbeitung benötigt. Das Interupthandling beim PIC ist ja nu nicht gerade das beste was es gibt, ==> persönliche Meinung 3. Überprüf den kompletten Code wann, wo und wie lange die Interruptbehandlung gesperrt wird. 4. Rechne mal nach ob dein PIC wirklih der richtige µC für deine Anwendung ist. Ds heißt ob er genug Resurcen bietet. ==> eventuell wirst du auf einen µC mit mehr Leistung umsteigen müssen.
> Wer benutzt float in einem uC ohne FPU? Dann ist klar dass man > absolut verloren hat. Soll das ein Trollbeitrag sein?
klingt so. Normalerweise arbeite ich mehr mit Int, aber manchmal ist es einfach sinnvoller (oder sogar unumgänglich) float zu nehmen. Ernstzunehmende Performance-Einbrüche habe ich keine erlebt :-) Und wenn das Teilchen durch float-Operationen in die Knie gezwungen, wurde einfach der falsche Prozessor gewählt. Üblicherweise wird doch ne ganze Menge Zeit gewartet.
Super Antworten, danke... @Ralf Die Punkte 2 und 3 sind interessant. Ich werde mich eimal darauf stürzen. Mal schauen. Im schlimmsten Fall muss ich halt wirklich mit INT rechnen und für */ Loopings verwenden. Das Interrupthandling ist wirklich mühsam :-). Klar, der PIC ist nicht besonders geeignet für meine Anwendung. Aber Preis und Umgebung sind super. Die Leistung müsste ausreichen. Der Hund liegt im Detail. Eine FPU währe wohl etwas übertrieben. :-) Ich will ja kein CAS bauen. MfG MICHI
Yes!! War ich ein Vollidiot :-). Habe folgenden Befehl im Interrupt verwenden um den Compare neu zu laden und die Flanke zu toggeln. //OpenCompare2(compop^=1,comp+=i); Habe leider übersehen dass der Assembler ein CALL zu einer GIGA-Funktion schreibt. Händisch comp+=i; CCPR2L = comp; CCPR2H = (comp >> 8); CCP2CON = compop^=1; Wieso nicht von Anfang an so?? Funktioniert super! MfG MICHI
@Dieter Werner: Wieso soll das ein Trollbeitrag gewesen sein? Float auf ner 8 Bit uC ohne FPU ist nunmal absolute Resourcenverschwendung, das weiß jedes Kind. Klar, wenn man eh davon genug hat spielt das vielleicht keine Rolle, aber dann braucht man sich nicht wundern wenn man immer dickere Hardware braucht. In den meisten Fällen reicht nunmal Festkommaarithmetik.
Eine FPU vorzuschlagen wenn alle 5 Sekunden mal eine Rechenoperation durchgeführt werden soll ist doch noch viel größere Ressourcenverschwendung. Und es gibt halt Situationen wo es float sein muss und fixed-point nicht ausreicht.
> Wieso soll das ein Trollbeitrag gewesen sein?
Weil ein 8-Bit uC mit FPU die absolute Ausnahme ist, mir ist kein
einziger bekannt.
Bei 16 oder 32-Bit DSP sieht das schon ganz anders aus.
Morin wrote: > Eine FPU vorzuschlagen wenn alle 5 Sekunden mal eine Rechenoperation > durchgeführt werden soll ist doch noch viel größere > Ressourcenverschwendung. Und es gibt halt Situationen wo es float sein > muss und fixed-point nicht ausreicht. Welche Situation ?
z.B. wenn der Wertebereich 2^32 (long) nicht reicht? Gibts immer wieder mal, dass "grosse" oder "kleine" zahlen auftauchen...
wenn 2^32 nicht ausreicht, dann nimm 2^64, immer noch Integer und bei sehr kleinen zahlen mit zb 256 ( shift 8) multiplizieren dann auch interger. Also Float ist ok auf einem PC mit FPU, aber auf µC glattweg Unfug. Du solltest dich mal ernsthaft mit Integerarithmetik beschäftigen.
@Dieter Werner und Mroin: Deswegen schlage ich ja fixed point vor, nicht eine uC mit FPU.
Ich berechne mit meinem uP die Töne aus Frequenzen und verse vice. Dazu benötige ich zum * oder / die 12.Wurzel aus 2 für die mikrotonale Abstimmung. Dies funktioniert präzise und schnell. Immerhin benötige ich pro Berechnung bis zu 10 Float-Divisionen und das Resultat kommt in <5ms... Ich sehe keinen Grund für die Umstellung auf INTEGER.
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.