Control de 4 servos con píc 16F628A

Hola, soy nuevo en el tema y he modificado este código original para controlar un servo para que lo haga para 4 servos, pero he notado que se me altera la posición de los otros 3 cuando manipulo uno de ellos, me podrían ayudar a resolverlo?
La idea es poder mover 4 servos con 8 pulsadores usando el puerto A del pic y controlar los servos con el puerto B,

el código que tengo es el siguiente:

Código:
__CONFIG _LVP_OFF & _MCLRE_OFF & _BODEN_OFF & _CP_OFF & _PWRTE_ON & _WDT_OFF & _INTOSC_OSC_NOCLKOUT 

       LIST	   P=16F628A       ;Procesador utilizado.
       INCLUDE   <P16F628A.INC>
       ERRORLEVEL   0,   -302      ;suppress bank selection messages
  
;******************************   ZONA DE DATOS    ****************************
#define     Banco0       bcf  STATUS,RP0
#define     Banco1       bsf  STATUS,RP0 

#define     Servo1         PORTB,0
#define     Servo2         PORTB,1
#define     Servo3         PORTB,2
#define     Servo4         PORTB,3

#define     Pulsador_IZQ   PORTA,0
#define     Pulsador_DER   PORTA,1
#define     Pulsador_IZQ1   PORTA,2
#define     Pulsador_DER1   PORTA,3
#define     Pulsador_IZQ2   PORTA,4
#define     Pulsador_DER2   PORTA,5
#define     Pulsador_IZQ3   PORTA,6
#define     Pulsador_DER3   PORTA,7



;******************************  MAPA DE MEMORIA   ****************************
     CBLOCK    0x20         ;Inicio de 16f628, pero 0C para el 16f84
     contador
     contador_
     velocidad 
     PDel0                   
     PDel1                  
     PDel2
  
     ENDC	

;******************************************************************************
;*************************         INICIO          ****************************
;****************************************************************************** 
Inicio org  	0
       goto 	Configuracion  
 
;Datos que se veran al cargar el HEX en el micro, pero no afectan al programa 
       DT	" control de un servomotor"  
       DT	" 16f628A"
Configuracion 
 
       Banco1                  ;Acceso al Banco 1.
       bsf   Pulsador_DER      ;entradas 
       bsf   Pulsador_IZQ
       bsf   Pulsador_DER1      ;entradas 
       bsf   Pulsador_IZQ1
       bsf   Pulsador_DER2      ;entradas 
       bsf   Pulsador_IZQ2
       bsf   Pulsador_DER3      ;entradas 
       bsf   Pulsador_IZQ3
       bcf   Servo1
       bcf   Servo2
       bcf   Servo3
       bcf   Servo4

       bcf	OPTION_REG,NOT_RBPU  ;Activa las resistencias Pull-Up del Puerto B           
       Banco0                    ;Acceso al Banco 0.      
        
       movlw     0x07           ;desconecta los comparadores analogicos del
       movwf     CMCON          ;pic 16f628

       clrf    contador
       clrf    contador_
       clrf    velocidad 
       movlw     .128           ;valor para la posicion neutra
       movwf    contador

       goto      principal1

	

;******************************************************************************
;*************************       PRINCIPAL         ****************************
;****************************************************************************** 
principal1 
    bcf   Servo1 ;a nivel bajo
    goto bucle_2

principal2
    bcf   Servo2
    goto bucle_3

principal3
    bcf   Servo3
    goto bucle_4

principal4
    bcf   Servo4
    goto bucle_5
    

   
;*************************       SEÑAL DE SERVO1
bucle_2
    bsf     Servo1         ;pongo en alto la salida
    call    Retardo_300micros    ;tiempo minimo de 550 us
    call    Retardo_200micros
    call    Retardo_50micros    

    call    TEMPO          ;incremento el tiempo seleccionado
    bcf     Servo1         ;pongo la salida en bajo
    call    Retardo_10ms   ;tiempo para completar un ciclo conpleto
    call    Retardo_5ms   ;tiempo para completar un ciclo conpleto
    decfsz	velocidad,F    ;decrementa el contador   
    goto    pulsadores        ;vuelve a mandar el mismo pulso   


;*************************       SEÑAL DE SERVO2
bucle_3
    bsf     Servo2         ;pongo en alto la salida
    call    Retardo_300micros    ;tiempo minimo de 550 us
    call    Retardo_200micros
    call    Retardo_50micros    

    call    TEMPO          ;incremento el tiempo seleccionado
    bcf     Servo2         ;pongo la salida en bajo
    call    Retardo_10ms   ;tiempo para completar un ciclo conpleto
    call    Retardo_5ms   ;tiempo para completar un ciclo conpleto
    decfsz	velocidad,F    ;decrementa el contador   
    goto    pulsadores        ;vuelve a mandar el mismo pulso   
    
    
;*************************       SEÑAL DE SERVO3
bucle_4
    bsf     Servo3         ;pongo en alto la salida
    call    Retardo_300micros    ;tiempo minimo de 550 us
    call    Retardo_200micros
    call    Retardo_50micros    

    call    TEMPO          ;incremento el tiempo seleccionado
    bcf     Servo3         ;pongo la salida en bajo
    call    Retardo_10ms   ;tiempo para completar un ciclo conpleto
    call    Retardo_5ms   ;tiempo para completar un ciclo conpleto
    decfsz	velocidad,F    ;decrementa el contador   
    goto    pulsadores        ;vuelve a mandar el mismo pulso   

;*************************       SEÑAL DE SERVO4
bucle_5
    bsf     Servo4         ;pongo en alto la salida
    call    Retardo_300micros    ;tiempo minimo de 550 us
    call    Retardo_200micros
    call    Retardo_50micros    

    call    TEMPO          ;incremento el tiempo seleccionado
    bcf     Servo4         ;pongo la salida en bajo
    call    Retardo_10ms   ;tiempo para completar un ciclo conpleto
    call    Retardo_5ms   ;tiempo para completar un ciclo conpleto
    decfsz	velocidad,F    ;decrementa el contador   
    goto    pulsadores        ;vuelve a mandar el mismo pulso   
    
    
  
;******************************************************************************
;*************************       PULSADORES         ****************************
;****************************************************************************** 
pulsadores
	
     
     btfss   Pulsador_DER   ;salta si vale 1
     goto    Sumar
     btfss   Pulsador_IZQ
     goto    Restar
     btfss   Pulsador_DER1   	;salta si vale 1
     goto    Sumar1
     btfss   Pulsador_IZQ1
     goto    Restar1
     btfss   Pulsador_DER2   	;salta si vale 1
     goto    Sumar2
     btfss   Pulsador_IZQ2
     goto    Restar2
     btfss   Pulsador_DER3   	;salta si vale 1
     goto    Sumar3
     btfss   Pulsador_IZQ3
     goto    Restar3
     RETURN

Sumar 
     incf    contador,F      	; rutina de  incremento 
     movf    contador,W   		; incremento las unidades 
     btfss   STATUS,Z           ;Mira si vale cero
     goto    bucle_2
     movlw   0xFF          
     movwf   contador      		;vuelvo a dejarlo en 256
     goto    principal1   
Restar 
     movf    contador,F         ;se carga sobre si mismo
     btfsc   STATUS,Z           ;Mira si vale cero
     goto    bucle_2     		;regresa si vale cero
     decfsz  contador,F         ;decrementa el contador
     nop                        ;importante, para que no me salte el return.
     goto    principal1



Sumar1 
     incf    contador,F 		 ; rutina de  incremento 
     movf    contador,W  		 ; incremento las unidades 
     btfss   STATUS,Z      		 ;Mira si vale cero
     goto     bucle_3
     movlw     0xFF          
     movwf     contador     	 ;vuelvo a dejarlo en 256
     goto 		principal2   
Restar1
     movf    contador,F        	 ;se carga sobre si mismo
     btfsc   STATUS,Z          	 ;Mira si vale cero
     goto bucle_3            	 ;regresa si vale cero
     decfsz contador,F         	 ;decrementa el contador
     nop                         ;importante, para que no me salte el return.
     goto principal2 



Sumar2 
     incf    contador,F   ; rutina de  incremento 
     movf    contador,W   ; incremento las unidades 
     btfss   STATUS,Z           ;Mira si vale cero
     goto     bucle_4
     movlw     0xFF          
     movwf     contador      ;vuelvo a dejarlo en 256
     goto principal3   
Restar2
     movf    contador,F         ;se carga sobre si mismo
     btfsc   STATUS,Z           ;Mira si vale cero
     goto bucle_4                     ;regresa si vale cero
     decfsz contador,F          ;decrementa el contador
     nop                        ;importante, para que no me salte el return.
     goto principal3



Sumar3 
     incf    contador,F      ; rutina de  incremento 
     movf    contador,W      ; incremento las unidades 
     btfss   STATUS,Z        ;Mira si vale cero
     goto     bucle_5
     movlw     0xFF          
     movwf     contador      ;vuelvo a dejarlo en 256
     goto     principal4   
Restar3
     movf    contador,F      ;se carga sobre si mismo
     btfsc   STATUS,Z        ;Mira si vale cero
     goto bucle_5            ;regresa si vale cero
     decfsz contador,F       ;decrementa el contador
     nop                     ;importante, para que no me salte el return.
     goto     principal4


      
;******************************************************************************
;*************************       MICROSWITCH       ****************************
;****************************************************************************** 
;******************************************************************************
;*************************      MEDIR TIEMPO       ****************************
;****************************************************************************** 
;cada unidad del contador_ equivale a un tiempo de 4us
TEMPO  
       movf     contador,W        
       movwf     contador_ 

       movf    contador_,F         ;se carga sobre si mismo
       btfsc   STATUS,Z            ;Mira si vale cero
       return                     ;regresa si vale cero

Tiempo 
     nop                                         ; 4us
     nop                                         ; 5us   
     nop                                         ; 6us	  
     nop                                         ; 7us    
 ;    nop                                        ; 8us   no utilizado


        decfsz	contador_,F	 ;decrementa el contador  1us
        goto    Tiempo    ;regresa si llego a cero    3us

        return                              


;******************************************************************************
;*************************     RETARDOS            ****************************
;****************************************************************************** 

; ZONA DE DATOS *************************************************************** 
	CBLOCK
	R_ContA	    ;Contadores para los retardos.
	R_ContB
	R_ContC
	ENDC
;****************************************************************************** 
; RETARDOS de 0.5 hasta 60 segundos  
;****************************************************************************** 
Retardo_1minuto
Retardo_60s	
        call    Retardo_10s			 
Retardo_50s	
        call    Retardo_25s
Retardo_25s				 
	movlw	d\'250\'			 
	goto	Retardo_1Decima	
Retardo_20s				 
	movlw	d\'200\'			 
	goto	Retardo_1Decima		 
Retardo_10s				 
	movlw	d\'100\'			 
	goto	Retardo_1Decima		 
Retardo_5s				 
	movlw	d\'50\'			 
	goto	Retardo_1Decima		 
Retardo_2s				 
	movlw	d\'20\'			 
	goto	Retardo_1Decima		 
Retardo_1s				 
	movlw	d\'10\'			 
	goto	Retardo_1Decima		 
Retardo_500ms				 
	movlw	d\'5\'			 
 
Retardo_1Decima
	movwf	R_ContC			 
R1Decima_BucleExterno2
	movlw	d\'100\'			 
	movwf	R_ContB			 
R1Decima_BucleExterno
	movlw	d\'249\'			 
	movwf	R_ContA			 
R1Decima_BucleInterno          
	clrwdt				 
	decfsz	R_ContA,F		 
	goto	R1Decima_BucleInterno	 
	decfsz	R_ContB,F		 
	goto	R1Decima_BucleExterno	 
	decfsz	R_ContC,F		   
	goto	R1Decima_BucleExterno2	 
	return

;****************************************************************************** 
; RETARDOS de 1 ms hasta 200 ms.  
;****************************************************************************** 
Retardo_200ms				 
	movlw	d\'200\'			 
	goto	Retardos_ms		 
Retardo_100ms				 
	movlw	d\'100\'			 
	goto	Retardos_ms		 
Retardo_50ms				 
	movlw	d\'50\'			 
	goto	Retardos_ms		 
Retardo_20ms				 
	movlw	d\'20\'			 
	goto	Retardos_ms		 
Retardo_10ms				 
	movlw	d\'10\'			 
	goto	Retardos_ms	 
Retardo_5ms				 
	movlw	d\'5\'			 
	goto	Retardos_ms	
Retardo_3ms				 
	movlw	d\'2\'			 
	goto	Retardos_ms		 
Retardo_2ms				 
	movlw	d\'2\'			 
	goto	Retardos_ms		 
Retardo_1ms				 
	movlw	d\'1\' 
 
Retardos_ms
	movwf	R_ContB			 
R1ms_BucleExterno
	movlw	d\'249\'			  
	movwf	R_ContA			 
R1ms_BucleInterno
	clrwdt				 
	decfsz	R_ContA,F		  
	goto	R1ms_BucleInterno		 
	decfsz	R_ContB,F		 
	goto	R1ms_BucleExterno 	 
	return	
				 
;****************************************************************************** 
; RETARDOS de 20 hasta 500 microsegundos  
;****************************************************************************** 
Retardo_500micros				 
	clrwdt				 
	movlw	d\'164\'			 
	goto	RetardoMicros
Retardo_300micros				 
	clrwdt				 
	movlw	d\'95\'			 
	goto	RetardoMicros	
Retardo_200micros				 
	clrwdt				 
	movlw	d\'64\'			 
	goto	RetardoMicros		 
Retardo_100micros				 
	movlw	d\'31\'			 
	goto	RetardoMicros		 
Retardo_50micros				 
	clrwdt				 
	movlw	d\'14\'			 
	goto	RetardoMicros		 
Retardo_20micros				 
	movlw	d\'5\' 
 
RetardoMicros
	movwf	R_ContA			 
Rmicros_Bucle
	decfsz	R_ContA,F		 
	goto	Rmicros_Bucle		 
	return	

;******************************************************************************
; RETARDOS de 4 hasta 10 microsegundos  
;******************************************************************************
Retardo_10micros				 
	nop				 
	nop				 
	nop				 
	nop				 
	nop				 
Retardo_5micros				 
	clrwdt				 
Retardo_4micros				 
	return	


      end ...
 
Última edición por un moderador:
esta laborioso tu programa pero creo que estas sumando los tiempos de los 4 servos osea los 15ms por cada servo que esto da60 ms , lo mas factible es que lo hagas con interrupciones por medio del timer, si lo requieres te mando un ejemplo
 
¡Sorpresaaaa!
Temporizaciones con retardos que dan problemas.
¡¡Mira que me resulta raro con lo bien que van y lo útiles que son!!
[/modo sarcástico]

Borra de tu mente para siempre el uso de los retardos a base de bucles vacíos, son 'una plaga'.
En mi opinión un bucle da más de unos pocos, muy pocos, microsegundos es una aberración.
Aprende a usar los timers por interrupciones que están para eso. Al principio te costará un poco pero luego verás 'la luz'.
Ojo, esto es una opinión personal, cada uno es libre de complicarse la vida como prefiera.

Para hacerlo por retardos habría que sacar las restas de unos arespecto de otros para que el tiempo de cada uno se mantenga constante.
 
Última edición:
Atrás
Arriba