;PRODUCIDO Y DISEÑADO POR BRUNO FASCENDINI(BRUNOF) EN RESPUESTA A PREGUNTA DEL FORO WWW.TODOPIC.COM.AR
;DUDAS Y SUGERENCIAS A brunodini@yahoo.com.ar ó badpaperboy@hotmail.com ó al FORO! QUE TANTAS VUELTAS! ;)
;calibrado para 4 mhz

		list	p=16f84
		#include <p16F84.inc>

		__CONFIG   _CP_OFF & _WDT_OFF & _PWRTE_ON & _HS_OSC	

		ERRORLEVEL -302

;Bruno*Fascendini*brunodini@yahoo.com.ar*Bruno*Fascendini*brunodini@yahoo.com.ar*Bruno*Fascendini*brunodini@yahoo.com.ar*
;Bruno*Fascendini*brunodini@yahoo.com.ar*Bruno*Fascendini*brunodini@yahoo.com.ar*Bruno*Fascendini*brunodini@yahoo.com.ar*


Vi		EQU	0x0c
Vf		EQU	0x0d
Vmax		EQU	0x0e
acel		EQU	0x0f
desacel		EQU	0x10
tinit		EQU	0x11
tfinal		EQU	0x12
tmax		EQU	0x13
tacel		EQU	0x14
tdesacel	EQU	0x15
AUX1		EQU	0X16
AUX2		EQU	0x17
Velact		EQU	0X18
FLAGREDOND	EQU	0X19
TMP1		EQU	0x1A
RET1		EQU	0X1B
RET2		EQU	0X1C

;Bruno*Fascendini*brunodini@yahoo.com.ar*Bruno*Fascendini*brunodini@yahoo.com.ar*Bruno*Fascendini*brunodini@yahoo.com.ar*
;Bruno*Fascendini*brunodini@yahoo.com.ar*Bruno*Fascendini*brunodini@yahoo.com.ar*Bruno*Fascendini*brunodini@yahoo.com.ar*


		ORG	0x10
	
		BSF	STATUS,RP0
	
		CLRW
		MOVWF	PORTA	;PORTA TODAS SALIDAS, PONE LEDS EN MODO FUENTE PARA PODER VER LOS MENSAJES,OK? PORTA,4 NECESITA PULL UP!
		MOVWF	PORTB	;PORTB TODAS COMO SALIDAS

		BCF	STATUS,RP0

FILLIT	CLRF	PORTA	;LIMPIO BASURAS(LATCH ANTERIOR) QUE PUDIESE HABER EN EL PUERTOA
		CLRF	PORTB	;LIMPIO BASURAS(LATCH ANTERIOR) QUE PUDIESE HABER EN EL PUERTOB		

		MOVLW	.2	;aca defini la velocidad inicial (Vi)
		MOVWF	Vi
		MOVWF	Velact

		MOVWF	PORTB	;envio el valor al conversor DA en el puertoB

		MOVLW	.6	;aca defini la velocidad final (vf)
		MOVWF	Vf

		MOVLW	.240	;aca defini la velocidad maxima (Vmax)
		MOVWF	Vmax


		MOVLW	.200	;aca defini el tiempo que queres que espere antes de comenzar a acelerar.
				;TIEMPO = 10ms X constante: EN este caso: TIEMPO = 10ms X 200 =2000 ms = 2seg

		MOVWF	tinit

		MOVLW	.220	;aca defini el tiempo que queres que espere luego de completado el proceso, antes de reinciar la secuencia.
				;TIEMPO = 10ms X constante: EN este caso: TIEMPO = 10ms X 220 =2200 ms = 2.2seg

		MOVWF	tfinal	


		MOVLW	.150	;aca defini el tiempo que queres que espere una vez alcanzada la velocidad maxima, y antes de comenzar la desaceleracion
						;TIEMPO = 10ms X constante: EN este caso: TIEMPO = 10ms X 150 =1500 ms = 1.5seg

		MOVWF	tmax
		

		MOVLW	.180	;aca defini el tiempo que queres que lleve el proceso de aceleracion.
					;TIEMPO = 10ms X constante: EN este caso: TIEMPO = 10ms X 180 =1800 ms = 1.8seg

		MOVWF	tacel

		MOVLW	.100	;aca defini el tiempo que queres que lleve el proceso de desaceleracion.
				;TIEMPO = 10ms X constante: EN este caso: TIEMPO = 10ms X 100 =1000 ms = 1seg

		MOVWF	tdesacel

				;los valores puestos arriba son arbritarios, los elegi yo. podes cambiarlos cuando quieras.
				;LIMITACIONES! LEE ABAJO!
				;tene en cuenta que Vmax "deberia" ser > Vi y a la vez Vmax "deberia" ser > Vf, sino el motor va a comportarse raro...o no comportarse, no lo se, no lo calculé ;)
				;tacel,tdesacel,tinit,tfinal y tmax deben ser > 0.
				;Vmax-Vi deberia ser >= tacel Vmax-Vf deberia ser >= tdesacel para lograr mejor aceleracion constante 
				;(Vmax-Vi)/tacel deberia dar un numero entero para lograr una aceleracion completamente constante
				;(Vmax-Vf)/tdesacel deberia dar un numero entero para lograr una desaceleracion completamente constante
				;calculo de C1 y C2(mira el grafico)


				;la constante C1 de aceleracion + vendra dada por la formula (Vmax -Vi)/ tacel

		CLRF	acel	;acel = C1 del grafico, INICIALIZO A CERO

		MOVF	Vi,w
		SUBWF	Vmax,W	;DIFERENCIA DE VELOCIDAD MAXIMA Y INICIAL = Vmax - Vi
		MOVWF	AUX1	;muevo el resultado a AUX1
		
CALCULC1	MOVF	tacel,W	;EL RESULTADO DE Vmax - Vi dividido por tacel da la variacion de velocidad instantanea constante positiva buscada (C1 DEL GRAFICO)
		SUBWF	AUX1,W	;UNA DIVISION SE PUEDE LOGRAR HACIENDO UNA RESTA REPETIDA x(equis) VECES, ASI QUE...
		BTFSC	STATUS,Z
		GOTO	LISTOC1

		BTFSS	STATUS,C	;LA RESTA DA NEGATIVA? SI-> DETENER DIVISION ;NO -> REPETIR RESTA
		GOTO	LISTOC1		

		MOVWF	AUX1
		INCF	acel,F
		GOTO	CALCULC1		

LISTOC1	
					;la constante C2 de aceleracion - vendra dada por la formula (Vmax -Vf)/ tdesacel


NOHAYRESTOC1	CLRF	desacel	;desacel = C2 del grafico, INICIALIZO A CERO

		MOVF	Vf,w
		SUBWF	Vmax,W	;DIFERENCIA DE VELOCIDAD MAXIMA Y FINAL = Vmax - Vf
		MOVWF	AUX2	;muevo el resultado a AUX2
		
CALCULC2	MOVF	tdesacel,W	;EL RESULTADO DE Vmax - Vf dividido por tdesacel da la variacion de velocidad instantanea constante negativa buscada (C2 DEL GRAFICO)
		SUBWF	AUX2,W		;UNA DIVISION SE PUEDE LOGRAR HACIENDO UNA RESTA REPETIDA x(equis) VECES, ASI QUE...
		BTFSC	STATUS,Z
		GOTO	LISTOC2

		BTFSS	STATUS,C	;LA RESTA DA NEGATIVA? SI-> DETENER DIVISION ;NO -> REPETIR RESTA
		GOTO	LISTOC2		

		MOVWF	AUX2
		INCF	desacel,F
		GOTO	CALCULC2

LISTOC2	

					;ENTONCES AHORA TENEMOS:
					;acel: incremento de velocidad cada 10ms
					;desacel: decremento de velocidad cada 10ms
					;AUX1: Resto de la division de aceleracion (AUX1 < tacel)
					;AUX2: Resto de la division de desaceleracion (AUX1 < tdesacel)



;Bruno*Fascendini*brunodini@yahoo.com.ar*Bruno*Fascendini*brunodini@yahoo.com.ar*Bruno*Fascendini*brunodini@yahoo.com.ar*
;Bruno*Fascendini*brunodini@yahoo.com.ar*Bruno*Fascendini*brunodini@yahoo.com.ar*Bruno*Fascendini*brunodini@yahoo.com.ar*

;PASO 1:
;ESPERA INICIAL, MANTIENE CONSTANTE Vi durante (tinit x 10 ms)

		MOVF	tinit,F
		BTFSC	STATUS,Z
		GOTO	NOTINIT		;si decidiste que no haya tinit saltar directamente al proceso de aceleracion(2)	

		BSF	PORTA,0		;INDICAR CON UN LED EN PORTA,0 QUE ESTA HACIENDO EL tinit
		MOVF	tinit,W
		MOVWF	TMP1

LOOPTINIT	CALL	RET10MS
		DECFSZ	TMP1,F
		GOTO	LOOPTINIT		

		BCF	PORTA,0		;INDICAR FIN DE tinit

;Bruno*Fascendini*brunodini@yahoo.com.ar*Bruno*Fascendini*brunodini@yahoo.com.ar*Bruno*Fascendini*brunodini@yahoo.com.ar*
;Bruno*Fascendini*brunodini@yahoo.com.ar*Bruno*Fascendini*brunodini@yahoo.com.ar*Bruno*Fascendini*brunodini@yahoo.com.ar*

;PASO 2:
;ACELERACION

		BSF	PORTA,1		;INDICAR CON UN LED EN PORTA,1 QUE ESTA HACIENDO LA ACELERACION

NOTINIT		MOVF	tacel,F

		BTFSC	STATUS,Z
		GOTO	BEGINMAX

		MOVF	Vi,W
		MOVWF	Velact

		MOVF	tacel,W
		MOVWF	TMP1

		CLRF	FLAGREDOND	;HAY QUE REDONDEAR? SETEO INICIALMENTE A: NO
	
		MOVF	AUX1,F
		BTFSS	STATUS,Z
		BSF	FLAGREDOND,0	;HAY QUE REDONDEAR(HAY RESTO)

		
INCVEL	CALL	RET10MS
		MOVF	acel,W		;MUEVO el % de velocidad instantanea a variar
		ADDWF	Velact,F	;se lo agrego a la velocidad actual
		BTFSS	FLAGREDOND,0	;hay que hacer redondeo?
		GOTO	MAKEACEL	;NO

		INCF	Velact,F	;UTILIZANDO REDONDEO (PENDIENTE = acel+1)
		DECFSZ	AUX1,F		;TERMINO EL REDONDEO?
		GOTO	MAKEACEL	;NO
		
		CLRF	FLAGREDOND	;SI, ANULAR REDONDEO

MAKEACEL	MOVF	Velact,W
		MOVWF	PORTB
		DECFSZ	TMP1,F		;TERMINO DE AUMENTAR VELOCIDAD?
		GOTO	INCVEL		;NO, SEGUIR AUMENTANDO
	
		BCF	PORTA,1		;SI, APAGAR LUZ DE MENSAJE DE ACELERACION EN PROGRESO

;Bruno*Fascendini*brunodini@yahoo.com.ar*Bruno*Fascendini*brunodini@yahoo.com.ar*Bruno*Fascendini*brunodini@yahoo.com.ar*
;Bruno*Fascendini*brunodini@yahoo.com.ar*Bruno*Fascendini*brunodini@yahoo.com.ar*Bruno*Fascendini*brunodini@yahoo.com.ar*

;PASO 3:
;MANTENIMIENTO DE Vmax(Velocidad Maxima)

BEGINMAX	
			MOVF	Vmax,W	
			MOVWF	PORTB
			MOVWF	Velact		;AJUSTA EN CASO DE QUE tacel = 0, nada mas

			MOVF	tmax,F		;
			BTFSC	STATUS,Z
			GOTO	INITDESAC

			BSF	PORTA,2
			
			MOVF	tmax,W
			MOVWF	TMP1
		
LOOPTMAX	CALL	RET10MS

			DECFSZ	TMP1,F
			GOTO	LOOPTMAX
	
			BCF	PORTA,2

;Bruno*Fascendini*brunodini@yahoo.com.ar*Bruno*Fascendini*brunodini@yahoo.com.ar*Bruno*Fascendini*brunodini@yahoo.com.ar*
;Bruno*Fascendini*brunodini@yahoo.com.ar*Bruno*Fascendini*brunodini@yahoo.com.ar*Bruno*Fascendini*brunodini@yahoo.com.ar*

;PASO 4:
;DESACELERACION

INITDESAC	MOVF	tdesacel,F
			BTFSC	STATUS,Z
			GOTO	MANTLOW

			BSF	PORTA,3		;INDICAR CON UN LED EN PORTA,3 QUE ESTA HACIENDO LA DESACELERACION

		MOVF	Vmax,W
		MOVWF	Velact

		MOVF	tdesacel,W
		MOVWF	TMP1

		CLRF	FLAGREDOND	;HAY QUE REDONDEAR? SETEO INICIALMENTE A: NO
	
		MOVF	AUX2,F
		BTFSS	STATUS,Z
		BSF		FLAGREDOND,0	;HAY QUE REDONDEAR(HAY RESTO)

		
DECVEL	CALL	RET10MS
		MOVF	desacel,W		;MUEVO el % de velocidad instantanea a variar
		SUBWF	Velact,F		;se lo agrego a la velocidad actual
		BTFSS	FLAGREDOND,0		;hay que hacer redondeo?
		GOTO	MAKEDESACEL		;NO

		DECF	Velact,F		;ajustar con redondeo
		DECFSZ	AUX2,F			;hay que seguir redondeando?
		GOTO	MAKEDESACEL		;SI
		
		CLRF	FLAGREDOND		;NO,detener redondeo

MAKEDESACEL	MOVF	Velact,W		;expulsa la velocidad actual por el puertoB
			MOVWF	PORTB
			DECFSZ	TMP1,F
			GOTO	DECVEL

			BCF	PORTA,3

;Bruno*Fascendini*brunodini@yahoo.com.ar*Bruno*Fascendini*brunodini@yahoo.com.ar*Bruno*Fascendini*brunodini@yahoo.com.ar*
;Bruno*Fascendini*brunodini@yahoo.com.ar*Bruno*Fascendini*brunodini@yahoo.com.ar*Bruno*Fascendini*brunodini@yahoo.com.ar*

;PASO 5
;MANTENIMIENTO DE VELOCIDAD FINAL

MANTLOW	MOVF	Vf,W
		MOVWF	PORTB
		MOVWF	Velact

		MOVF	tfinal,F
		BTFSC	STATUS,Z
		GOTO	FILLIT		;si decidiste que no haya tfinal volver al inicio del programa

		BSF		PORTA,4		;INDICAR CON UN LED EN PORTA,4 QUE ESTA HACIENDO EL MANTENIMIENTO DE LA VELOCIDAD FINAL
		MOVF	tfinal,W
		MOVWF	TMP1

LOOPFINAL	CALL	RET10MS
			DECFSZ	TMP1,F
			GOTO	LOOPFINAL

			BCF	PORTA,4		;INDICAR FIN DE tfinal

			GOTO	FILLIT

;PROCEDIMIENTOS(no devuelven resultados):

RET10MS			DECFSZ	RET1,F
			GOTO	RET10MS

			NOP
			NOP
			MOVLW	0X0B
			MOVWF	RET1

			DECFSZ	RET2,F
			GOTO	RET10MS

			RETURN

		END
