John Bolin (Flying Canuk) sent this to me in June 2009. I discovered a printout today with the code, but a forum search couldn't find it anywhere here. So here is a very clever piece of code written in MBASIC 5.2.1.1 for your study.
NOTE: This is probably doable with a newer Atom chip, like the RevD Atom28-M module. However, some syntax changes will have to be made since Studio is the standard BMicro compiler nowadays. Also, the 32KHz crystal will need small 15 to 20 pF capacitors from the pins to ground in order to work properly.
Code:
CPU = 16F876
MHZ = 10
CONFIG 16382
;This is to show how to run a 32khz second clock chip on 16F876 on pins C0 C1
;C7 C6 are LED common to ground through a 1.2k resistor
;A 10mhz resonator runs the timer0 and a second 32kHZ clock crystal runs off
timerint0 var bit
timerint1 var bit
ampm var bit ;am=0 pm=1
seconds var byte
minutes var byte
hours var byte
day var byte
month var byte
year var word
clear ;clears all vars set to zero
;initialize vars
hours=10
timerint1=1
pause 500
;LCDWRITE B5B6B7, portA.nib0, [INITLCD1, INITLCD2, TWOLINE,CLEAR, HOME, SCR,"Hello"]
;Display scan for Real time clock
ONINTERRUPT TMR0INT, Timer0
SETTMR0 TMR0INT256 ;set prescaler
ENABLE TMR0INT; turn the interupt on
;Real time clock RTC interrupt setup.
ONINTERRUPT TMR1INT, Timer1; jump to timer1 interupt routine on inerrupt tmr1int
SETTMR1 TMR1ext8 ;set prescaler to divide by eight
TMR1H=$F0 ;timer counts up and when it reaches $FFFF and interrupt is generated
TMR1L=$00 ;set to zero this plus 15 in upper byte = 16 times or 1 second
T1CON.BIT3=1 ;TURNS On EXT 32.768 khz osc crystal
ENABLE TMR1INT ;Turn on Timer1
LOW C6 ;set C6 as output and set low LED off will toggle if interrupt is generated
LOW C7 ;SET C7 AS OUTPUT AND SET low LED off will toggle if interrupt is generated
main:
if timerint1=1 then ;interrupt routine set to =1
timerint1=0 ;set to zero and update display once:
LCDWRITE B5B6B7, portA.nib0, [HOME, "The time is ", DEC hours2,":",DEC minutes2,":",DEC seconds2]
SEROUT B0, i9600,["The time is ", DEC hours2,":",DEC minutes2,":",DEC seconds2]
endif
goto main
DISABLE; all interupts disabled for code below
Timer0
timerint0=1
TOGGLE C6
RESUME
Timer1
timerint1=1; ONE SECOND HAS PASSED, CLOCK NEEDS TO BE UPDATED
TOGGLE C7;ONE SECONDS
TMR1H=$F0;Counter counts up so this leaves divide by 16(TRM1H)*256(TRM1L)*8(prescaler)=32,768hz
;TMR1L=$00 ;NOT USED value could change before update is depending on interrupt timing =256 counts
if seconds<59 then ;update second and check minutes
seconds=seconds+1
else
seconds=0
if minutes<59 then ;update minutes and check hours
minutes=minutes+1
else
minutes=0
if hours<23 then ;update houurs and set ampm flag
hours=hours+1
else
hours=0
endif ;close clock update
if hours<12 then ;set ampm flag
ampm=0
else
ampm=1
endif ;end ampm flag
endif
endif
RESUME