;********************************************************************** ; MANEJO DE SERVOS - Programa Básico 1 ; Por Eduardo J. Carletti, Robots Argentina, 2007 ;********************************************************************** list p=16F628A ; definir procesador #include ; 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