Ich habe ein Board mit einem PIC16F18855, der mit 8 MHz von einem externen Kristall läuft. Die meiste Zeit funktioniert es gut, aber wenn es schnell aus- und wieder eingeschaltet wird, wird es bei 4 MHz neu gestartet. Die Hauptsymptome dafür sind Dinge wie die UART-Baudrate und die halbierte PWM-Frequenz.
Genauer gesagt, wenn ich den Netzschalter in weniger als ~ 2 Sekunden ein- und ausschalte, läuft er mit der niedrigeren Frequenz. Länger und es funktioniert einwandfrei. Wenn ich das Board programmiere, startet es bei 4 MHz neu, was bedeutet, dass ich es physisch aus- und wieder einschalten muss, bevor es funktioniert. Wenn ich den MCLR-Pin gegen Masse kurzschließe, ist das Verhalten inkonsistent - manchmal beginnt es bei 4 MHz und normalerweise beginnt es bei 8 MHz.
Ich hatte auch einen Fall, in dem es wesentlich länger dauerte, als es innerhalb von 10 Minuten nach dem Ausschalten eingeschaltet wurde und es bei 4 MHz startete. Ich bin mir nicht sicher, ob das Problem damit zusammenhängt, aber ich kann den Fehler im Moment nicht reproduzieren.
Wenn ich den OSC2/CLKOUT-Pin sondiere, kann ich sehen, dass der Kristall selbst immer noch mit 8 MHz läuft. Mit den Sonden, die ich habe, kann ich den OSC1-Pin nicht sondieren, ohne das Mikro zurückzusetzen.
BEARBEITEN 1:
Wenn das Board mit 8 MHz läuft, sind seine OSCCONx-Register:
OSCCON1: 0x70
OSCCON2: 0x70
OSCCON3: 0x10
und wenn es bei 4 MHz läuft, sind sie:
OSCCON1: 0x70
OSCCON2: 0x60
OSCCON3: 0x00
Es läuft also vom internen HF-Oszillator. Werde mir das etwas näher anschauen. Wenn ich das weiß, kann ich vielleicht eine Lösung finden, aber ich würde lieber die Ursache des Problems herausfinden.
OSCFRQ = 0x02
, was die Einstellung für 4 MHz ist, also passiert das definitiv. Eine schreckliche Problemumgehung wäre, das OSCFRQ
Register auf die 8-MHz-Einstellung zu setzen, damit es in beiden Fällen gleich funktioniert, aber dann verliere ich die Präzision des Kristalls. Das ruiniert vielleicht nicht alles, aber ich habe einige Timing-empfindliche Dinge, also ziehe ich es vor, den Kristall zu verwenden, wenn ich kann.
Dies ist keine Erklärung dafür, warum es passiert ist, aber ich habe eine Lösung gefunden. Als erstes habe ich versucht, die Fuse-Bits für RSTOSC_EXT (dh #pragma fuses HS, RSTOSC_EXT
) auf der Grundlage dessen zu setzen, was Spehro in den Kommentaren gesagt hat, aber das hat bei mir nicht funktioniert. Was ich getan habe, war Folgendes hinzuzufügen (beachten Sie, dass OSCCON2 die tatsächliche Einstellung und OSCCON1 der Puffer ist):
if(OSCCON2 == 0x60){
OSCCON1 = 0x60;
OSCCON1 = 0x70;
}
Mein Grund, dies zu versuchen, ist: OSCCON2 ist die tatsächliche Einstellung und lädt den Wert in OSCCON1, wenn es fertig ist. Aus meiner früheren Untersuchung wusste ich, dass der richtige Wert in OSCCON1 war und OSCCON2 ihn nie geladen hat. Die Annahme war also, dass der Ladeprozess irgendwo hängen geblieben ist und das Laden des Werts in OSCCON2 in OSCCON1 den Chip glauben lassen würde, dass er korrekt geladen ist. Dies würde es "lösen" und mir dann erlauben, den richtigen Wert neu zu laden, ohne dass es hängen bleibt.
Dieser Code steht direkt am Anfang der Hauptfunktion, nach Variablendeklarationen. Es löst das Problem, erklärt aber nicht, warum es überhaupt passiert ist. Wenn jemand weiß, was dies verursacht hat, und wenn es eine bessere Lösung gibt, bin ich immer noch offen für bessere Antworten.
Spehro Pefhany
Fliehen
Spehro Pefhany
Zeichnete
Fliehen
John Birkkopf