Hallo, ich verwende einen PIC24FJ64GB004 für eine USB Anwendung. Ich würde gernen auf den internen FRC (8 Mhz; Genauigkeit typ: +/-0.25, min: -1.25%, max: +1,00%) zurückgreifen. Die USB-Spezifikation schreibt für den Betrieb bei Full-Speed eine Genauigkeit von +/-0.25% vor. Im Datenblatt steht für den USB-Betrieb ist kein externer Quarz nötig, allerdings steht nicht dabei das dies nur für den Betrieb bei Low-Speed zutrifft - ist aber anzunehmen (siehe oben: Genauigkeit des internen FRC außerhalb +/-0.25%) Ich suche nun eine Möglichkeit den FRC hinreichend zu kalibrieren (Register OSCTUN). Zur Verfügung steht mir dazu ein (genauer) Uhrenquarz als SOSC, welche auch die RTCC Einheit speist. Wie stelle ich das am besten an? - Die Kalibrierung sollte dabei nicht all zu viel Zeit in Anspruch nehmen (max. 20 Sekunden) - Timer stehen mir alle zur Verfügung, allerdings verstehe ich möglicherweise die verschiedenen "Clocks-Speise-Möglichkeiten" nicht hinreichend. Das hab ich mir nun überlegt: 1. Timer1 wird über SOSC (Uhrenquarz) gespeist. Mit Prescaler von 256 generiert er alle 1/128Hz = ~7,81ms einen Interrupt. 2. Timer2 wird durch Systemtakt (FRC / 2 = ~4MHz) versorgt. Kein Prescaler. Wert erhöht sich dabei ca alle 1/4Mhz = ~250ns um eins. 3. Auswerten (evtl. auch erst nach mehreren Zyklen, dann wäre aber sicherlich für Timer2 ein Prescaler nötig) Wenn der FRC genau mit 8MHz schwingt dann müsste Timer2 einen Wert von 31250 haben ( 1/128Hz : 1/4MHz = 31250 ), schwingt der Quarz mit 8000256 Mhz, dann hätte Timer2 den Wert 31251, 31249 für 7999744 Mhz, usw. Frage A: Kann ich Timer1 überhaupt von meinem Uhrenquarz speisen. Im Datenblatt steht dazu "External clock from T1CK pin (on the rising edge)". Heißt das ich benötige einen Uhrenquarz-OSZILLATOR? Frage B: Kann ich mit dieser Vorgehensweise eine ausreichende Genauigkeit erreichen? Frage C: Wird es überhaupt genauer wenn ich mit mehreren Zyklen auswerte, UND damit auch einen Precaler für Timer2 verwenden muss? Frage D: (Zu Frage C) Wäre es genauer den Timer2 als 32-bit Timer laufen zu lassen, also wieder OHNE Prescaler? Frage E: Kann ich dabei die Genauigkeit des Uhrenquarzes außer Acht lassen, sie wie ich es nun gemacht habe? Frage F: Ist der Ansatz überhaupt brauchbar, funktioniert das überhaupt, oder gibt es "smartere" Lösungsansätze? Vielen Dank fürs Lesen (ist nun doch etwas viel geworden) :) mfg Benny
Sorry, kanns sein das ich etwas nicht verstehe? Laut dir: Benjamin R. schrieb: > Die USB-Spezifikation schreibt für den Betrieb bei Full-Speed eine > Genauigkeit von +/-0.25% vor. Laut Datenblatt: > 8 MHz Internal Oscillator with 0.25% Typical Accuracy (-1.25 +0.25 1.0) ICh würd Microchip da mal soweit vertrauen :) Abgesehen davon, auch die 1% PICs (PIC24FJ256GB210) oder auch die 2% FRC (PIC24FJ256GB110) machen keinerlei Probleme am USB-Bus, ist natürlich nur zum Testen geeignet, auf keinen Fall für die Produktion.
Interessanten Lesestoff zu dem Thema bieten AN244 http://ww1.microchip.com/downloads/en/AppNotes/00244a.pdf als auch: http://www.microchip.com/forums/m452880.aspx
Ok danke für die bisherigen Meinungen. >Michael H. >ICh würd Microchip da mal soweit vertrauen :) Ich hätte das gerne sauber gelöst. >Florian V. Danke, den Thread hatte ich noch nicht gesehen. Aber man sieht das es selbst da keine 100% klare Aussage gibt. Ich hab die ganzen Timer noch über und würde die gerne noch sinnvoll nutzen, damit ich ganz sicher weiß das Teil funktioniert in zwei Jahren auch noch, bin aber gleichzeitig auf die zusätzlichen IOs angewiesen, sonst würde ich ja sowieso einen Quarz nehmen. ;) Mit Assembler habe ich leider nichts am Hut und möchte schon ganz gerne bei C bleiben. Den ASM Code zu portieren sehe ich aber problematisch, da die Instructions gezählt werden, was ich wiederrum bei C nicht kann:
1 | volatile varInstructions = 0; |
2 | volatile varCalDone = FALSE |
3 | |
4 | ISR_Timer1Overflow { Auswerten (varInstructions); varInstructions = 0; varCalDone = TRUE } |
5 | |
6 | main: |
7 | |
8 | while (!varCalDone) { varInstructions++; }; |
Problem: Je nach Optimierungsstufe und Compilerversion könnte der Code anders übersetzt werden, was dazu führt das ich u.U. eine sehr große Abweichung der gezählten Instruktionen hätte. Deswegen auch mein Vorschlag mit den beiden Timern, sinngemäß:
1 | // Timer1 Clock: 32,786 kHz, Timer2 Clock: FRC/2
|
2 | ISR_Timer1Overflow { Auswerten (Timer2_Zaehlstand); } |
Was meint ihr dazu? Zu einfach? Zu Umständlich? mfg Benny
Benjamin R. schrieb: > Mit Assembler habe ich leider nichts am Hut und möchte schon ganz gerne > bei C bleiben. Da würd ich nicht dran rumschrauben, gibt es bei C keinen Inline Code? Das ganze ist doch simpel gemacht, braucht kaum Flash und gerade mal 30ms at startup. Der Pic geht danach so gut wie unverändert an den Start, nur halt mit garantierter Taktfrequenz.
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.