;MOTOR1.ASM
;Este programa recibe una orden x PB y hace girar un motor a pasos.
;Se requiere que este dormido el PIC en periodos de inactividad.
;Se despierta cuando recibe seņal x PB y hace girar al motor x PA.
;
;       Programa:          	MOTOR1.ASM
;       Fecha de elaboracion:	22-XII-03    por Ricardo R. Horta O.
;*******************************************************************


		LIST		P=16F84
		RADIX		HEX
		INCLUDE		"p16f84.inc"	;Define etiquetas.
		;Switches de Configuration: 
		__CONFIG _PWRTE_ON & _LP_OSC & _WDT_OFF
;
CONT		equ		0xc	;Dir. de Registros.
seņal		equ		0xd
tiempo		equ		0xe
giros		equ		0xf
sentido		equ		0x10
VUELTA		equ		0x11
;
#define		BANCO_0		bcf	STATUS,RP0	;Al Banco 0
#define		BANCO_1		bsf	STATUS,RP0	;Al Banco 1
;
		org     0
		goto    rrho		;Vector de Reset.
;
		org     4
		goto    bionica		;Vector de interrupcion.
;
		org	6		;Inicio de Instrucciones, rrho.
;********************* PROGRAMA PRINCIPAL **************************
rrho
		BANCO_1
		movlw   B'11000101'     ;Sin RBPU, INTEDG=1 (/),
		movwf   OPTION_REG	;Rj int.,TMR0 en/<=PSA,1:256
		clrf	TRISA		;TRISA<=00, PA como salida.
		movlw	0xff		;W<=FFh.
		movwf	TRISB		;TRISB<=W, PB como entrada.

		BANCO_0
		movlw	0x0
		movwf	giros		;giros<=0
		movwf	sentido		;sentido<=0
		movlw	0xa
		movwf	tiempo		;tiempo<=Ah
loop		call    PreparaPAB  	;inicializa PA y PB.
		call	refresca	;Refresca bandera RBIF.
        	sleep                   ;Duerme y despierta x seņal.
		nop
		call	gira
		goto    loop		;regresa a dormir.

;<<<<<<<<<<<<<<<<<< PROGRAMA DE INTERRUPCION >>>>>>>>>>>>>>>>>>>>>>>
;Busca seņal externa. Coloca en SEŅAL<=PB. Determina cual seņal es.
;De ser SDV (x PB7), carga en "giros" y "tiempo" el valor recibido 
;x PB0-PB3. Ejecuta tantas vueltas en el motor como "giros",
;si no hay otra interrupcion, y para.

bionica
		bcf	INTCON,GIE	;GIE<=0.
		btfss   INTCON,RBIF     ;Si RBIF=1 brinca.
		goto	vuelve		;No hay Int x PB.
		bcf	INTCON,RBIE	;RBIE<=0

sdv		movf	PORTB,W		;W<=PORTB
		btfss	PORTB,7		;Brinca si RB7=1
		goto	temp
		andlw   B'00001111'     ;W<=W&0F.
		btfsc	STATUS,Z	;brinca si Z=0
		goto	vuelve
		movwf	seņal		;seņal<=W
		movlw	0x0d		;W<=0Dh
		subwf	seņal,0		;W<=seņal-W
		btfsc	STATUS,Z	;Si Z=1 fue tecla D.
		goto	fue_d		;sentido<=00 a la Der.
		movlw	0x0c
		subwf	seņal,0
		btfsc	STATUS,Z	;Si Z=1 fue tecla C.
		goto	fue_c
		movf	seņal,0		;W<=seņal
		movwf	giros		;giros<=W


vuelve		movf	PORTB,W		;W<=PORTB
		andlw	B'11110000'	;W<=W&F0
		btfss	STATUS,Z	;Brinca si W=0
		goto	vuelve		;Vuelve hasta q' no haya seņal.
		call	refresca	;Refresca bandera RBIF.
		bcf     INTCON,T0IE     ;Quita permiso de Int.xTMR0.
		bcf     INTCON,T0IF     ;Quita bandera de Int.xTMR0.
		retfie

temp		btfss	PORTB,6		;Brinca si RB6=1
		goto	es_RB5
		andlw   B'00001111'     ;W<=W&0F.
		btfss	STATUS,Z	;brinca si Z=1
		movwf	tiempo		;tiempo<=W
		goto	vuelve

es_RB5		btfss	PORTB,5		;Brinca si RB5=1
		goto	es_RB4
		andlw   B'00001111'     ;W<=W&0F.
		btfss	STATUS,Z	;brinca si Z=1
		goto	vuelve		;Z=1
		goto	vuelve

es_RB4		btfss	PORTB,4		;Brinca si RB5=1
		goto	vuelve
		andlw   B'00001111'     ;W<=W&0F.
		btfss	STATUS,Z	;brinca si Z=1
		goto	vuelve		;Z=1
		goto	vuelve

fue_d		clrf	sentido
		goto	vuelve

fue_c		bsf	sentido,0
		goto	vuelve

;+++++++++++++++++++++++++++ PREPARAPAB +++++++++++++++++++++++++++++
;Esta sub-rutina prepara PB0-PB7 como entradas, CONT=00h
;y el PA como salidas, habilita Int. x RBIE y GIE.
PreparaPAB
		movlw	0x00
		movwf	PORTA		;PA<=00.
		movwf	CONT		;CONT<=00
		movwf	giros		;giros<=00
		movlw	0x1
		movwf	VUELTA		;VUELTA<=1
		retfie                 	;GIE=1 y regresa.

;+++++++++++++++++++++++++++ REFRESCA ++++++++++++++++++++++++++++++
;Refresca la bandera de interrupcion RBIF.
refresca
		bcf	INTCON,RBIE	;RBIE<=0.
		movf	PORTB,W		;W<=PORTB, refresca.
		bcf	INTCON,RBIF	;RBIF<=0.
		bsf	INTCON,RBIE	;RBIE<=1.
		
		return

;+++++++++++++++++++++++++++ RETARDO +++++++++++++++++++++++++++++++
;Esta sub-rutina espera un tiempo usando las Int. del TMR0.
retardo
		bcf	INTCON,GIE	;GIE<=0
		movf	tiempo,W	;W<=tiempo
		movwf	CONT		;CONT<=W
		clrf	TMR0		;TMR0<=00 e inicia conteo.
		bsf     INTCON,T0IE     ;Habilita Int. x TMR0
reretardo	bcf     INTCON,T0IF     ;Quita bandera, TOIF<=0.
revisa_TMR0	btfss   INTCON,T0IF     ;TMR0 sobregirado?
		goto    revisa_TMR0	;NO, revisa otra vez.
		decfsz	CONT,F		;Salta si CONT<=CONT-1=0.
		goto	reretardo
		bcf     INTCON,T0IE     ;SI, quita Int. x TMR0.
		bcf     INTCON,T0IF	;Quita bandera, TOIF<=0.
		retfie

;<<<<<<<<<<<<<<<<<<<<<<<<<<<< GIRA >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
;Con tiempo=1 cada vuelta tarda 0.75 seg. aprox.
gira		movf	giros,W		;W<=giros
		addwf	VUELTA,F	;VUELTA<=VUELTA+W	
otra		decfsz	VUELTA,F	;VUELTA<=VUELTA-1,Salta si=0
		goto	de_nuez
		return
de_nuez		call 	grados		;30° de giro.
		call 	grados		;30° de giro.
		call 	grados		;30° de giro.
		call 	grados		;30° de giro.
		call 	grados		;30° de giro.
		call 	grados		;30° de giro.
		call 	grados		;30° de giro.
		call 	grados		;30° de giro.
		call 	grados		;30° de giro.
		call 	grados		;30° de giro.
		call 	grados		;30° de giro.
		call 	grados		;30° de giro.
		goto	otra
;::::::::::::::::::::::::::: GRADOS :::::::::::::::::::::::::::::::
grados
		movlw	0xc		;W<=paso 1Der/1Izq.
		movwf	PORTA		;PORTA<=W.
		call	retardo		;Espera
		clrw			;W<=00
		iorwf	sentido,F	;sentido<=sentido+00
		btfss	STATUS,Z	;Si Z=1 gira a la der.
		goto	paso_2Izq
paso_4Izq	movlw	0xd		;W<=paso 2Der/4Izq.
		movwf	PORTA		;PORTA<=W.
		call	retardo		;Espera
		clrw			;W<=00
		iorwf	sentido,F	;sentido<=sentido+00
		btfss	STATUS,Z	;Si Z=1 gira a la der.
		goto	fin_ciclo
paso_3Izq	movlw	0xf		;W<=paso 3Der/3Izq.
		movwf	PORTA		;PORTA<=W.
		call	retardo		;Espera
		clrw			;W<=00
		iorwf	sentido,F	;sentido<=sentido+00
		btfss	STATUS,Z	;Si Z=1 gira a la der.
		goto	paso_4Izq
paso_2Izq	movlw	0xe		;W<=paso 4Der/2Izq.
		movwf	PORTA		;PORTA<=W.
		call	retardo		;Espera
		clrw			;W<=00
		iorwf	sentido,F	;sentido<=sentido+00
		btfss	STATUS,Z	;Si Z=1 gira a la der.
		goto	paso_3Izq

fin_ciclo	return

		end
