;**********************************************************************
; MANEJO DE SERVOS - Programa Básico 1
; Por Eduardo J. Carletti, Robots Argentina, 2007
;**********************************************************************

	list      p=16F628A	; definir procesador

#include <p16F628A.inc>		; definiciones de variables específicas del procesador

	ERRORLEVEL 1;-302	; para evitar los mensajes de cambio de
				; banco en el resultado del compilador

	__CONFIG   _CP_OFF & _WDT_OFF & _LVP_OFF & _PWRTE_ON & _INTRC_OSC_NOCLKOUT & _MCLRE_OFF

;***** DEFINICIÓN DEL NOMBRE DE ENTRADAS Y SALIDAS

#define SERVO1	 	PORTA,0		; puerto de salida de servo 1
#define PULSADOR1 	PORTA,1		; puerto de entrada de pulsador 1
#define PULSADOR2 	PORTA,2		; puerto de entrada de pulsador 2
#define PULSADOR3 	PORTA,3		; puerto de entrada de pulsador 3

;***** VARIABLES

	CBLOCK	0x20
	acum_A		; variable momentánea
	Posic		; posición servo
	ENDC

;***********************************************************************************

	org	0x000
	goto	principal

;***********************************************************************************
; Principal
;***********************************************************************************

principal
		movlw b'00000111' 	; deshabilita comparadores. Esto es
		movwf CMCON		; algo importante en el PIC 16F628A

		clrf PORTA		; inicia ports
		clrf PORTB		; inicia ports

		bsf STATUS,RP0		; Apunta a banco 1

		movlw b'00001110' 	; PORTA 
		movwf	TRISA		; salidas menos 1, 2 y 3, entradas

		MOVLW b'00000000' 	; PORTB 
		movwf	TRISB		; salidas

		movlw	b'00000010'	; Configuración para TMR0
		movwf	OPTION_REG	; preescaler 2, 1:8 con CLK interno (que es
					; de 1 MHz si el oscilador es de 4 MHz).
					; El contador cuenta cada 8 useg

	        bcf STATUS,RP0          ; Apunta a banco 0

		clrf TMR0		; inicia registro de timer en 0

		movlw d'133'		; inicia valor de posición de servo (centro)
		movwf Posic

;***********************************************************************************
; Lazo principal
;***********************************************************************************

lazo

; Los servos actúan con un pulso de control que va entre 0,5 ms y 2,5 ms.
; En el bloque que sigue se inicia en 1 el pulso de control y se espera un 
; retardo fijo de aproximadamente 0,5 ms, que es el valor mínimo del pulso.
; Con este valor de longitud de pulso y una longitud cero en la parte variable, 
; el servo está parado al máximo hacia la izquierda (sentido antihorario).

		bsf	SERVO1		; pone la señal de servo en 1
		bcf	INTCON,T0IF	; borra el flag de timer
		movlw	d'192'		; (256-192 = 64) 64 * 8 us = 0,512 ms
		movwf	TMR0		; valor al registro de timer
		btfss	INTCON,T0IF	; espera por timer = ff -> 00
		goto	$-1
		bcf	INTCON,T0IF	; borra el flag de timer

; A continuación, comienza el tiempo variable del pulso. Esto permite 
; que el recorrido completo, de 180 grados (valores de pulso entre 0,5 ms
; y 2,5 ms), se divida en 256 segmentos (256 * 8 us = 2,048 ms).
; La parte variable del pulso de control varía entre 0 y 2 ms

		movf	Posic,w		; 256-nn x 8 uS = 1 ms, 1,5 ms, 2,5 ms
		movwf	TMR0		; valor al registro de timer
		btfss	INTCON,T0IF	; espera por timer = ff -> 00
		goto	$-1
		bcf	SERVO1		; pone la señal de servo en 0
		bcf	INTCON,T0IF	; borra el flag de timer

; Retardo de 20 ms, que es el tiempo estándar que debe separar los pulsos 
; de control para los servos comunes de RC

		movlw	d'9'		; cantidad de veces: 9 x 2 ms = 18 ms + 2 ms
		movwf	acum_A
retardo		bcf	INTCON,T0IF	; borra el flag de timer
		movlw	d'6'		; (256-6 = 250) 250 * 8 us = 2 ms
		movwf	TMR0		; valor al registro de timer
		btfss	INTCON,T0IF	; espera por timer = ff -> 00
		goto	$-1
		decfsz	acum_A		; decrementa cantidad de veces
		goto	retardo

pulsadores				; lee órdenes a través de pulsadores
		btfss	PULSADOR1
		goto iniciaPos		; servo en posición central
		btfss	PULSADOR2
		goto incPos		; incrementa Posic
		btfss	PULSADOR3
		goto decPos		; decrementa Posic

		goto lazo

iniciaPos	movlw d'133'		; 256-133 = 123, 123 * 8 us = 984 us + 512 us
		movwf Posic		; posición central en esta disposición
		goto lazo		; y sale
					
decPos		movf Posic,f		; se fija si Posic ya es cero
		bz sale1		; si es cero no decrementa
		decf Posic,f		; si no es cero, decrementa
sale1		goto lazo		; y sale


incPos		movlw 0xFF		; se fija si Posic no es 0xFF
		xorwf Posic,w		; que es el valor máximo
		bz sale2		; si es el valor máximo, no incrementa
		incf Posic,f		; si no es el valor máx, incrementa
sale2		goto lazo		; y sale

		END

