;9UPmotor.asm
;WWW.MWFTR.COM/book.html
;Charles Kim
;This program is to:
;1. Control a Unipolar Stepper Motor
;2. Turn Forward then Reverse
;3. Motor Control Chip is ALLEGRO UCN5804 (for Unipolar Stepper control)
;
;
; HIGH-To-LOW PULSE output connected to RD7 
; DIRECTION output is connected to RD6 
;
; LED1 is connected to RD1   (RVS motion indication)
; LED0 is connected to RD0   (FWD motion indication)
;
;

;  ACTION  		PORTD
;
;  1 STEP FORWARD: set RD6 H   then   (H --> L) RD7
;  1 STEP REVERSE: set RD6 L   then  H --> L of RD7
;   To change the direction, RD7 must be in L state



        list P = 16F877

STATUS	EQU	0x03
CARRY	EQU	0x00
ZERO	EQU	0x02
TRISC	EQU	0x87
PORTC	EQU	0x07
TRISD	EQU	0x88
PORTD	EQU	0x08
IRX	EQU	0x03		;RC3 for IR receiver
MSB	EQU	0x07
ZERO	EQU	0x02
STEP	EQU	0x07
FR	EQU	0x06
LED1	EQU	0x01
LED0	EQU	0x00


;RAM arEA
       
	CBLOCK	0x20
		TIMEBLOCK
		Kount120us   ;Delay count (number of instr cycles for delay)
		Kount100us
		Kount1ms
		Kount10ms
		Kount200ms
		Kount1s
		Kount10s
		Kount1m
		first
		second
		third
		Bitcount	;data bit count
		Kount		;Delay count (number of instr cycles for delay)
		ADDRreg		;IR ADDRESS
		COMreg		;IR Command
		Pcount		;HIGH duration count
		ADcount
		CMcount
		Tcount
		ADDRtemp	;for ASCII conversion
		COMtemp
		ADDR1
		ADDR2
		COM1
		COM2
		ASCIIreg
	ENDC
	

;The Next 5 lines must be here
;because of bootloader arrangement
;Bootloader first execute the first 4 addresses
;then jump to the address what the execution directs 
;=========================================================
        org 	0x0000      	;line 1
	GOTO	START		;line 2 ($0000)
	NOP			;line 3 ($0001)
	NOP			;line 4 ($0002)
	NOP			;line 5 ($0003)
;======================================================
;start of the program from $0004
START	
	
	banksel	TRISC
; Port setting (1 for input and 0 for output)
; 0010 1000
	clrf	STATUS
	movlw	0x28
	movwf	TRISC
;RC3 - IRX Pin (IN)

	banksel	TRISD
	movlw	H'00'
	movwf	TRISD		;All ports are outputs
	
AGAIN	
	banksel	PORTD
	movlw	B'00000000'
	movwf	PORTD		;STOP Condition



FORWARDSTEP
	banksel	PORTD
	bsf	PORTD, FR	;forward
	bsf	PORTD, LED1	;forward indicator
	bcf	PORTD, LED0
	banksel	first
	movlw	H'14'
	movwf	first
fagain	call	PULSE
	decfsz	first
	goto	fagain
	banksel	PORTD
	movlw	B'00000000'
	movwf	PORTD
	
	call	delay1s
	call	delay1s
	call	delay1s

REVERSESTEP
	banksel	PORTD
	bcf	PORTD,LED1
	bsf	PORTD,LED0
	bcf	PORTD, FR	;Reverse
	banksel	second
	movlw	H'0A'
	movwf	second
ragain	call	PULSE
	decfsz	second
	goto	ragain
	banksel	PORTD
	movlw	B'00000000'
	movwf	PORTD
	
	call	delay1s
	call	delay1s
	call	delay1s

	goto	AGAIN

; subroutine PULSE
PULSE	
	banksel	PORTD
	bsf	PORTD, STEP	;RD7
	call	delay200ms
	banksel	PORTD
	bcf	PORTD, STEP
	call	delay200ms
	return
;
;==========================================================
;DELAY SUBROUTINES 


; 1 instruction cycle for 20MHz clock is 0.2 us
; Therefore 120 uS delay needs 600 instuction cycles
;  600 =199*3 +3 ---->Kount=199=0xC7
;  or  =198*3 +6 ---->Kount=198=0xC6
;  or  =197*3 +9 ---->Kount=197=0xC5

Delay120us
	banksel	Kount120us
	movlw	H'C5'		;D'197'
	movwf	Kount120us
R120us	decfsz	Kount120us
	goto	R120us
	return
;
;100us delay needs 500 instruction cycles
;  500 =166*3 +2 ---->Kount=166=0xA6
;  or  =165*3 +5 ---->Kount=165=0xA5
;  or  =164*3 +8 ---->Kount=164=0xA4
Delay100us
	banksel	Kount100us
	movlw	H'A4'
	movwf	Kount100us
R100us	decfsz	Kount100us
	goto	R100us
	return

;
;10ms delay
; call 100 times of 100 us delay  (with some time discrepancy)
Delay10ms 
	banksel	Kount10ms
	movlw	H'64'	;100
	movwf	Kount10ms
R10ms	call	delay100us
	decfsz	Kount10ms
	goto	R10ms
	return
;
Delay200ms
	banksel	Kount200ms
	movlw	H'14'
	movwf	Kount200ms
R200ms	call	delay10ms
	decfsz	Kount200ms
	goto	R200ms
	return
;
;
	
;1 sec delay
;call 100 times of 10ms delay
Delay1s
	banksel	Kount1s
	movlw	H'64'
	movwf	Kount1s
R1s	call	Delay10ms
	decfsz	Kount1s
	goto	R1s
	return
;
;
;10 s delay
;call 10 tiems of 1 s delay
Delay10s
	banksel	Kount10s
	movlw	H'0A'		;10
	movwf	Kount10s
R10s	call	Delay1s
	decfsz	Kount10s
	goto	R10s
	return
;
;1 min delay
;call	60 times of 1 sec delay
Delay1m
	banksel	Kount1m
	movlw	H'3C'	;60
	movwf	Kount1m
R1m	call	Delay1s
	decfsz	Kount1m
	goto	R1m
	return
;======================================================
;
;END OF CODE
        END

