1
\$\begingroup\$

I have a board that has a PIC16F18855 running at 8MHz from an external crystal. Most of the time it works fine, but if it gets rapidly power cycled it will restart at 4MHz. The main symptoms of this are things such as the UART baud rate and the PWM frequency dropping by half.

More specifically, if I flick the power switch on and off in less than ~2 seconds, it will run at the lower frequency. Longer and it works properly. When I program the board, it restarts at 4MHz, meaning I have to physically turn it off and on before it will work. If I short the MCLR pin to ground, the behavior is inconsistent - sometimes it will start at 4MHz and but usually it will start at 8MHz.

I have also had one instance where it was taking substantially longer, where turning it on within 10 minutes of turning it off made it start at 4MHz. I'm not sure if the problem is related, but I'm not able to reproduce that error at the moment.

From probing the OSC2/CLKOUT pin, I can see that the crystal itself is still running at 8MHz. With the probes I have I can't probe the OSC1 pin without it resetting the micro.

EDIT 1:

When the board is running at 8MHz, its OSCCONx registers are:

OSCCON1: 0x70
OSCCON2: 0x70
OSCCON3: 0x10

and when its running at 4MHz they are:

OSCCON1: 0x70
OSCCON2: 0x60
OSCCON3: 0x00

So it's running off the HF internal oscillator. Will look at this a little closer. Knowing this I may be able to come up with a work around, but I'd rather figure out the cause of the problem.

OSCFRQ = 0x02, which is the setting for 4MHz, so this is definitely whats happening. Terrible workaround would be to set the OSCFRQ register to the 8MHz setting, so it works the same either way, but then I lose the precision of the crystal. That may not ruin everything, but I have some timing sensitive things so I prefer to use the crystal if I can.

\$\endgroup\$
  • \$\begingroup\$ What are your OSCCONx settings? \$\endgroup\$ – Spehro Pefhany Jan 8 '18 at 20:05
  • \$\begingroup\$ OSCCON1: 0x70, OSCCON2: 0x70, OSCCON3: 0x10, \$\endgroup\$ – Escape Jan 8 '18 at 20:26
  • \$\begingroup\$ There's a lot of clock source and prescaler complexity on that chip. RSTOSC matters too. I'll look at tomorrow if nobody has helped. \$\endgroup\$ – Spehro Pefhany Jan 8 '18 at 20:31
  • \$\begingroup\$ Does the chip have clock failover enabled? Some PICs will use the internal oscillator 1: while the external oscillator is stabilizing. and or 2: if the external oscillator fails. If you have a scope, you may want to check and see if the crystal is oscillating correctly. (that won't be a guarantee, because the probe will effect the circuit but it may tell you something). \$\endgroup\$ – Drew Jan 8 '18 at 21:43
  • \$\begingroup\$ The probes I have load the circuit too much for me to probe the oscillator input pin. I'm not totally sure what you mean by clock failover, but it is defaulting to the HF internal oscillator (worked that out thanks to Spehro's comments, its in the edits). I'm currently trying to work out what's causing that \$\endgroup\$ – Escape Jan 8 '18 at 22:06
1
\$\begingroup\$

This is not an explanation for why it was happening, but I found a fix. First thing I tried was setting the fuse bits for RSTOSC_EXT (i.e. #pragma fuses HS, RSTOSC_EXT) on the basis of what Spehro said in the comments, but that didn't work for me. What I did was add in the following (note that OSCCON2 is the actual setting, and OSCCON1 is the buffer):

if(OSCCON2 == 0x60){
    OSCCON1 = 0x60;
    OSCCON1 = 0x70;
}

My reason for trying this is: OSCCON2 is the actual setting, and will load the value in OSCCON1 when its ready. From my earlier investigation, I knew that the correct value was in OSCCON1, and OSCCON2 never loaded it. So the assumption was that the loading process got stuck somewhere, and loading the value in OSCCON2 into OSCCON1 would make the chip think its loaded correctly. This would 'unstick' it, and then allow me to reload the correct value without it getting stuck.

This code is right at the start of the main function, after variable declarations. It solves the problem, but it doesn't explain why it was happening in the first place. If anyone knows what was causing this and if there is a better fix I'm still open to better answers.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.