Control de Servomotores en ASM
Hola, soy nuevo en el foro y navegando dentro de este foro decidi iniciar un 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 [/HTML] Aqui les adjunto una imagen de la implementacion que estoy realizando en el proteus xD http://img202.imageshack.us/img202/1179/servos8.jpg Ademas del Hexadecimal generado en el MPLAB: [URL="http://www.multiupload.com/?d=WOBHS9P0"]http://www.multiupload.com/?d=WOBHS9P0[/URL] Esperando sus sugerencias para terminar este proyecto, gracias :D |
La franja horaria es GMT +2. Ahora son las 07:11. |
Powered por vBulletin™ Version 3.8.10
Copyright © 2024 vBulletin Solutions, Inc. All rights reserved.
Traducido por vBsoporte - vBulletin en español
ZackYFileS - Foros de Debate