;;==========================================================;;
;; hand clock with fast and stop mode ;;
;;==========================================================;;
;; ;;
;; Program: Hclock -- Hand clock module ;;
;; Code: Jindra Fucik ;;
;; Platform: Microchip PIC12F629, 32768 Hz ;;
;; Date: 04.06.2013 ;;
;; First release: 04.06.2013 ;;
;; LastDate: 04.06.2013 ;;
;; ;;
;;==========================================================;;
; Minimal external components, uses external xtall at 32768 Hz
; (re-used from clock movement :))
; This program is distributed as is but WITHOUT ANY WARRANTY
; I hope you enjoy!!
;
; Revisions:
; 04.06.2013 Start of writting code
; ----- Definitions
#define __VERNUM D'1'
#define __VERDAY 0x04
#define __VERMONTH 0x06
#define __VERYEAR 0x13
LIST p=12F629 ; target processor
; errorlevel -305 ; Using default destination of 1 (file).
errorlevel -302 ; Register in operand not in bank 0. Ensure that bank bits are correct.
#include p12F629.inc
__CONFIG _BODEN_OFF & _CP_OFF & _WDT_OFF & _MCLRE_OFF & _PWRTE_ON & _LP_OSC
; Make sure that internal osc. is calibrated (although not used)
; Value has to be read before reprogramming the device.
; Hardware
; +-----------+
; +3V -|Vdd U Vss|- GND
; |-68-100pf+32768xtall -|OSC1 GP0|- Fast
; |-68-100pf+32768xtall -|OSC2 GP1|- Out1 -47R--+mot--|<--| 1N5819
; o-pull-up---Stop -|GP3 GP2|- Out2 -47R--+mot--|<--| 1N5819
; +-----------+
; 68-100pF for LP osc (less than 37kHz)
; --- Macros
#define DNOP goto $+1
; --- Constant values
FXTAL equ D'32768'
GP_TRIS equ 0x09 ; GP0,GP3: inputs
GP_INI equ 0x00 ; all zero
OPTION_INI equ b'00001000' ; Option register: pull-up, falling GP2,no prescaler 1:1 (1:4)
WPU_INI equ 0x01 ; Weak pull-up enable for GP0.
INTC_INI equ 0x00 ; disable interrupts
PIE1_INI equ 0x00 ; no interrupts
#define SW_FAST GPIO,0 ; switch to fast mode
#define OUT_A GPIO,1 ; motor out A
#define OUT_B GPIO,2 ; motor out 2
#define SW_STOP GPIO,3 ; switch to stop (GPIO,3 only input)
#define ENERGISE_TIME 0x20
; --- EEPROM Section
#define EE_INI 0x00
cblock EE_INI
EE_FCLK ; Fast clock divider
; the value used when fast mode is active
endc
; ----- Variables
; --- Internal RAM Section
#define RAMINI0 0x020 ; 64 bytes
cblock RAMINI0
FCLK ; Value for fast clock see description at end
CLKCNT ; counter of time ticks
POLARITY ; used for polarity (even/odd second)
ECNT ; counter for energize of coil
endc
; --------------- Program Section --------------------------------------
org 0x000
PowerUp:
clrf STATUS ; Bank 0 default
clrf INTCON ; Disable all interrupts
clrf PCLATH ; tables on page 0
goto INIT
; ----------------------------------------------------------------------
org 0x004
Interrupt: ; not used...
;movwf INT_W ; save context registers ;1
;swapf STATUS,w ;2
;movwf INT_STAT ;3
;clrf STATUS ; interrupt uses bank 0 ;4
EndInt:
;swapf INT_STAT,w ; restore context registers ;49 ;34
;movwf STATUS ;50 ;35
;swapf INT_W,f ;51 ;36
;swapf INT_W,w ;52 ;37
;retfie ;53,54 ;38,39
; ----------------------------------------------------------------------
INIT:
clrf GPIO
movlw 0x07
movwf CMCON ; set GP2:0 to digital I/O
bsf STATUS,RP0 ; bank 1
movlw GP_TRIS
movwf TRISIO
;call 0x3FF ; get OSCCAL value
;movwf OSCCAL
movlw WPU_INI ; pull-ups
movwf WPU
clrf IOC ; interrupt on change
clrf VRCON ; voltage reference off
movlw OPTION_INI ; Option register: no pull-up, falling GP2, no prescaler, wdt 1:1
movwf OPTION_REG
movlw PIE1_INI
movwf PIE1
bcf STATUS,RP0 ; bank 0
clrf PIR1
movlw 0x00 ; Timer 1 off, 1:1
movwf T1CON
movlw 0x20 ; clear RAM
movwf FSR
ClearRAM:
clrf INDF
incf FSR,f
movlw 0x60
xorwf FSR,w
btfss STATUS,Z
goto ClearRAM
movlw INTC_INI
movwf INTCON
movlw EE_FCLK ; read saved FCLK value
call EE_Read
movwf FCLK
clrf TMR0
bcf INTCON,T0IF
clrf CLKCNT
; ----------------------------------------------------------------------
MainLoop:
btfss INTCON,T0IF
goto MainLoop
bcf INTCON,T0IF
incf CLKCNT,f
btfss SW_STOP ; if STOP switch is active,
clrf CLKCNT ; clear counter every time
btfsc SW_FAST ; if fast button is not pressed
goto NormalTime ; calculate only normal time
movf FCLK,w
xorwf CLKCNT,w
btfsc STATUS,Z ; if FCLK and CLKCNT are the same
goto SendPulse
NormalTime:
movf CLKCNT,w
andlw 0xE0 ; bits 7,6,5
btfsc STATUS,Z ; if CLKCNT>=32
goto MainLoop
SendPulse:
incf POLARITY,f
clrf CLKCNT
btfss POLARITY,0
goto SendPulseB
SendPulseA:
bsf OUT_A
goto SendPulseE
SendPulseB:
bsf OUT_B
;goto SendPulseE
SendPulseE:
movlw ENERGISE_TIME
movwf ECNT
SendPulseLoop:
decfsz ECNT,f
goto SendPulseLoop
bcf OUT_A
bcf OUT_B
goto MainLoop
;---------------------------------------------------------------------------
EE_Read:
bsf STATUS,RP0 ; w=ADR
movwf EEADR
bsf EECON1,RD
movf EEDATA,w
bcf STATUS,RP0
return
; ----- EEPROM default values
org 0x2100
; TMR0 = clock / 4 = 32768 / 4 = 8192
; TMR0 over = 256 ~ 8192 / 256 = 32
; 32 times TMR0 over = 1 sec
; 8 times TMR0 = 4x faster
; 6 times TMR0 =5.333x normal clock
; 5 times TMR0 =6.4x normal clock
dw 0x08 ; fast clock counter - 5=6.4x normal clock 6=5.333x normal clock
;dw 0x06 ; fast clock counter - 5=6.4x normal clock 6=5.333x normal clock
;dw 0x05 ; fast clock counter - 5=6.4x normal clock 6=5.333x normal clock
org 0x2120
dt "FastClck"
dt " ver. ",(__VERNUM & 0x0F)+0x30," "
dt "J.Fucik "
dt (__VERDAY >> 4) +0x30
dt (__VERDAY & 0x0F)+0x30,"/"
dt (__VERMONTH >> 4) +0x30
dt (__VERMONTH & 0x0F)+0x30,"/"
dt (__VERYEAR >> 4) +0x30
dt (__VERYEAR & 0x0F)+0x30
end