;********************************************************
;
;               Stepper Motor controller
;
;                    Author :Lowe, Ideas from Seiichi Inoue
;                http://www.massmind.org/images/www/hobby_elec/e_step.htm
;********************************************************

        list            p=pic16f84a
        include         p16f84a.inc
        __config _XT_OSC&_WDT_OFF& _PWRTE_ON&_CP_OFF
        errorlevel      -302    ;Eliminate bank warning

;****************  Label Definition  ********************
        cblock  h'0c'
mode                            ;Operation mode
                                ;0=stop 1=right 2=left
count1                          ;Wait counter
count2                          ;Wait counter(for 1msec)
        endc

rb0     equ     0               ;RB0 of PORTB
rb1     equ     1               ;RB1 of PORTB
rb2     equ     2               ;RB2 of PORTB
rb5     equ     5               ;RB5 of PORTB
rb7     equ     7               ;RB7 of PORTB

;****************  Program Start  ***********************
        org     0               ;Reset Vector
        goto    init		;1
        org     4               ;Interrupt Vector
        clrf    INTCON          ;Clear Interruption reg

;****************  Initial Process  *********************
init
        bsf     STATUS,RP0      ;Change to Bank1
        clrf    TRISA           ;Set PORTA all OUT
        movlw   b'00100111'     ;RB0,1,2.5=IN RB7=OUT(rb5 a teszt miatt out!)
        movwf   TRISB           ;Set PORTB
        movlw   b'10000000'     ;RBPU=1 Pull up not use
        movwf   OPTION_REG      ;Set OPTION_REG
        bcf     STATUS,RP0     ;Change to Bank0
        clrf    mode            ;Set mode = stop
        clrf    count1          ;Clear counter
        clrf    count2          ;Clear counter
        movlw   b'0000011'     ;Set PORTA initial value
        movwf   PORTA          ;Write PORTA
        bsf     PORTB,rb7       ;Set RB7 = 1
	;bcf	PORTB,rb5	;For testing !
        btfsc   PORTB,rb5       ;RB5 = 0 ?
        goto    $-1             ;No. Wait

start
;*************  Check switch condition  *****************
        btfsc   PORTB,rb1       ;RB1(stop key) = ON ?
        goto    check1          ;No. Next
        clrf    mode            ;Yes. Set stop mode
        goto    drive           ;No. Jump to motor drive
check1
        btfsc   PORTB,rb2       ;RB2(right key) = ON ?
        goto    check2          ;No. Next
        movlw   d'1'            ;Yes. Set right mode
        movwf   mode            ;Save mode
        goto    drive           ;No. Jump to motor drive
check2
        btfsc   PORTB,rb0       ;RB0(left key) = ON ?
        goto    drive           ;No. Jump to motor drive
        movlw   d'2'            ;Yes. Set left mode
        movwf   mode            ;Save mode

;********************  Motor drive  *********************
drive
        movf    mode,w          ;Read mode
        bz      start           ;mode = stop. Branch by zero
        bsf     PORTB,rb7       ;Set RB7 = 1
	;bcf	PORTB,rb5	;For testing !
        btfsc   PORTB,rb5       ;RB5 = 0 ?
        goto    $-1             ;No. Wait
        movlw   d'5'            ;Set loop count(5msec)
        movwf   count1          ;Save loop count
loop    call    timer           ;Wait 1msec
        decfsz  count1,f        ;count - 1 = 0 ?
        goto    loop            ;No. Continue
        bcf     PORTB,rb7       ;Set RB7 = 0
	;bsf	PORTB,rb5	;For testing !
        btfss   PORTB,rb5       ;RB5 = 1 ?
        goto    $-1             ;No. Wait
	movf	mode,w
	sublw	d'1'
	bnz	drive_l
drive_r
        movf    PORTA,w         ;Read PORTA
        sublw   b'000000011'    ;Check motor position
        bnz     drive1          ;Branch not zero
        movlw   b'00000101'     ;Set right data
        goto    drive_end       ;Jump to PORTA write
drive1
        movf	PORTA,w         ;Read PORTA
        sublw	b'00000101'	;Check motor position
	bnz	drive2		;Branch not zero
	movlw	b'00000110'	;Set right data
	goto	drive_end	;Jump to PORTA write
;-------
drive2
        movlw   b'00000011'     ;Set right data
        goto    drive_end       ;Jump to PORTA write

drive_l 
        movf	PORTA,w		;Read PORTA
	sublw	b'00000011'	;Check motor position
	bnz	drive3		;Branch not zero
	movlw	b'00000110'	;Set left data
        goto    drive_end       ;Jump to PORTA write
;-------
drive3
        movf    PORTA,w         ;Read PORTA
        sublw   b'000000110'    ;Check motor position
        bnz     drive4          ;Branch not zero
        movlw	b'00000101'	;Set left data
        goto    drive_end       ;Jump to PORTA write
drive4
        movlw   b'00000011'     ;Set left data
        goto    drive_end       ;Jump to PORTA write
;-------
drive_end
        movwf   PORTA           ;Write PORTA
        goto    start           ;Jump to start

;*************  1msec Timer Subroutine  *****************
timer
        ;return			;For testing !
	movlw   d'200'          ;Set loop count
        movwf   count2          ;Save loop count
tmlp    nop                     ;Time adjust
        nop                     ;Time adjust
        decfsz  count2,f        ;count - 1 = 0 ?
        goto    tmlp            ;No. Continue
        return                  ;Yes. Count end

;********************************************************
;             END of Stepper Motor controller
;********************************************************

        end


