MicroChip pic 16c84 16f84 asm code for propeller clock
;-----------------------------------------------------------------
; 3mode.asm
; Copyright Don Zehnder all rights reserved December 1997
;
; Code made for "the propeller clock"
; Copyright Bob Blick all rights reserved February 1997
;
;
; This code give the propeller 3 modes
;
; Analog clock mode by Don Zehnder
: Digital mode by Bob Blick
; Scrolling text mode by Don Zehnder
;
; mode 0: digital
; mode 1: analog
; mode 2: message
;
; Assignments on portb. Say, here's a dumb way to hook things up!
; BIT LED (from center=1 to edge=7)
; 0 5
; 1 1
; 2 2
; 3 3
; 4 rotation index input
; 5 4
; 6 7
; 7 6
; hours bit 1,2,3,5
; min bit 1,2,3,5,0,7
; seconds bit 6
; time set porta,4
; ~10 MHz crystal
;----------------------------------------------------------------------
list p=16f84
include "p16f84.inc"
__FUSES _CP_OFF & _WDT_ON & _HS_OSC &
_PWRTE_OFF
cblock 0x0c
;----unique to analog---
DIVISOR1 ;these are to
count # of interrupts
DIVISOR2 ;required to
increment ZSEC, decrement DSEC
DSEC
;There are 256 DSECs in a minute (1 rev)
ZSEC
;When this rolls over, decrement DMIN
DMIN
;There are 256 DMINs in an hour (1 rev)
ZMIN
;When this rolls over, decrement DHOUR
DHOUR
;There are 256 DHOURs in 12 hours (1 rev)
mulcnd
; 8 bit multiplicand
H_byte
; High byte of the 16 bit result
L_byte
; Low byte of the 16 bit result - (unused result)
TEMP ;
part of routine for setting hands when period=0
;----unique to digital---
dot_index ;which column is being
displayed
digit_index ;which digit is being displayed
hours ;in
display format, not hex(01-12)
minutes ;00 to 59
bigtick_dbl ;incremented each interrupt
bigtick_hi
bigtick_lo
scratch ;scratch value
tick
;used by delay
COUNTER2 ;used as
secondary counter to slow time set
ADJUST ;fine adjust
on timing
;---unique to message--------------
CT1
;incremented each interrupt
CT2
;incremented each interrupt when CT1 rolls-over
CNT
;counter for display of columns in message
MAX ;
OFFSET ;counter for
offsetting display. Scrolls by incrementing this
;----common--------------
COUNTER ;used to slow time
set
PERIOD_CNT ;incremented each interrupt
PERIOD ;stable period
after hysteresis calc.
safe_w ;copy of W
safe from interrupt
safe_s ;copy of STATUS safe
from interrupt
period_dup ;copy of
period_count safe from interrupt
flags ;b2=int,
b1=minute, b0=prev_flag, b3=mode_bit,
b4=toggle
mode
endc
;----ANALOG-----
#define divisor1_val d'147'
;roll-over at 109 (256-109)=147
#define divisor2_val d'235'
;roll-over at 21
#define zsec_val d'196'
;min hand moves 1/60 fast as sec hand
#define zmin_val d'244'
;hour hand moves 1/12 fast as min hand
#define offset_val d'57'
;offset is n/256 rev for analog.
;needed for proper display
position
;since we want analog noon to be
where
;the digital colon is. Determined
empirically.
#define nths_adj_div2 d'2'
;these are adjusted to correct
#define nths_adj_zsec d'8'
;for observed crystal error in analog mode
#define nths_adj_zmin
d'1' ;time is kept similarly to
AN590
;-----COMMON-------
#define in_bit
PORTB,4 ;using phototransistor
connect to ground
#define time_set
PORTA,4 ;Hall-effect, externally
pulled-up
#define prev_flag flags,0
#define mode_bit flags,3
;1=analog, default=digital
;-----MESSAGE------
#define MAX_VAL
d'194' ;# cols in message minus 4
(-4? why? it works!)
#define CNT_VAL
d'30' ;# cols displayed in message
at any time
#define CT2_VAL
d'253' ;scroll rate: smaller=slower
org 0x00
goto Start
;---INTERRUPT ROUTINE--------------------------
org
0x04
;interrupt vector
Int movwf
safe_w ;save w
swapf
STATUS,w ;swap status, w
movwf
safe_s ;save
status(nibble swap, remember)
test_mode
movf mode,f
btfsc STATUS,Z
goto digital
;mode=0
movlw d'1'
xorwf mode,w
btfsc STATUS,Z
goto analog
;if mode = 1
goto message
;else mode = 2
;--------------------------------
;ANALOG---main time keeping code
;--------------------------------
analog incfsz DIVISOR1,1
goto exit
movlw
divisor1_val ;reset DIVISOR1 every time it rolls over
movwf DIVISOR1
incfsz DIVISOR2,1
goto exit
movlw
divisor2_val ;reset DIVISOR2 each time it rolls
movwf DIVISOR2
movlw
nths_adj_div2 ;adj-roll later (plus)
subwf DIVISOR1,1
decf DSEC,1
;decrement: reverses direction of display
incfsz ZSEC,1
goto exit
movlw zsec_val
;reset ZSEC when it rolls
movwf ZSEC
movlw
nths_adj_zsec ;earlier (minus)
addwf DIVISOR1,1
decf DMIN,1
incfsz ZMIN,1
goto exit
movlw zmin_val
;reset ZMIN when it rolls
movwf ZMIN
movlw nths_adj_zmin
subwf DIVISOR1,1
;later (plus)
decf DHOUR,1
exit
;start setting hands on the clock based on time in the
registers
;seconds--------
movlw
b'11111111' ;make all outputs high
movwf PORTB
;to turn off all the LEDs
movf PERIOD,W
;some junk is here to fix problem
movwf TEMP
;where hands turn off when PERIOD_CNT is 0
movlw d'2'
subwf TEMP,1
;TEMP=PERIOD-2
movf DSEC,W
movwf mulcnd
call mpy_F
;do the math->PERIOD x time
movf H_byte,W
;if H_byte>PERIOD-2 and
subwf TEMP,W
btfsc STATUS,C
goto ng
movf
PERIOD_CNT,1 ;if PERIOD_CNT=0 turn on LED
btfsc STATUS,Z
goto sec_on
ng movf
PERIOD_CNT,W ;divide result by 256 then compare to
PERIOD_CNT
xorwf H_byte,W
btfsc STATUS,Z
sec_on bcf PORTB,6
;minutes-------------------------
movf DMIN,W
movwf mulcnd
call mpy_F
movf H_byte,W
;if H_byte>PERIOD-2 and
subwf TEMP,W
btfsc STATUS,C
goto ngm
movf
PERIOD_CNT,1 ;if PERIOD_CNT=0 turn on LEDs
btfsc STATUS,Z
goto min_on
ngm movf PERIOD_CNT,W
xorwf H_byte,W
btfss STATUS,Z
;defacto divide by 256 then compare to PERIOD_CNT
goto skipm
min_on bcf
PORTB,0 ;light up the minute hand
bcf PORTB,5
bcf PORTB,7
bcf PORTB,1
bcf PORTB,2
bcf PORTB,3
skipm
;skipped to here means no turn on
;hours-------------------------
movf DHOUR,W
movwf mulcnd
call mpy_F
movf H_byte,W
;if H_byte>PERIOD-2 and
subwf TEMP,W
;if PERIOD_CNT=0 turn on
btfsc STATUS,C
goto ngh
movf PERIOD_CNT,1
btfsc STATUS,Z
goto hour_on
ngh movf PERIOD_CNT,W
xorwf H_byte,W
btfss STATUS,Z
;defacto divide by 256 then compare to PERIOD_CNT
goto skiph
hour_on bcf PORTB,1
bcf PORTB,2
bcf PORTB,3
bcf PORTB,5
skiph goto end_int
;-----------------------------
;--DIGITAL--------------------
;-----------------------------
digital
; ?????????? interrupts every minute. Increment the bigtick each time.
incf bigtick_lo,f
btfsc STATUS,Z
incf bigtick_hi,f
btfsc STATUS,Z
incfsz bigtick_dbl,f
goto Bigtick_out
;--------
; here? bigtick has rolled over to zero and one minute has passed.
; reload bigtick and set a flag for the main counter
;--------
movlw
0xf7
;these timings for no prescale
movwf bigtick_dbl ;and 10Mhz crystal
movlw 0x0c ;corrected
for observed error
movwf bigtick_hi
movlw 0xf8
movwf bigtick_lo
bsf
flags,1 ;notify
Keep_time
incfsz
ADJUST ;make correction every 256
minutes
goto Bigtick_out
movlw d'243'
subwf
bigtick_lo,f
Bigtick_out goto end_int
;--------------------
;---message----------
;--------------------
message incfsz
CT1,1
goto end_int
incfsz CT2,1
goto end_int
movlw
CT2_VAL ;these counters cause
action
movwf
CT2 ;to occur after set # ints
;controls scroll rate
incf
OFFSET,1 ;OFFSET is the counter that
;controls scrolling-indexes
;through message
movf MAX,w
xorwf
OFFSET,w
btfss
STATUS,Z ;if OFFSET=MAX
goto
end_int ;clear OFFSET
clrf
OFFSET ;now at end of message, so
reset to beginning
goto end_int
;restore and return--
end_int btfsc
flags,4 ;increment PERIOD_CNT only
every other
goto
clear_flag ;interrupt. Since hand position can only
incf
PERIOD_CNT,1 ;be determined to the nearest interrupt,
bsf
flags,4 ;this produces less hand
jitter than using
goto
go_there ;tmr0 prescale of 2x
clear_flag
bcf
flags,4 ;flags,4 is toggled each
interrupt
go_there
clrwdt
swapf safe_s,w
;fetch status, reswap nibbles
movwf
STATUS ;restore
status
swapf safe_w,f
;swap nibbles in preparation
swapf safe_w,w
;for the swap restoration of w
bcf
INTCON,2 ;clear interrupt
flag before
return
retfie
;return from interrupt
;*******************************************************************
;Time, whether sec, min, or hour is kept as a value between 0 to
255.
;To scale the time in order to compare to the current value of
PERIOD_CNT,
;multiply time*PERIOD and divide by 256, which is just the high
;byte of time*PERIOD result
; ( Fast Version
: Straight Line Code )
; Before calling the subroutine " mpy_F ", the multiplier is PERIOD
; multiplicand is " mulcnd " . The 16 bit result is stored in locations
; H_byte & L_byte.
;*******************************************************************
;**** Define a macro for adding & right shifting
**
mult MACRO
bit
; Begin macro
btfsc PERIOD,bit
addwf H_byte,1
rrf H_byte,1
rrf L_byte,1
ENDM
; End of macro
;
*****************************
Begin Multiplier Routine
mpy_F clrf H_byte
clrf L_byte
movf
mulcnd,W ; move the
multiplicand to W reg.
bcf
STATUS,C ; Clear the carry
bit in the status Reg.
mult 0
mult 1
mult 2
mult 3
mult 4
mult 5
mult 6
mult 7
retlw 0
;--initialize all RAM-digital and analog---------------------
;
Ram_init ;***digital*****
movlw
0x12
;why do clocks always start
movwf
hours ;at
12:00 ?
clrf minutes
clrf dot_index
clrf digit_index
movlw 0xFB
movwf bigtick_dbl
movlw d'5'
movwf COUNTER2
;****analog*******
movlw
divisor1_val ;initialize DIVISOR1
movwf DIVISOR1
movlw
divisor2_val ;initialize DIVISOR2
movwf DIVISOR2
movlw
zsec_val ;and other timekeeping
movwf
ZSEC ;counters
movlw zmin_val
movwf ZMIN
movlw
offset_val ;initialize to start all hands at 12:00
movwf DHOUR
movwf DSEC
movwf DMIN
;******message******
movlw
d'245' ;control scroll speed- smaller=slower
movwf CT2
movlw
MAX_VAL ;must not be greater than # lines in
movwf
MAX ;message table
clrf OFFSET
clrf CNT
;****common*****
clrf mode
retlw 0
;-----------------------------------
Port_init movlw
b'00010000' ;all but bit 4 are output
tris
PORTB
;portb 4 is index sensor
movlw b'00010000' ;porta 4 is
timeset
tris
PORTA
retlw 0
;-----------------------------------
Timer_init bcf
INTCON,2 ;clear TMR0 int flag
bsf
INTCON,7 ;enable global
interrupts
bsf
INTCON,5 ;enable TMR0 int
clrf
TMR0
;clear timer
clrwdt
;why is this needed? just do
it..
movlw b'01011000' ;set up
timer. no prescale
;portb pullups enabled
option
;send w to option. generate
warning.
clrf
TMR0
;start timer
retlw 0
;------------------------------------
org 100
;---------------------------------------
;Check_index- common to all modes
; Bob Blick's original code also
works. This method
; stabilizes period faster.
;--------------------------------------
Check_index bcf
flags,5 ;bit 5 is for message
btfss
in_bit
goto no_phase
btfsc prev_flag
goto cont
bsf prev_flag
movf
PERIOD_CNT,w ;make a working copy
movwf
period_dup ;called period dup
clrf
PERIOD_CNT ;a fresh start for next rotation
clrf
digit_index ;set to first digit
clrf dot_index
;first column
bsf flags,5
bcf
flags,4 ;clear period count toggle
bit. PERIOD_CNT
goto
cont ;will be incremented on the
next interrupt
no_phase bcf prev_flag
; calculate a period that does not dither or jitter
; period will not be changed unless new period is really different
cont movf
PERIOD,W
subwf
period_dup,W ;find difference
btfss
STATUS,C ;carry flag set means no borrow
goto
Calc_neg ;must be other way
sublw
2 ;allowable deviation = 3
btfss
STATUS,C ;borrow won't skip
incf
PERIOD ;new value much larger than
calc
retlw 0
Calc_neg addlw 2
;allowable deviation = 3
btfss
STATUS,C ;carry will skip
decf
PERIOD ;no carry means it must be
change
retlw 0
;-------------------
;set_analog for adjusting time
;-------------------
Set_analog
btfsc time_set
;input uses pull-up- normally set
retlw 0
;exit if no magnet near
decfsz COUNTER,1
;COUNTER used to take action only every 256 loops
retlw 0
;this slows down time setting
movlw offset_val
;reset seconds hand to 12:00 position
movwf DSEC
;to make it pretty
decf DMIN,1
;adjust time one minute
incfsz ZMIN,1
;this one goes the other way
retlw 0
;if ZMIN rolls, reset it and
decrement DHOUR
movlw zmin_val
movwf ZMIN
decf
DHOUR,1
retlw 0
;****************************************
;---Digital Code--subs below here
;****************************************
;--------
; CHARACTER LOOKUP TABLE
; ignore bit 4. set=LED off, clear=LED on
;-flipped digits upside down-pattern modified for my crazy LED wiring
Char_tbl
addwf PCL,f
dt 0x42
,0xAD ,0xAD ,0xAD
,0x42
dt 0xEF
,0xED ,0x0 ,0x6D
,0xEF
dt 0x6C
,0x8D ,0xA5 ,0xA9
,0x6D
dt 0xA3
,0xD ,0xAC ,0xAD
,0xAB
dt 0xE7
,0x0 ,0x67 ,0xE6
,0xC7
dt 0x83
,0xAC ,0xAC ,0xAC
,0x2A
dt 0xE3
,0x8D ,0x8D ,0x4D
,0xC2
dt 0x2F
,0xAE ,0x8F ,0xA1
,0xAF
dt 0x62
,0x8D ,0x8D ,0x8D
,0x62
dt 0x46
,0x8B ,0x8D ,0x8D
,0x6E
dt 0xEF
,0xEF ,0x62 ,0xEF
,0xEF
Char_tbl_end
;--------
; change LED pattern based on state of digit_index and dot_index
;--------
Display_now movlw 0x05
xorwf dot_index,w ;test for end of
digit
movlw
0xFF
;pattern for blank column
btfsc STATUS,Z
goto D_lookup_3 ;it
needs a blank
bcf
STATUS,C ;clear carry before
a rotate
rlf digit_index,w ;double the index
because each
bcf PCLATH,1
bsf PCLATH,0
addwf
PCL,f
;takes two instructions
D_1min
movf minutes,w ;DZ-reversed order
of display
goto D_lookup ;since my motor is
counterclockwise
D_10min
swapf minutes,w
goto D_lookup
D_colon
movlw 0x0A
goto D_lookup
D_1hr
movf hours,w
goto
D_lookup
D_10hr
swapf hours,w
goto
D_lookup
D_nothing retlw 0
D_lookup andlw
b'00001111' ;strip off hi bits
movwf
scratch ;multiply this
by 5 for lookup
addwf scratch,f ;table
base position
addwf scratch,f ;is
this cheating?
addwf scratch,f ;I
think not.
addwf scratch,f ;I
think it is conserving
energy!
btfss STATUS,Z
;test for zero
goto D_lookup_2 ;not a
zero
movlw
0x04 ;-DZ
changes- 10 hours is now digit 5
xorwf
digit_index,w ;-if digit 5 is 0, display blank
movlw
0xFF
;this makes a blank LED pattern
btfsc STATUS,Z
;test if it is 10 hrs digit
goto D_lookup_3 ;it's a
trailing zero
D_lookup_2 movf
dot_index,w ;get column
addwf scratch,w ;add it
to digit base
bcf
PCLATH,1 ;set to page 0x100 for lookup
bsf
PCLATH,0
call
Char_tbl ;get the dot pattern
for this
column
D_lookup_3 movwf
PORTB ;send
it to the LEDs
movf
PERIOD,w ;made delay longer than
original program
call
Delay
;width of digits with this delay
incf dot_index,f ;increment
to the next column
movlw
0x06
;6 columns is a digit plus space
xorwf dot_index,w ;next digit test
btfss STATUS,Z
retlw
0
;not a new digit
clrf dot_index
;new digit time
incf digit_index,f
retlw
0
;Display_now done.
;--------
; a short delay routine
;--------
Delay
movwf tick
Delay_loop
nop
;added NOPs to
increase delay
nop
;to make really wide display
nop
nop
decfsz tick,f
goto Delay_loop ;w is
not damaged, so Delay can
return
;be recalled without reloading
;--------
; test for magnet and adjust time if needed
;--------
Set_digital btfsc
time_set ;input uses pull-up- normally set
retlw
0 ;exit if no magnet near
decfsz
COUNTER,1 ;COUNTER used to take action only every 256
loops
retlw
0 ;this slows down time setting
decfsz
COUNTER2,1 ;COUNTER2 slows things even more
retlw
0
movlw
d'8' ;adjust to suit for setting
speed
movwf
COUNTER2 ;reset COUNTER2 when it rolls
call
Inc_mins ;got to here, now adjust time
retlw 0
;--------
; increment one hour
;--------
Inc_hours movlw 0x12
xorwf hours,w
btfsc STATUS,Z
goto Inc_hours_12
movlw
0x07
;this part gets a little sloppy
addwf hours,w
movlw 0x07
btfss STATUS,DC
movlw 1
addwf hours,f
retlw 0
Inc_hours_12 movlw 0x01
movwf hours
retlw 0
;--------
; increment the time based on flags,1 as sent by interrupt routine
; Inc_mins also used by time setting routine
;--------
Keep_time btfss
flags,1 ;the minutes
flag
retlw
0
;not this time
bcf
flags,1 ;clear the
minutes flag
Inc_mins movlw
0x07
;start incrementing time
addwf minutes,w ;add 7
minutes into w
btfsc STATUS,DC ;did
adding 7 cause digit carry?
goto Sixty_mins ;then
test for an hour change
incf
minutes ;otherwise add
1 for real
retlw
0
;and go back
Sixty_mins movwf
minutes ;save the
minutes
movlw
0x60
;test for 60
xorwf minutes,w ;are
minutes at 60?
btfss STATUS,Z
retlw
0
;no? go back
clrf
minutes ;otherwise zero
minutes
goto Inc_hours
;and increment hours
;--------------------
;message stuff
;
;bit mapped data table generated using BASIC program
;--------------------
org 0x200
mess_data
addwf PCL,f
dt 0xEF ;blank
dt 0xEF ;blank
dt 0xEF ;blank
dt 0xEB ;image of
christmas tree 13 columns
dt 0xE3
dt 0xC3
dt 0xC2
dt 0x40
dt 0x00
dt 0x40
dt 0xC2
dt 0xC3
dt 0xE3
dt 0xEB
dt 0xEF
dt 0xEF
;"merry christmas from don pam and philip"
;182 columns
dt 0x00,0x6F,0xEE,0x6F,0x00,0xEF
dt 0x00,0x8D,0x8D,0xAD,0xEF
dt 0x00,0x87,0x8B,0x6C,0xEF
dt 0x00,0x87,0x8B,0x6C,0xEF
dt 0x2F,0xEE,0xC1,0xEE,0x2F,0xEF
dt 0xEF
dt 0x42,0xAD,0xAD,0x6B,0xEF
dt 0x00,0xCF,0xCF,0xCF,0x00,0xEF
dt 0x00,0x87,0x8B,0x6C,0xEF
dt 0xAD,0x00,0xAD,0xEF
dt 0x6A,0x8D,0x8D,0x63,0xEF
dt 0xAF,0xAF,0x00,0xAF,0xAF,0xEF
dt 0x00,0x6F,0xEE,0x6F,0x00,0xEF
dt 0x40,0x8F,0x8F,0x40,0xEF
dt 0x6A,0x8D,0x8D,0x63,0xEF
dt 0xEF
dt 0x00,0x8F,0x8F,0xAF,0xEF
dt 0x00,0x87,0x8B,0x6C,0xEF
dt 0x42,0xAD,0xAD,0x42,0xEF
dt 0x00,0x6F,0xEE,0x6F,0x00,0xEF
dt 0xEF
dt 0x00,0xAD,0xAD,0x42,0xEF
dt 0x42,0xAD,0xAD,0x42,0xEF
dt 0x00,0x6F,0xCE,0xE7,0x00,0xEF
dt 0xEF
dt 0xEF
dt 0x00,0x8F,0x8F,0x6E,0xEF
dt 0x40,0x8F,0x8F,0x40,0xEF
dt 0x00,0x6F,0xEE,0x6F,0x00,0xEF
dt 0xEF
dt 0x40,0x8F,0x8F,0x40,0xEF
dt 0x00,0x6F,0xCE,0xE7,0x00,0xEF
dt 0x00,0xAD,0xAD,0x42,0xEF
dt 0xEF
dt 0x00,0x8F,0x8F,0x6E,0xEF
dt 0x00,0xCF,0xCF,0xCF,0x00,0xEF
dt 0xAD,0x00,0xAD,0xEF
dt 0x00,0xED,0xED,0xED,0xEF
dt 0xAD,0x00,0xAD,0xEF
dt 0x00,0x8F,0x8F,0x6E,0xEF
;could add blanks to either end
;--------------
Message
top call Check_index
btfss flags,5
goto top
;wait until index occurs
loops movlw 0xFF
movwf PORTB
;turn everything off
movlw CNT_VAL
;if CNT==CNT_VAL, clear CNT and goto top
xorwf CNT,w
;CNT_VAL is # cols displayed at any time
btfss STATUS,Z
goto
cont_message ;else continue and display next column
clrf CNT
goto top
cont_message
movf OFFSET,w
;if offset>cnt
subwf CNT,w
btfss STATUS,C
goto no_wrap
;goto no_wrap
goto wrap
;else wrap
no_wrap movf CNT,w
subwf OFFSET,w
;W=OFFSET-CNT
goto look
wrap subwf MAX,w
;w=MAX-(CNT-OFFSET)
look bcf PCLATH,0
;lookup at page 0x200
bsf PCLATH,1
call mess_data
;lookup bit pattern in table
movwf PORTB
;and send to LEDs
movlw d'100'
call Delay
;leave "ON" for a while
call Delay
incf CNT,f
;get next column to display
goto loops
retlw 0
;can't ever get here- endless loop
;--------------------
; Program starts here
;--------------------
Start
call
Ram_init ;set variables to
nice values
call Port_init
;set port directions
read_ee bcf
STATUS,RP0 ;EEPROM read from
movlw
0x00 ;first location
movwf EEADR
bsf STATUS,RP0
bsf EECON1,RD
bcf STATUS,RP0
test_m movf
EEDATA,f ;read EEPROM and test mode
btfsc STATUS,Z
goto
zero ;mode=0
movlw d'1'
xorwf EEDATA,w
btfsc STATUS,Z
goto
one ;mode = 1
goto
two ;else mode = 2
zero movf
EEDATA,w
movwf
mode ;set mode to 0
movlw
0x01 ;write 1 for next time
call write_ee
goto
run_dig ;start machine in digital
mode
one movf EEDATA,w
movwf mode
movlw 0x02
call write_ee
goto
run_ana ;start machine in analog
mode
two movf EEDATA,w
movwf mode
movlw 0x00
call write_ee
goto
run_mess ;start machine in message mode
;---write_ee-------------
write_ee movwf EEDATA
movlw
0x00 ;
movwf
EEADR ;
bsf
STATUS,RP0 ;bank 1
bcf
INTCON,GIE ;don't need
bsf
EECON1,WREN ;write enable
movlw
0x55 ;mchip required section
movwf
EECON2 ;""
movlw
0xAA ;""
movwf
EECON2 ;""
bsf
EECON1,WR ;""
bsf
INTCON,GIE ;don't need
write_wait btfsc
EECON1,WR ;wait for finish writing
goto write_wait
bcf
STATUS,RP0 ;back to bank 0
call
Timer_init ;start timer based interrupt
retlw 0
;--------------
run_ana
Analog_circle call
Check_index
call Set_analog
goto
Analog_circle
run_dig
Digital_circle call Check_index
call Display_now
call Set_digital
call Keep_time
goto Digital_circle
run_mess call Message
end