desktop

Control de Servomotores

Hola, navegando dentro de este foro despues de tiempo decidi iniciar un nuevo tema; el cual a su vez de compartir tambien estoy buscando alguna sugerencia que puedan brindarme; ya que stoy apunto de iniciar un proyecto, pero primero quiero perfeccionar bien mi programa en ASM que voy a usar en la implementacion del control de servomotores, inicialmente este codigo simula el giro de 8 servos divididos en:
RA0-RA3 (Puerto A)
RB0-RB3 (Puerto B)
No utilizo ningun control que inicie tal rutina del giro de los servos; por lo que ahi esta mi duda, he simulado y corregido varios codigos pero para el control de estos motores y su giro los quiero iniciar con los otros puertos libres que quedan.
Recursos:
PIC16F84A
Proteus
MPLAB
Codigo en ASM:
HTML:
List p=16F84A
#include <P16F84A.inc>
 __CONFIG   _CP_OFF & _WDT_OFF & _PWRTE_ON & _XT_OSC
;**** Definicion de variables ****
CBLOCK 0X20 ; CBLOCK en 20h para que valga para toda la serie 16f 
 PDel0  ; Contadores para demor
 PDel1
 W_Temp   ; Registro para guardar temporalmente W
 STATUS_Temp  ; Registro para guardar temporalmete STATUS
 CONTADOR_0  ; para repeticiones de trenes de pulsos
 CONTADOR_1  ; seguramente se pueda hacer con uno solo pero no fuicapaz
 CONTADOR_2
 CONTADOR_3
 CONTADOR_4
 CONTADOR_5
 CONTADOR_6
 CONTADOR_7
 CONTADOR_8
 CONTADOR_9
 CONTADOR_10
 CONTADOR_11
 CONTADOR_12
 CONTADOR_13
 CONTADOR_14
 CONTADOR_15
 CONTADOR_16
 CONTADOR_17
 CONTADOR_18
 CONTADOR_19 
ENDC 
;**** Inicio del Micro ****
Reset  org 0x00  ; Aquí comienza el micro
   goto Inicio  ; Salto a inicio de mi programa
;**** Vector de Interrupcion **** 
   org 0x04  ; Atiendo Interrupcion
   goto Inicio_ISR 
; **** Programa Principal ****;**** Configuracion de puertos *** 
   org 0x05  ; Origen del código de programa
Inicio  bsf STATUS,RP0  ; Pasamos de Banco 0 a Banco 1
   movlw b'11110000' ; RB0 a RB3 como salida para control de servoS 
   movwf TRISB  ;  
   movlw b'10000' ; PORTA, RA0>RA3 salidas 
   movwf PORTA 
   movlw b'00000110' ; Se selecciona TMR0 y preescaler de 128
   movwf OPTION_REG ; para que al desbordar nos de 19,968 ms 
   bcf  STATUS,RP0 ; Paso del Banco 1 al Banco 0 
   clrf PORTA  ; empezamos con servos en 0 
   clrf PORTB 
   movlw .100  ; Cargamos 100 en TMR0 para lograr aprox. 20ms
   movwf TMR0 
   movlw b'10100000' ; Habilitamos GIE y T0IE (interrupción del TMR0) 
   movwf INTCON 
   clrf CONTADOR_0 ; empieza con contador_0 a 0 por ser el primero que cuenta          ; los otros se iran borrando en el programa    
   clrf CONTADOR_1  
   clrf CONTADOR_2 
   clrf CONTADOR_3 
   clrf CONTADOR_4 
   clrf CONTADOR_5 
   clrf CONTADOR_6 
   clrf CONTADOR_7 
   clrf CONTADOR_8 
   clrf CONTADOR_9 
   clrf CONTADOR_10 
   clrf CONTADOR_11 
   clrf CONTADOR_12 
   clrf CONTADOR_13 
   clrf CONTADOR_14 
   clrf CONTADOR_15 
   clrf CONTADOR_16 
   clrf CONTADOR_17 
   clrf CONTADOR_18 
   clrf CONTADOR_19  
;*************control de velocidad de los servos, variando el Nº de repeticiones ********************
;********se varia la velocidad de movimiento, cuanto menor es el Nº mas rapido va el servo***********************
MAIN   btfss INTCON,2 ; chequea si acabo la interrupcion, si pasaron 20ms 
   goto MAIN  ; sino acabo espera, aqui espera mucho tiempo entre 17.5 y 19.5ms        ; de cada 20ms, se pueden hacer otras cosas, entre un 85% y un 95%        ; del tiempo esta sin hacer nada para que se puedan hacer otras cosas  
   bcf  INTCON,2 ; aqui borra bandera interrupcion, se deja sin borrar en la          ; interrupcion para poder detectar en MAIN la interrupcion  
   bsf  INTCON,7  
   clrf CONTADOR_19   
   incf CONTADOR_0,f ; cuenta nº veces se desborda 
TIMER0  movlw  .25 ; EN 90º seran dobles por ser el centrado del movimiento 
   subwf CONTADOR_0,0 
   btfsc STATUS,Z ; mira si son 25 desbord 
   goto MAIN_A100 ; Z=1 va a siguiente posicion 
   call    CENT_SERVOS ; todavia no, sigue en 90º 
   goto MAIN  ; y vuelve para esperar desborde de TIMER0  
;***********comienzo avance servos PORTA**************************************************** 
MAIN_A100 btfss INTCON,2 ; chequea si acabo la interrupcion, si pasaron 20ms 
   goto MAIN_A100 ; sino acabo espera, aqui espera mucho tiempo entre 17.5 y 19.5ms        ; de cada 20ms, se pueden hacer otras cosas, entre un 85% y un 95%        ; del tiempo esta sin hacer nada para que se puedan hacer otras cosas  
   bcf  INTCON,2 ; aqui borra bandera interrupcion, se deja sin borrar en la          ; interrupcion para poder detectar en MAIN la interrupcion 
   bsf  INTCON,7 
   clrf CONTADOR_0  
   incf CONTADOR_1,f ; pasaron 8 veces empieza para 100º 
   movlw  .8  ; 25 es el numero de repeticiones para 100º 
   subwf CONTADOR_1,0 
   btfsc STATUS,Z ; van 8 veces? 
   goto MAIN_A110 ; si, va a siguiente posicion 
   call  MOV_A100 ; no sigue en 100º 
   goto MAIN_A100  
MAIN_A110  btfss INTCON,2 ; chequea si acabo la interrupcion, si pasaron 20ms 
   goto MAIN_A110 ; sino acabo espera, aqui espera mucho tiempo entre 17.5 y 19.5ms        ; de cada 20ms, se pueden hacer otras cosas, entre un 85% y un 95%        ; del tiempo esta sin hacer nada para que se puedan hacer otras cosas     bcf INTCON,2 ; aqui borra bandera interrupcion, se deja sin borrar en la          ; interrupcion para poder detectar en MAIN la interrupci 
   bsf  INTCON,7 
   clrf CONTADOR_1 
   incf CONTADOR_2,f ; si, empieza en 110º 
   movlw .8 
   subwf CONTADOR_2,0 
   btfsc STATUS,Z ; van 8? 
   goto MAIN_A120 ; SI, va a siguiente posicion 
   call MOV_A110 ; no, sigue en 110º 
   goto MAIN_A110 
MAIN_A120  btfss INTCON,2 ; chequea si acabo la interrupcion, si pasaron 20ms 
   goto MAIN_A120 ; sino acabo espera, aqui espera mucho tiempo entre 17.5 y 19.5ms        ; de cada 20ms, se pueden hacer otras cosas, entre un 85% y un 95%        ; del tiempo esta sin hacer nada para que se puedan hacer otras cosas  
   bcf  INTCON,2 ; aqui borra bandera interrupcion, se deja sin borrar en la  
   bsf  INTCON,7 ; interrupcion para poder detectar en MAIN la interrupcion  
   clrf CONTADOR_2   
   incf CONTADOR_3,f ; si, empieza en 160º 
   movlw .8 
   subwf CONTADOR_3,0 
   btfsc STATUS,Z ; van 8? 
   goto MAIN_A130 ; SI, va a siguiente posicion 
   call MOV_A120 ; no, sigue en 120º 
   goto MAIN_A120   
MAIN_A130  btfss INTCON,2 ; chequea si acabo la interrupcion, si pasaron 20ms 
   goto MAIN_A130 ; sino acabo espera, aqui espera mucho tiempo entre 17.5 y 19.5ms        ; de cada 20ms, se pueden hacer otras cosas, entre un 85% y un 95%        ; del tiempo esta sin hacer nada para que se puedan hacer otras cosas  
   bcf  INTCON,2 ; aqui borra bandera interrupcion, se deja sin borrar en la          ; interrupcion para poder detectar en MAIN la interrupcion 
   bsf  INTCON,7 
   clrf CONTADOR_3 
   incf CONTADOR_4,f ; si, empieza en 130º 
   movlw .8  ; aqui repite doble de veces por ser final de recorrido 
   subwf CONTADOR_4,0 ; ya se vera si asi va bien 
   btfsc STATUS,Z ; van 8? 
   goto MAIN_A140 
   call MOV_A130 ; no, sigue en 130º 
   goto MAIN_A130     
MAIN_A140 btfss INTCON,2 ; chequea si acabo la interrupcion, si pasaron 20ms 
   goto MAIN_A140 ; sino acabo espera, aqui espera mucho tiempo entre 17.7 y 19.7ms        ; de cada 20ms, se pueden hacer otras cosas, entre un 85% y un 95%        ; del tiempo esta sin hacer nada para que se puedan hacer otras cosas  
   bcf  INTCON,2 ; aqui borra bandera interrupcion, se deja sin borrar en la          ; interrupcion para poder detectar en MAIN la interrupcion 
   bsf  INTCON,7 
   clrf CONTADOR_4  
   incf CONTADOR_5,f ; si, empieza cuenta en en 140º 
   movlw .8 
   subwf CONTADOR_5,0 
   btfsc STATUS,Z ; van 8? 
   goto MAIN_RA130 
   call MOV_A140 ; no, sigue en 140º 
   goto MAIN_A140 
;**********retrceder servos PORTA de 140º a 90º************************************************** 
MAIN_RA130 btfss INTCON,2 ; chequea si acabo la interrupcion, si pasaron 20ms 
   goto MAIN_RA130 ; sino acabo espera, aqui espera mucho tiempo entre 17.7 y 19.7ms        ; de cada 20ms, se pueden hacer otras cosas, entre un 85% y un 95%        ; del tiempo esta sin hacer nada para que se puedan hacer otras cosas     bcf INTCON,2 ; aqui borra bandera interrupcion, se deja sin borrar en la           ;interrupcion para poder detectar en MAIN la interrupcion 
   bsf  INTCON,7 
   clrf CONTADOR_5    
   incf CONTADOR_6,f ; si, empieza en 130º 
   movlw .8 
   subwf CONTADOR_6,0 
   btfsc STATUS,Z ; van 8?   
   goto MAIN_RA120 
   call MOV_A130 ; no, sigue en 130º 
   goto MAIN_RA130  
MAIN_RA120 btfss INTCON,2 ; chequea si acabo la interrupcion, si pasaron 20ms 
   goto MAIN_RA120 ; sino acabo espera, aqui espera mucho tiempo entre 17.5 y 19.5ms        ; de cada 20ms, se pueden hacer otras cosas, entre un 85% y un 95%        ; del tiempo esta sin hacer nada para que se puedan hacer otras cosas  
   bcf  INTCON,2 ; aqui borra bandera interrupcion, se deja sin borrar en la          ;interrupcion para poder detectar en MAIN la interrupcion 
   bsf  INTCON,7  
   clrf CONTADOR_6 
   incf CONTADOR_7,f ; pasaron 50 veces empieza para 115º 
   movlw  .8  ; 8 es el numero de repeticiones para 115º 
   subwf CONTADOR_7,0 
   btfsc STATUS,Z ; van 8 veces? 
   goto MAIN_RA110 ; SI, va a siguiente 
   call  MOV_A120 ; no sigue en 120º 
   goto MAIN_RA120  
MAIN_RA110  btfss INTCON,2 ; chequea si acabo la interrupcion, si pasaron 20ms 
   goto MAIN_RA110 ; sino acabo espera, aqui espera mucho tiempo entre 17.5 y 19.5ms        ; de cada 20ms, se pueden hacer otras cosas, entre un 85% y un 95%         ; del tiempo esta sin hacer nada para que se puedan hacer otras cosas  
   bcf  INTCON,2 ; aqui borra bandera interrupcion, se deja sin borrar en la          ; interrupcion para poder detectar en MAIN la interrupcion 
   bsf  INTCON,7 
   clrf CONTADOR_7 
   incf CONTADOR_8,f ; si, empieza en 110º 
   movlw .8 
   subwf CONTADOR_8,0 
   btfsc STATUS,Z ; van 8? 
   goto MAIN_RA100 ; SI, va a siguiente posicion 
   call MOV_A110 ; no, sigue en 110º 
   goto MAIN_RA110 
MAIN_RA100 btfss INTCON,2 ; chequea si acabo la interrupcion, si pasaron 20ms 
   goto MAIN_RA100 ; sino acabo espera, aqui espera mucho tiempo entre 17.5 y 19.5ms        ; de cada 20ms, se pueden hacer otras cosas, entre un 85% y un 95%        ; del tiempo esta sin hacer nada para que se puedan hacer otras cosas  
   bcf  INTCON,2 ; aqui borra bandera interrupcion, se deja sin borrar en la          ; interrupcion para poder detectar en MAIN la interrupcion 
   bsf  INTCON,7 
   clrf CONTADOR_8 ; se pone a 0 para proxima vez 
   incf CONTADOR_9 ; pasaron 50 veces empieza para 100º 
   movlw  .8  ; 8 es el numero de repeticiones para 100º 
   subwf CONTADOR_9,0 
   btfsc STATUS,Z ; van 8 veces? 
   goto MAIN_CENT ; si, va a siguiente posicion 
   call  MOV_A100 ; no sigue en 10º 
   goto MAIN_RA100  
MAIN_CENT    ; aqui centra servos despues de movimiento completo PORTA         ; para empezar avance de PORTB 
   btfss INTCON,2 ; chequea si acabo la interrupcion, si pasaron 20ms 
   goto MAIN_CENT ; sino acabo espera, aqui espera mucho tiempo entre 17.5 y 19.5ms        ; de cada 20ms, se pueden hacer otras cosas, entre un 85% y un 95%        ; del tiempo esta sin hacer nada para que se puedan hacer otras cosas  
   bcf  INTCON,2 ; aqui borra bandera interrupcion, se deja sin borrar en la          ; interrupcion para poder detectar en MAIN la interrupcion 
   bsf  INTCON,7 
   clrf CONTADOR_9 ; la primera vez no es necesario pero despues si  
   incf CONTADOR_10,f ; cuenta nº veces se desborda TIMER0 
   movlw  .8  ; 
   subwf CONTADOR_10,0 
   btfsc STATUS,Z ; mira si son 8 desbordes 
   goto MAIN_B100 ; Z=1 va a siguiente posicion 
   call    CENT_SERVOS ; todavia no, sigue en 90º 
   goto MAIN_CENT ; y vuelve para esperar desborde de TIMER0
;********************movimientos avance  SERVOS PORTB*****************************************   
MAIN_B100 btfss INTCON,2 ; chequea si acabo la interrupcion, si pasaron 20ms 
   goto MAIN_B100 ; sino acabo espera, aqui espera mucho tiempo entre 17.5 y 19.5ms        ; de cada 20ms, se pueden hacer otras cosas, entre un 85% y un 95%        ; del tiempo esta sin hacer nada para que se puedan hacer otras cosas  
   bcf  INTCON,2 ; aqui borra bandera interrupcion, se deja sin borrar en la
       ; interrupcion para poder detectar en MAIN la interrupcion 
   bsf  INTCON,7 
   clrf CONTADOR_10 ; se pone a 0 para proxima vez 
   incf CONTADOR_11,f ; pasaron 50 veces empieza para 100º 
   movlw  .8  ; 25 es el numero de repeticiones para 100º 
   subwf CONTADOR_11,0 
   btfsc STATUS,Z ; van 8 veces? 
   goto MAIN_B110 ; si, va a siguiente posicion 
   call  MOV_B100 ; no sigue en 110º 
   goto MAIN_B100  
MAIN_B110  btfss INTCON,2 ; chequea si acabo la interrupcion, si pasaron 20ms 
   goto MAIN_B110 ; sino acabo espera, aqui espera mucho tiempo entre 17.5 y 19.5ms        ; de cada 20ms, se pueden hacer otras cosas, entre un 85% y un 95%         ; del tiempo esta sin hacer nada para que se puedan hacer otras cosas  
   bcf  INTCON,2 ; aqui borra bandera interrupcion, se deja sin borrar en la          ; interrupcion para poder detectar en MAIN la interrupcion   
   bsf  INTCON,7 
   clrf CONTADOR_11 
   incf CONTADOR_12,f ; si, empieza en 110º 
   movlw .8 
   subwf CONTADOR_12,0 
   btfsc STATUS,Z ; van 8? 
   goto MAIN_B120 ; SI, va a siguiente posicion 
   call MOV_B110 ; no, sigue en 110º 
   goto MAIN_B110 
MAIN_B120  btfss INTCON,2 ; chequea si acabo la interrupcion, si pasaron 20ms 
   goto MAIN_B120 ; sino acabo espera, aqui espera mucho tiempo entre 17.5 y 19.5ms        ; de cada 20ms, se pueden hacer otras cosas, entre un 85% y un 95%        ; del tiempo esta sin hacer nada para que se puedan hacer otras cosas  
   bcf  INTCON,2 ; aqui borra bandera interrupcion, se deja sin borrar en la
     ; interrupcion para poder detectar en MAIN la interrupcion 
   bsf  INTCON,7 
   clrf CONTADOR_12    
   incf CONTADOR_13,f ; si, empieza en 120º 
   movlw .8 
   subwf CONTADOR_13,0 
   btfsc STATUS,Z ; van 8?   
   goto MAIN_B130 ; SI, va a siguiente posicion 
   call MOV_B120 ; no, sigue en 120º 
   goto MAIN_B120 
MAIN_B130  btfss INTCON,2 ; chequea si acabo la interrupcion, si pasaron 20ms 
   goto MAIN_B130 ; sino acabo espera, aqui espera mucho tiempo entre 17.5 y 19.5ms        ; de cada 20ms, se pueden hacer otras cosas, entre un 85% y un 95%        ; del tiempo esta sin hacer nada para que se puedan hacer otras cosas  
   bcf  INTCON,2 ; aqui borra bandera interrupcion, se deja sin borrar en la          ; interrupcion para poder detectar en MAIN la interrupcion 
   bsf  INTCON,7 
   clrf CONTADOR_13 
   incf CONTADOR_14,f ; si, empieza en 130º 
   movlw .8  ; aqui repite doble de veces por ser final de recorrido 
   subwf CONTADOR_14,0 ; ya se vera si asi va bien 
   btfsc STATUS,Z ; van 8? 
   goto MAIN_B140 
   call MOV_B130 ; no, sigue en 130º 
   goto MAIN_B130     
MAIN_B140  btfss INTCON,2 ; chequea si acabo la interrupcion, si pasaron 20ms 
   goto MAIN_B140 ; sino acabo espera, aqui espera mucho tiempo entre 17.5 y 19.5ms        ; de cada 20ms, se pueden hacer otras cosas, entre un 85% y un 95%        ; del tiempo esta sin hacer nada para que se puedan hacer otras cosas     bcf INTCON,2 ; aqui borra bandera interrupcion, se deja sin borrar en la          ; interrupcion para poder detectar en MAIN la interrupcion 
   bsf  INTCON,7 
   clrf CONTADOR_14 
   incf CONTADOR_15,f ; si, empieza en 140º 
   movlw .8 
   subwf CONTADOR_15,0 
   btfsc STATUS,Z ; van 8? 
   goto MAIN_RB130 
   call MOV_B140 ; no, sigue en 140º 
   goto MAIN_B140 
;**********retroceder servos PORTB de 140º a 90º************************************************** 
MAIN_RB130 btfss INTCON,2 ; chequea si acabo la interrupcion, si pasaron 20ms 
   goto MAIN_RB130 ; sino acabo espera, aqui espera mucho tiempo entre 17.5 y 19.5ms        ; de cada 20ms, se pueden hacer otras cosas, entre un 85% y un 95%        ; del tiempo esta sin hacer nada para que se puedan hacer otras cosas  
   bcf  INTCON,2 ; aqui borra bandera interrupcion, se deja sin borrar en la          ; interrupcion para poder detectar en MAIN la interrupcion   
   bsf  INTCON,7 
   clrf CONTADOR_15 
   incf CONTADOR_16,f ; si, empieza en 135º 
   movlw .8 
   subwf CONTADOR_16,0 
   btfsc STATUS,Z ; van 8? 
   goto MAIN_RB120 
   call MOV_B130 ; no, sigue en 130º   
   goto MAIN_RB130  
MAIN_RB120   
   btfss INTCON,2 ; chequea si acabo la interrupcion, si pasaron 20ms   
   goto MAIN_RB120 ; sino acabo espera, aqui espera mucho tiempo entre 17.5 y 19.5ms        ; de cada 20ms, se pueden hacer otras cosas, entre un 85% y un 95%        ; del tiempo esta sin hacer nada para que se puedan hacer otras cosas  
   bcf  INTCON,2 ; aqui borra bandera interrupcion, se deja sin borrar en la          ; interrupcion para poder detectar en MAIN la interrupcion 
   bsf  INTCON,7 
   clrf CONTADOR_16 
   incf CONTADOR_17,f ; pasaron 50 veces empieza para 115º 
   movlw  .8  ; 25 es el numero de repeticiones para 115º 
   subwf CONTADOR_17,0 
   btfsc STATUS,Z ; van 8 veces? 
   goto MAIN_RB110 ; SI, va a siguiente   
   call  MOV_B120 ; no sigue en 120º 
   goto MAIN_RB120  
MAIN_RB110  btfss INTCON,2 ; chequea si acabo la interrupcion, si pasaron 20ms 
   goto MAIN_RB110 ; sino acabo espera, aqui espera mucho tiempo entre 17.5 y 19.5ms        ; de cada 20ms, se pueden hacer otras cosas, entre un 85% y un 95%        ; del tiempo esta sin hacer nada para que se puedan hacer otras cosas  
   bcf  INTCON,2 ; aqui borra bandera interrupcion, se deja sin borrar en la          ; interrupcion para poder detectar en MAIN la interrupcion   
   bsf  INTCON,7 
   clrf CONTADOR_17 
   incf CONTADOR_18,f ; si, empieza en 110º 
   movlw .8 
   subwf CONTADOR_18,0 
   btfsc STATUS,Z ; van 8? 
   goto MAIN_RB100 ; SI, va a siguiente posicion 
   call MOV_B110 ; no, sigue en 110º 
   goto MAIN_RB110 
MAIN_RB100 btfss INTCON,2 ; chequea si acabo la interrupcion, si pasaron 20ms 
   goto MAIN_RB100 ; sino acabo espera, aqui espera mucho tiempo entre 17.5 y 19.5ms        ; de cada 20ms, se pueden hacer otras cosas, entre un 85% y un 95%        ; del tiempo esta sin hacer nada para que se puedan hacer otras cosas  
   bcf  INTCON,2 ; aqui borra bandera interrupcion, se deja sin borrar en la          ; interrupcion para poder detectar en MAIN la interrupcion 
   bsf  INTCON,7
   clrf CONTADOR_18 ; se pone a 0 para proxima vez 
   incf CONTADOR_19,f ; pasaron 50 veces empieza para 100º 
   movlw  .8  ; 25 es el numero de repeticiones para 100º 
   subwf CONTADOR_19,0 
   btfsc STATUS,Z ; van 8 veces? 
   goto MAIN  ; si, va a posicion inicial, centra y empieza siguiente paso 
   call  MOV_B100 ; no sigue en 10º 
   goto MAIN_RB100 
;************DUTTY DE movimiento de centrado a 90º PORTA, PORTB******************************************  
CENT_SERVOS movlw 0x0F  ; ponemos dutty a 1 del PORTA y PORTB los servos estan conectados  
   iorwf PORTA,f  ; entre RA0>RA3 y RB0>RB3, el nibble bajo lo ponemos a 1111  
   iorwf PORTB,f  ; y al alto le aplicamos mascara para dejarlo como esta   
   movlw .13  ; cargamos 12 para que la demora sea de 1336us>90º  
   call DEMORA  ; durante 0.111 ms para movimientos de 10º aprox    
   movlw 0XF0  ; mascara para que no nos afecte al nibble alto  
   andwf PORTA,f  ; nos pone a 0 el nibble bajo donde tenemos los servos  
   andwf PORTB,f  ; y nos deja el valor del nibble alto como estaba  
   return   ; retorna a esperar el final de los 20ms  
;**************DUTTYS para movimientos servos PORTA de 10 en 10 grados*********************************** 
MOV_A100 movlw 0x0F  ; ponemos dutty a 1 del PORTA y PORTB estan conectados  
   iorwf PORTA,f  ; entre RA0>RA3 y RB0>RB3, el nibble bajo lo ponemos a 1111  
   iorwf PORTB,f  ; y al alto le aplicamos mascara para dejarlo como esta    
   movlw .13  ; para 90º, 9X0.111ms de los 90º +3x0.111ms de 0º segun MPLAB 1.336ms         ; "creo" que es aceptable el desfase de 36us, sino se corrige  
   call DEMORA  ; durante 0.111 ms para movimientos de 10º aprox       movlw 0XF0  ; mascara para que no nos afecte al nibble alto     
       ; nos pone a 0 el nibble bajo donde tenemos los servos  
   andwf PORTB,f  ; y nos deja el valor del nibble alto como estaba en PORTB  
   movlw .1  
   call DEMORA  ; hacemos un retardo mas para PORTA, asi se movera a 100º  
   movlw 0XF0  ; mascara para PORTA  
   andwf PORTA,f  ; nibble alto como estaba y bajo a 0   
   return   ;   
MOV_A110 movlw 0x0F  ; ponemos dutty a 1 del PORTA y PORTB estan conectados  
   iorwf PORTA,f  ; entre RA0>RA3 y RB0>RB3, el nibble bajo lo ponemos a 1111  
   iorwf PORTB,f  ; y al alto le aplicamos mascara para dejarlo como esta    
   movlw .13  ; para 90º  
   call DEMORA  ; durante 0.110 ms para movimientos de 10º aprox       movlw 0XF0  ; mascara para que no nos afecte al nibble alto     
     ; nos pone a 0 el nibble bajo donde tenemos los servos  
   andwf PORTB,f  ; y nos deja el valor del nibble alto como estaba en PORTB  
   movlw .2  ; cargamos 2 en w para tiempo adicional de PORTA de 0.222ms>20º  
   call DEMORA  ; hacemos 2 retardoS mas para PORTA, asi se movera a 100º  
   movlw 0XF0  ; mascara para PORTA  
   andwf PORTA,f  ; nibble alto como estaba y bajo a 0   
   return   ;   
MOV_A120 movlw 0x0F  ; ponemos dutty a 1 del PORTA y PORTB estan conectados  
   iorwf PORTA,f  ; entre RA0>RA3 y RB0>RB3, el nibble bajo lo ponemos a 1111  
   iorwf PORTB,f  ; y al alto le aplicamos mascara para dejarlo como esta    
   movlw .13  ; para 90º  
   call DEMORA  ; durante 0.111 ms para movimientos de 10º aprox       movlw 0XF0  ; mascara para que no nos afecte al nibble alto     
     ; nos pone a 0 el nibble bajo donde tenemos los servos  
   andwf PORTB,f  ; y nos deja el valor del nibble alto como estaba en PORTB  
   movlw .3  ; cargamos 3 en w para tiempo adicional de PORTA de 0.333ms>30º  
   call DEMORA  ; hacemos un retardo mas para PORTA, asi se movera a 120º  
   movlw 0XF0  ; mascara para PORTA  
   andwf PORTA,f  ; nibble alto como estaba y bajo a 0   
   return   ;  
MOV_A130 movlw 0x0F  ; ponemos dutty a 1 del PORTA y PORTB estan conectados  
   iorwf PORTA,f  ; entre RA0>RA3 y RB0>RB3, el nibble bajo lo ponemos a 1111  
   iorwf PORTB,f  ; y al alto le aplicamos mascara para dejarlo como esta    
   movlw .13  ; para 90º  
   call DEMORA  ; durante 0.111 ms para movimientos de 10º aprox       movlw 0XF0  ; mascara para que no nos afecte al nibble alto     
     ; nos pone a 0 el nibble bajo donde tenemos los servos  
   andwf PORTB,f  ; y nos deja el valor del nibble alto como estaba en PORTB  
   movlw .4  ; cargamos 4 en w para tiempo adicional de PORTA de 0.444ms>40º  
   call DEMORA  ; hacemos un retardo mas para PORTA, asi se movera a 130º  
   movlw 0XF0  ; mascara para PORTA  
   andwf PORTA,f  ; nibble alto como estaba y bajo a 0   
   return   ; 
MOV_A140 movlw 0x0F  ; ponemos dutty a 1 del PORTA y PORTB estan conectados  
   iorwf PORTA,f  ; entre RA0>RA3 y RB0>RB3, el nibble bajo lo ponemos a 1111  
   iorwf PORTB,f  ; y al alto le aplicamos mascara para dejarlo como esta    
   movlw .13  ; para 90º  
   call DEMORA  ; durante 0.111 ms para movimientos de 10º aprox       movlw 0xF0  ; mascara para que no nos afecte al nibble alto     
     ; nos pone a 0 el nibble bajo donde tenemos los servos  
   andwf PORTB,f  ; y nos deja el valor del nibble alto como estaba en PORTB  
   movlw .5  ; cargamos 5 en w para tiempo adicional de PORTA de 0.555ms>50º  
   call DEMORA  ; hacemos un retardo mas para PORTA, asi se movera a 140º  
   movlw 0XF0  ; mascara para PORTA  
   andwf PORTA,f  ; nibble alto como estaba y bajo a 0   
   return   ;   
;*****************DUTTYS para movimientos servos PORTB de 10 en 10 grados********************************** 
MOV_B100 movlw 0x0F  ; ponemos dutty a 1 del PORTA y PORTB estan conectados  
   iorwf PORTA,f  ; entre RA0>RA3 y RB0>RB3, el nibble bajo lo ponemos a 1111  
   iorwf PORTB,f  ; y al alto le aplicamos mascara para dejarlo como esta    
   movlw .13  ; para 90º  
   call DEMORA  ; durante 0.111 ms para movimientos de 10º aprox       movlw 0XF0  ; mascara para que no nos afecte al nibble alto     
     ; nos pone a 0 el nibble bajo donde tenemos los servos  
   andwf PORTA,f  ; y nos deja el valor del nibble alto como estaba en PORTA  
   movlw .1  ; aunque solo es una repeticion hay que cargar W porque tiene otro valor    call DEMORA  ; hacemos un retardo mas para PORTB, asi se movera a 100º  
   movlw 0XF0  ; mascara para PORTB  
   andwf PORTB,f  ; nibble alto como estaba y bajo a 0   
   return   ;  
MOV_B110 movlw 0x0F  ; ponemos dutty a 1 del PORTA y PORTB estan conectados  
   iorwf PORTA,f  ; entre RA0>RA3 y RB0>RB3, el nibble bajo lo ponemos a 1111  
   iorwf PORTB,f  ; y al alto le aplicamos mascara para dejarlo como esta    
   movlw .13  ; para 90º  
   call DEMORA  ; durante 0.111 ms para movimientos de 10º aprox       movlw 0XF0  ; mascara para que no nos afecte al nibble alto     
     ; nos pone a 0 el nibble bajo donde tenemos los servos  
   andwf PORTA,f  ; y nos deja el valor del nibble alto como estaba en PORTA  
   movlw .2  ; cargamos 2 en w para tiempo adicional de PORTA de 0.222ms>20º  
   call DEMORA  ; hacemos 2 retardoS mas para PORTB, asi se movera a 110º  
   movlw 0XF0  ; mascara para PORTA  
   andwf PORTB,f  ; nibble alto como estaba y bajo a 0   
   return   ;  
MOV_B120 movlw 0x0F  ; ponemos dutty a 1 del PORTA y PORTB estan conectados  
   iorwf PORTA,f  ; entre RA0>RA3 y RB0>RB3, el nibble bajo lo ponemos a 1111  
   iorwf PORTB,f  ; y al alto le aplicamos mascara para dejarlo como esta    
   movlw .13  ; para 90º  
   call DEMORA  ; durante 0.111 ms para movimientos de 10º aprox       movlw 0XF0  ; mascara para que no nos afecte al nibble alto     
     ; nos pone a 0 el nibble bajo donde tenemos los servos  
   andwf PORTA,f  ; y nos deja el valor del nibble alto como estaba en PORTA  
   movlw .3  ; cargamos 3 en w para tiempo adicional de PORTA de 0.330ms>30º  
   call DEMORA  ; hacemos un retardo mas para PORTB, asi se movera a 120º  
   movlw 0XF0  ; mascara para PORTA  
   andwf PORTB,f  ; nibble alto como estaba y bajo a 0   
   return   ;  
MOV_B130 movlw 0x0F  ; ponemos dutty a 1 del PORTA y PORTB estan conectados  
   iorwf PORTA,f  ; entre RA0>RA3 y RB0>RB3, el nibble bajo lo ponemos a 1111  
   iorwf PORTB,f  ; y al alto le aplicamos mascara para dejarlo como esta    
   movlw .13  ; para 90º  
   call DEMORA  ; durante 0.111 ms para movimientos de 10º aprox       movlw 0XF0  ; mascara para que no nos afecte al nibble alto     
     ; nos pone a 0 el nibble bajo donde tenemos los servos  
   andwf PORTA,f  ; y nos deja el valor del nibble alto como estaba en PORTA  
   movlw .4  ; cargamos 4 en w para tiempo adicional de PORTA de 0.444ms>40º  
   call DEMORA  ; hacemos un retardo mas para PORTA, asi se movera a 130º  
   movlw 0XF0  ; mascara para PORTB  
   andwf PORTB,f  ; nibble alto como estaba y bajo a 0   
   return   ;  
MOV_B140 movlw 0x0F  ; ponemos dutty a 1 del PORTA y PORTB estan conectados  
   iorwf PORTA,f  ; entre RA0>RA3 y RB0>RB3, el nibble bajo lo ponemos a 1111  
   iorwf PORTB,f  ; y al alto le aplicamos mascara para dejarlo como esta    
   movlw .13  ; para 90º  
   call DEMORA  ; durante 0.111 ms para movimientos de 10º aprox       movlw 0XF0  ; mascara para que no nos afecte al nibble alto     
     ; nos pone a 0 el nibble bajo donde tenemos los servos  
   andwf PORTA,f  ; y nos deja el valor del nibble alto como estaba en PORTA  
   movlw .5  ; cargamos 5 en w para tiempo adicional de PORTA de 0.555ms>50º  
   call DEMORA  ; hacemos un retardo mas para PORTA, asi se movera a 140º  
   movlw 0XF0  ; mascara para PORTB  
   andwf PORTB,f  ; nibble alto como estaba y bajo a 0   
   return   ;    
;************ Rutina de servicio de Interrupcion ************************ 
;********Aqui haremos copia de respaldo porque este programa ira integrado********* 
;*****************en otro mayor y puede afectar a dicho programa******************** 
;copia de registro W y STATUS
Inicio_ISR movwf W_Temp  ; Copiamos W a un registro Temporal. 
   swapf STATUS, W 
; Invertimos los nibles del registro STATUS. 
   movwf STATUS_Temp ; Guardamos STATUS en un registro temporal.
;**** Interrupcion por TMR0 ****
ISR   btfss INTCON,T0IF ; Consultamos si es por TMR0
   goto Fin_ISR  ; No, entonces restauramos valores
Actualizo_TMR0    ; Actualizo TMR0 para obtener una temporizacion de 20 ms. 
   movlw .100  ; d'100' 
   movwf TMR0 
   goto Fin_ISR  ; Restauro valores
; Restauramos los valores de W y STATUS
Fin_ISR  swapf STATUS_Temp,W ; Invertimos lo nibles de STATUS_Temp
   movwf STATUS 
   swapf W_Temp, f ; Invertimos los nibles y lo guardamos en el mismo registro
   swapf   W_Temp,W ; Invertimos los nibles nuevamente y lo guardamos en W
   return   ; Salimos de interrupción
     ;..........................................   
DEMORA     
     ; haremos demoras de 0.111ms equivalentes 10º del servo aprox 
  movwf PDel1  ; la demora multiplicara 0.111 por el numero que traiga w  
TOP1     movlw   .23       ; 1 set numero de repeticion         
  movwf   PDel0     ; 1 |
PLoop0   clrwdt              ; 1 clear watchdog        
  decfsz  PDel0, 1  ; 1 + (1) es el tiempo 0  ?        
  goto    PLoop0    ; 2 no, loop
PDelL1   goto  PDelL2         ; 2 ciclos delay
PDelL2   clrwdt              ; 1 ciclo delay            
  decfsz PDel1,1     
  goto TOP1        
  return               ; 2+2 Fin.  
  END

Aqui les adjunto una imagen de la implementacion que estoy realizando en el proteus :LOL:

http://img202.imageshack.us/i/servos8.jpg/

Ademas del Hexadecimal generado en el MPLAB:

[/URL]

Esperando sus sugerencias para terminar este proyecto, gracias :D
 
KanonOfGeminis: Puedes incluir una breve descripcion de cómo haces el control de los servos y qué tipo de servos son ?. La documentacion del codigo no es fácil de entender (por otra persona) justamente por faltar esa primera descripcion.

Saludos
 
Atrás
Arriba