Bei meinen ersten Schritten mit dem PIC32 habe ich natürlich mit dem „Hello World“ der embedded Welt begonnen: ein Port Bit wird ein- und ausgeschaltet. Das hat auf Anhieb funktioniert.
Als nächstes stellt sich dann die Frage: wie schnell kann man einen Port ein- und ausschalten. Hier bin ich auf ca. 400 nS gekommen, eigentlich zu langsam für so einen schnellen Prozessor. Unglücklicherweise habe ich das Ergebnis einfach so hingenommen, da es schnell genug für meine Aufgaben war.
Hätte ich mich damals um eine Klärung bemüht, wären mir gestern mehrere Stunden Fehlersuche erspart geblieben. Mein Frequenzzählerprojekt kommt nicht so schnell voran wie erhofft (das liegt zum einen an der verfügbaren Zeit aber noch mehr daran, dass ich mehr lernen muss als ich vorher gedacht hätte) – aber es macht Fortschritte. Mittlerweile haben ich das Anzeigemodul und einen einfachen durchlaufenden Zähler. Als ich gestern meinen Referenztakt von 25 MHz auf den Zähler gegeben habe, hat sich gezeigt, dass der Zähltakt unter einem MHz lief. Der Oszillator war unschuldig, das Oszilloskop hat ordentliche 25 MHz angezeigt.
Die Fehlersuche hat sich etwas mühsam gestaltet, da ich gleich zwei Fehler in der Prozessorkonfiguration hatte. Diese hatte ich einfach aus einem Beispiel übernommen, welches offensichtlich für eine andere Prozessorversion war.
Zum einen wurde der Takt für die externen Komponenten durch den Wert 8 geteilt. Wenn man die kryptischen Kurznamen der Konfiguration verinnerlicht hat, ist das offensichtlich. Mir ist es aber vorher nicht aufgefallen.
Der größere Fehler bestand aber darin, dass die Konfiguration für einen externen 8 MHz Quarzoszillator eingestellt war. Ich habe aber keinen Quarz in meiner Schaltung (der Prozessortakt geht nicht in die Messgenauigkeit ein). Irgendwie lief der Prozessor aber trotzdem, vermutlich blieb er auf einem langsamen internen Oszillator für den Start hängen.
Nachdem ich die Konfiguration in Ordnung gebracht hatte (interner schneller RC Oszillator mit 8 MHz, PLL auf 64 MHz), lief mein Zähler problemlos mit den 25 MHZ (da der Zähler intern synchronisiert wird, ist die Zählertaktrate durch den Prozessortakt beschränkt).
#pragma config FPLLIDIV = DIV_2 // PLL Input Divider (2x Divider)
#pragma config FPLLMUL = MUL_16 // PLL Multiplier (16x Multiplier)
#pragma config FPLLODIV = DIV_1 // System PLL Output Clock Divider (PLL Divide by 1)
#pragma config FWDTEN = OFF
#pragma config FNOSC = FRCPLL // Oscillator Selection Bits (Fast RC Osc with PLL)
#pragma config FSOSCEN = OFF // Secondary Oscillator Enable (Disabled)
#pragma config IESO = OFF // Internal/External Switch Over (Disabled)
#pragma config POSCMOD = OFF // Primary Oscillator Configuration (Primary osc disabled)
#pragma config OSCIOFNC = OFF // CLKO Output Signal Active on the OSCO Pin (Disabled)
#pragma config FPBDIV = DIV_1 // Peripheral Clock Divisor (Pb_Clk is Sys_Clk/1)
#pragma config FCKSM = CSDCMD // Clock Switching and Monitor Selection (Clock Switch Disable, FSCM Disabled)
Als nächstes habe ich nun noch mal mein Blinky Programm korrigiert. Jetzt komme ich auf eine Periode von ca. 100 nS für ein Bit Setzen und Zurücksetzen – also ca. 50 nS für eine Portausgabe. Das ist schon viel näher an den erwarteten Werten.