PIC16F18855 läuft mit halber Taktfrequenz, wenn ich ihn zu schnell ein- und ausschalte

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 OSCFRQRegister 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.

Was sind Ihre OSCCONx-Einstellungen?
OSCCON1: 0x70, OSCCON2: 0x70, OSCCON3: 0x10,
Auf diesem Chip gibt es eine Menge Taktquellen- und Prescaler-Komplexität. RSTOSC ist auch wichtig. Ich werde morgen mal schauen, ob niemand geholfen hat.
Hat der Chip Uhr-Failover aktiviert? Einige PICs verwenden den internen Oszillator 1: während sich der externe Oszillator stabilisiert. und oder 2: wenn der externe Oszillator ausfällt. Wenn Sie ein Zielfernrohr haben, möchten Sie vielleicht überprüfen, ob der Kristall richtig schwingt. (Das ist keine Garantie, da die Sonde den Stromkreis beeinflusst, aber es kann Ihnen etwas sagen).
Die Sonden, die ich habe, belasten die Schaltung zu sehr, als dass ich den Oszillator-Eingangspin sondieren könnte. Ich bin mir nicht ganz sicher, was Sie mit Takt-Failover meinen, aber es ist standardmäßig der interne HF-Oszillator (das hat dank Spehros Kommentaren funktioniert, es ist in den Bearbeitungen). Ich versuche gerade herauszufinden, woran das liegt
Versuchen Sie, /PWRTE auf "0" zu setzen (CONFIG2 Bit 1). Dadurch erhält Ihre Stromversorgungsspannung 64 ms Zeit, um sich zu stabilisieren, bevor der Reset beendet wird.

Antworten (1)

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.