Picaxe 18x RTC 32kHz xtal


Senior Member

I was recently tinkering with a new project idea. I needed to keep somewhat accurate timing, take some measurements in between, and spend the rest of the time on power save mode as the thing was to operate on batteries. Thought it would be a nice project with picaxe, too long since I used those parts in anything :D
As I had no other need for the internal timer 1 of the PIC chip, I tried to use that with an external 32kHz xtal to do the job. I think there was even a post about that in the past, but I couldn't find it.. Turns out that worked well, only external part was the 32kHz watch crystal connected in between outputs 6 and 7 (RB6 and RB7 or OSO and OSI of the PIC16F88) and one 22pF loading capacitor from both of those pins to ground.
Yes I know the 18x is an obsolete chip, but I have a few of those lying around, and I think similar techniques could be used for more recent parts as well.
Just for kicks I also noticed it was possible to use the sorout as an extra output by poking the output register, and be able to select clock speeds not normally selectable from the picaxe commands(didn't bother trying to set any outputs as inputs or vise versa, as I read on some other thread that the picaxe firmware continually resets the TRISx registers). Some notes:
-While the picaxe manual says that nap command will stop any internal timers, it does not seem to stop the timer1 when it has been started by poking the timer registers. So it's possible to use the 32kHz crystal to keep accurate timing while taking a nap which is very handy.
-sertxd does not bother the timer either, which it does to the "regular" picaxe timers (at least last I tried it, any blocking timing sensitive commands also stopped the timers and messed any hopes of accurate time keeping)
-AFAIK, commands like servo, pwm etc use the internal timer 1, so using these with the RTC trick will likely end up as a flaming failure
-As interrupting on the timer registers is not really possible, any RTC must be implemented by polling the timer registers. With 32kHz watch crystal and 1:8 prescaler the registers can hold over 10 seconds worth of time, so it's not necessary to poll the time too often.

test code with examples of use; What each bit does in each register can be found in the PIC16F88 datasheet.

#picaxe 18x

symbol OSCCON = $8F
symbol TMR1H = $0F
symbol TMR1L = $0E
symbol T1CON = $10
symbol PORT_A = $05

'set 1 MHz clock. not normally available in picaxe commands
peek OSCCON, B0
B0 = B0 & %11001111
B0 = B0 | %01000000
poke OSCCON, B0

'clear timer registers
poke TMR1H, 0
poke TMR1L, 0

'configure timer 1
peek T1CON, B0
B0 = B0 | %00111111 'prescale 1:8, enable external oscillator, no sync with external clock, select external clock source, enable and start the timer
poke T1CON, B0

nap 5 'power save delay
POKE PORT_A , %00001000 'serout used as an extra output not normally available in picaxe commands
nap 5 
POKE PORT_A , %00000000

	'loop, delay and sertxd the timer values
	nap 6

	peek TMR1H, B3
	peek TMR1L, B2
	'as the prescaler is set to 8, with 32.768kHz watch crystal we get 4096 counts per second



Senior Member

... I think there was even a post about that in the past, but I couldn't find it.. ... and I think similar techniques could be used for more recent parts as well.
I think hippy's original threads are here and here. Those date back to 2007 and concern "X2" and "M" chips (not M2). It would be very interesting to know if the method can be applied to recent (M2) chips.

There seem to be (at least) two potential issues:

The SerIn pin (T1OSCI in 08, 14 and 20M2) needs to be held low to prevent the reset/download mode starting. Certainly a pull-down much higher than the normal 32k (22k + 10k) can be used, but high enough to permit a 32kHz crystal oscillator to run? However, hippy appears to have shown that a reset did not occur (with the 08M) for some reason ?

The second problem is that M2s use Timer 1 for the "time" variable and T1 does not stop even after a DISABLETIME. I believe this is because T1 is used also for Servo pulse generation (and perhaps PWM). Furthermore, if T1 rolls over (past $FFFF or 65535) a software interrupt appears to load (or add) a value of 45536 (i.e. -20000 counts or 20 ms). So it may be necessary for the 32 kHz-based polling/interrupt routine to reset T1 to a "low" value before an overflow can occur, or perhaps the timer can be assumed to be dividing by 20000 ?

Cheers, Alan.