; ------------------------------------------------------------------------
;
; Title:
;
;   PD62 -- PIC 10 MHz to 1 Hz quartz clock stepper motor driver
;
; Function:
;
;   This PIC program implements a digital frequency divider and stepper
;   motor driver for use with common AA-battery quartz movements.
;   The external 10 MHz input clock is divided to 1 Hz and the coil is
;   pulsed once a second, alternating polarity every second.
;
;   The clock time will be as accurate as the 10 MHz reference.
;
; Diagram:
;                                ---__---
;              2-5V (Vdd)  +++++|1      8|=====  Ground (Vss)
;                  10 MHz  ---->|2  pD  7|z--->  -\/\/\- coil
;                              -|3  62  6|z--->  -\/\/\- coil
;                              o|4      5|-
;                                --------
; Notes:
;
;   PIC voltage is 2.0-5.5V (sorry, 1.5 V won't work).
;   Output drive current is 25 mA maximum per pin.
;   Current limiting resistors on coil may be required (e.g., 220R).
;   o Tie unused input pin4/GP3 to Vdd or Vss.
;   Coded for Microchip 12F675 but any '609 '615 '629 '635 '675 '683 works.
;
; Version:
;
;   24-Oct-2010  Tom Van Baak (tvb)  www.LeapSecond.com/pic
;
; ------------------------------------------------------------------------

; Microchip MPLAB IDE assembler code (mpasm).

        list        p=pic12f675
        include     p12f675.inc
        __config    _EC_OSC & _MCLRE_OFF & _WDT_OFF

; Register definitions.

        cblock  0x20            ; define register base
        endc

; One-time PIC 12F675 initialization.

        org     0               ;
        bcf     STATUS,RP0      ; bank 0
        movlw   07h             ; set mode to turn
        movwf   CMCON           ;   comparator off
        bsf     STATUS,RP0      ; bank 1
        clrf    ANSEL-0x80      ; set digital IO (no analog A/D)
        bcf     STATUS,RP0      ; bank 0

; Alternate positive and negative pulse polarity each second.
; The two code blocks below have been designed to use exactly 2,500,000
; instructions each, which is 1.000000000 second at 10 MHz.

even:   movlw   b'01'           ; coil -+
        movwf   GPIO            ;
        call    pulse           ;
        goto    odd             ;

odd:    movlw   b'10'           ; coil +-
        movwf   GPIO            ;
        call    pulse           ;
        goto    even            ;

; With polarity already set, generate short pulse to stepper motor.
; - Adjust the pulse width for best results with your stepper.
; - The sum of pulse on and pulse off delay calls below is 999 ms.
; - The code below uses a 27 ms on pulse.

pulse:  call    lowz            ; pulse on
        call    Delay20ms
        call    Delay5ms
        call    Delay2ms

        call    highz           ; pulse off
        call    Delay2ms
        call    Delay20ms
        call    Delay50ms
        call    Delay200ms
        call    Delay200ms
        call    Delay500ms

        ; Delay final partial 1 ms for exact 1 s period (use MPLAB SIM).
        movlw   d'24'           ;
        call    DelayW100       ; delay W*100
        movlw   d'74'           ;
        call    DelayW1         ; delay (15 <= W <= 255)
        return

; Activate both output pins.

        errorlevel -302
lowz:   bsf     STATUS,RP0      ; bank 1
        movlw   b'111100'       ; set GP1,GP0 as output(0)
        movwf   TRISIO          ;
        bcf     STATUS,RP0      ; bank 0
        return

; Deactivate output pins (by changing both to inputs).

highz:  bsf     STATUS,RP0      ; bank 1
        movlw   b'111111'       ; set GP1,GP0 as input(1)
        movwf   TRISIO          ;
        bcf     STATUS,RP0      ; bank 0
        return
        errorlevel +302

        include delay10.asm     ; precise millisecond delay functions
        end
