Continue to Site

Welcome to our site!

Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

  • Welcome to our site! Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

PIC 18F oscillator switching - crash

Status
Not open for further replies.

futz

Active Member
I've written a little routine to kick my clock down to a low power state for when it's on battery backup. I'm trying to get it to switch from the 20MHz main crystal to the 32.768kHz on Timer1 on loss of main power, and then switch back on power restore. But when power is restored the clock isn't running anymore. I've read the datasheet oscillator chapter four times and I don't see any "gotchas" I've missed. Here's the routine. RA5 senses main power. Oh ya, it's a 18F248:
Code:
void lo_power(void){
	ccpr1l=0;			//turn off LCD backlight
	adcon0.ADON=0;			//A/D off
	osccon=1;			//switch to timer1 osc (32.768kHz) - low power mode
	while(!porta.5)			//wait while no power
		delay_ms(100);
	osccon=0;			//switch back to 20MHz crystal
	adcon0.ADON=1;			//turn A/D back on
	ccpr1l=bl;			//restore backlight
}
Yes, the OSCSEN config bit is set enabled. :D
 
Last edited:
I think you have to use the software reset to kick the crystal back into operation if you changed to the internal RC clock.
Really? I just don't read it that way in the datasheet. It says the whole thing is automatic and when switched over, program execution resumes (not in those words obviously :p).

If I have to reset I'll have to save some variables in EEPROM first and restore them after. Probably more work than it's worth.
 
Oh, fer pete's sake! I just noticed it starting up on its own out of the corner of my eye. The problem is that the 32.768kHz osc is just SO slow that it appears to be dead while it's stuck in the delay loop. The interrupt is still blipping away though, because when it finally wakes back up the time is still correct.

So I (and the datasheet) was right. No reset is required. All timing things are handled automatically when switching between oscillators. :)

I need to pinch that delay WAY down. There's no reason for it to be so long anyway.
 
Last edited:
Have you got adequate decoupling capacitors very near to the power pins on the PIC ?

I've recently noticed some very strange problems on inadequately decoupled PICs
 
And looking at your code, is 100ms the delay while running at full speed or at 32khz ? It might be working just waiting a lot longer than you think ;)
 
And looking at your code, is 100ms the delay while running at full speed or at 32khz ? It might be working just waiting a lot longer than you think ;)

Futz said:
Oh, fer pete's sake! I just noticed it starting up on its own out of the corner of my eye. The problem is that the 32.768kHz osc is just SO slow that it appears to be dead while it's stuck in the delay loop. The interrupt is still blipping away though, because when it finally wakes back up the time is still correct.

The moral of the story is that when you switch clock speeds the built in delay_ms functions can be very wrong.
 
Never mind 'can be' they 'will be' :D
LOL
It is not often you make me laugh.

Futz:

For the CCS compiler you could put this where you slow down the processor
#use delay(clock=32768)​
It changes the delay calculations and the osccon bits to change the speed. I am sure the C purist would object.

I do not know if BoostC supports this but it is worth a look.

Swordfish has a CLOCK= but I do not know if you can change it or specify it in other then MHz.
 
LOL
It is not often you make me laugh.

Futz:

For the CCS compiler you could put this where you slow down the processor
#use delay(clock=32768)​
It changes the delay calculations and the osccon bits to change the speed. I am sure the C purist would object.

I do not know if BoostC supports this but it is worth a look.

I think this works the same...

#pragma CLOCK_FREQ 8000000
 
The moral of the story is that when you switch clock speeds the built in delay_ms functions can be very wrong.
Got that right. The delay is unnecessary. It could just spin in that while loop without one. I left it in anyway, but changed it to 5ms. So when power is restored, even at 32.768 it pops out of the loop in maybe a second at most.

The battery backup works great. I'm still going to work on getting it to consume even less power though. Do some Sleeping and things like that...
 
Status
Not open for further replies.

New Articles From Microcontroller Tips

Back
Top