Codigo para posicionar servos con microcotrolador Pic
De Asociación de Robotica y Domótica de España (A.R.D.E.)
Codigo para posicionar servos con microcotrolador Pic
Según los valores colocados en DuServ1L-DuServ1H Posiciona el servo 1 de -90º para 0 a +90º para 1000. En DuServ2L-DuServ2H se coloca el valor del servo dos.
Siguiendo este procedimiento es muy sencillo llegar a los 8 servos.
Enviado por: Bactering
Fichero fuente original: Descargar
; Servo motor ; José Vte Mateo ;******************************************************************** ;El TMR1 en el modo temporizador. ;Revisión: 00.6 12-04-2007 Fin a la incorporación dos servos ; ;Salida Servo1 PORTB,0. Servo2 PORTB,1 ;******************************************************************** Servo equ 0x2d Comp equ 0x2e ;Valor a complementar Dutty equ 0x2f Dutty1L equ 0x30 Dutty1H equ 0x31 TimeL equ 0x32 TimeH equ 0x33 TempL equ 0x34 TempH equ 0x35 DuServ2L equ 0x36 DuServ2H equ 0x37 DuServ1L equ 0x38 ; de 0 a 1000 valor a carvar posición servo DuServ1H equ 0x39 ;de 0 a 1000 valor a carvar posición servo RESH equ 0x40 RESM equ 0x41 RESL equ 0x42 SUSH equ 0x44 SUSL equ 0x43 SUM1H equ 0x45 SUM1L equ 0x46 SUM2H equ 0x47 SUM2L equ 0x48 list p=16f877, f=INHX8M, r=hex include "p16f877.inc" org 0 goto Inicio org 4 ;******************************************************************** ;TMR1 trabaja con oscilador interno y preescaler de 1:8. Si se trabaja ;a una frecuencia de 4 MHz, TMR1 deberá ser cargado con 62500 para que ;provoque interrupción a los 0,5 segundos. ;******************************************************************** Inter: btfss PIR1,TMR1IF ; ¿Inter por TIMER1? retfie btfsc Servo,0 ; es el primer servo? goto Servo0 btfsc Servo,1 goto Servo1 retfie Servo0 btfss Dutty,0 ; esta activa la salida? goto FinServo0 nop nop bcf PORTB,0 call Resta ; tiempo que queda por estar a cero call Carga22 ;Desconecta el dutty servo 0 bcf Dutty,0 goto SalIntTiemr1 FinServo0 BCF Servo,0 BSF Servo,1 movfw Dutty1L movwf SUM1L movfw Dutty1H movwf SUM1H movfw DuServ2L movwf SUM2L movfw DuServ2H movwf SUM2H CALL Suma Call Carga22 bsf Dutty,1 ;Activa tiempo servo 1 bsf PORTB,1 ; ACTIVA EL SERVO goto SalIntTiemr1 Servo1 btfss Dutty,1 ; esta activa la salida? goto FinServo1 bcf PORTB,1 call Resta ; tiempo que queda por estar a cero Call Carga22 ;Desconecta el dutty servo 0 bcf Dutty,1 goto SalIntTiemr1 FinServo1 bcf Servo,1 ; desconecta el servo y conecta siguiente bsf Servo,0 movfw Dutty1L movwf SUM1L movfw Dutty1H movwf SUM1H movfw DuServ1L movwf SUM2L movfw DuServ1H movwf SUM2H CALL Suma Call Carga22 bsf Dutty,0 ;Activa tiempo servo 1 bsf PORTB,0 ; ACTIVA EL SERVO SalIntTiemr1 bcf PIR1,TMR1IF ;Desconecta el flag del TMR1 retfie ;¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿ ;Conversión analógica movfw ADRESL movwf DuServ2L movfw ADRESH movwf DuServ2H Inicio clrf PORTB ;Borra los latch de salida. ; Con una temporización de 991 se queda a -90º. movlw LOW .991 ;Carga en TMR1, en hexadecimal, movwf Dutty1L ;el complemento de 62500 decimal. movlw HIGH .991 ; " movwf Dutty1H movlw LOW .10000 ;Carga en TMR1, en hexadecimal, movwf TimeL ;el complemento de 62500 decimal. movlw HIGH .10000 ; " movwf TimeH ;_______________________________________________________________________________________ movlw LOW .251 ; | movwf DuServ1L ; | movlw HIGH .251 ; " | movwf DuServ1H ; | movlw LOW .751 ; | movwf DuServ2L ; | movlw HIGH .751 ; " | movwf DuServ2H ; | ;_______________________________________________________________________________________| bsf STATUS,RP0 ;Selecciona banco 1. clrf TRISB ;Puerto B: salida. movlw b'11111111' ;Preescaler = 128, asociado al WDT. movwf OPTION_REG ; " bsf PIE1,TMR1IE ;Habilita interrupción del TMR1. bcf STATUS,RP0 ;Selecciona banco 0. clrf PORTB clrf Dutty clrf Servo movfw Dutty1L movwf SUM1L movfw Dutty1H movwf SUM1H movfw DuServ1L movwf SUM2L movfw DuServ1H movwf SUM2H CALL Suma call Carga22 bsf Dutty,0 bsf Servo,0 bsf PORTB,0 ;activa salida ; " movlw b'11000000' ;Habilita interrupciones generales y de movwf INTCON ;periféricos. movlw b'00000001' ;Timer1 habilitado, reloj interno y 1:8 de movwf T1CON ;predivisión. Bucle: clrwdt ;Inicializa el Supervisor. goto Bucle ; Resta el intervalo del ciclo, Tiempo a cero del serco Resta clrf RESH ;Borra registros de resultados. clrf RESM ; " clrf RESL ; movfw Dutty1L movwf SUSL movfw Dutty1H movwf SUSH movf SUSL,W ;Carga el sustraendo bajo en W. subwf TimeL,W ;Ejecuta MINL - SUSL y deja en W el resultado. movwf RESL ;Carga resultado bajo en registro 42. btfsc STATUS,C ;¿Resultado negativo en operación anterior? goto uno ;No: salta a restar operandos altos. incf SUSH,F ;Sí: incrementa sustraendo alto. btfsc STATUS,Z ;¿Hay desbordamiento en incremento? decf RESH,F ;Sí: pone resultado en negativo. uno: movf SUSH,W ;No: carga sustraendo alto en W. subwf TimeH,W ;Resta bytes altos. movwf RESM ;Deja resultado alto en registro 41. btfss STATUS,C ;¿Resultado negativo en resta? decf RESH,F ;Sí: escribe resultado negativo. return ;Suma el valor mínimo del dutty a la posición del servo. Suma clrf RESL ;Borra registros de resultados. clrf RESM ; " clrf RESH ; " movf SUM1L,W ;Se carga en W el byte bajo del sumando 1. addwf SUM2L,W ;Se suman los bytes de menor peso. movwf RESL ;Se coloca el byte bajo del resultado. btfss STATUS,C ;¿Ha habido Acarreo en la suma anterior? goto DOS ;No: salta a sumar los bytes altos. incf SUM1H,F ;Sí: incrementa uno de los sumandos altos. btfsc STATUS,Z ;¿Hay desbordamiento en el incremento? incf RESH,F ;Sí: incrementa el resultado alto. DOS: movf SUM1H,W ;Carga en W uno de los sumandos altos. addwf SUM2H,W ;Suma los bytes de peso alto. movwf RESM ;Coloca en registro el resultado alto. btfsc STATUS,C ;¿Hay acarreo en la suma final? incf RESH,F ;Sí: incrementa resultado alto. return Carga22 movfw RESL ;Carga en TMR1, en hexadecimal, xorlw 0xff movwf TMR1L ;el complemento de 62500 decimal. movfw RESM ; " xorlw 0xFF movwf TMR1H return end
