Servos
Servos
TEORIA
Descripcin: El servo es un pequeo pero potente dispositivo que dispone en su interior de un pequeo motor con un reductor de velocidad y multiplicador de fuerza, tambin dispone de un pequeo circuito que gobierna el sistema. El recorrido del eje de salida es de 180 en la mayora de ellos, pero puede ser fcilmente modificado para tener un recorrido libre de 360 y actuar as como un motor. Funcionamiento: El control de posicin lo efecta el servo internamente mediante un potencimetro que va conectado mecnicamente al eje de salida y controla un pwm (modulador de anchura de pulsos) interno para as compararlo con la entrada pwm externa del servo, mediante un sistema diferencial, y asi modificar la posicin del eje de salida hasta que los valores se igualen y el servo pare en la posicin indicada, en esta posicin el motor del servo deja de consumir corriente y tan solo circula una pequea corriente hasta el circuito interno, si forzamos el servo (moviendo el eje de salida con la mano) en este momento el control diferencial interno lo detecta y enva la corriente necesaria al motor para corregir la posicin. Para controlar un servo tendremos que aplicar un pulso de duracin y frecuencia especficos. todos los servos disponen de tres cables dos para alimentacin Vcc y Gnd y otro cable para aplicar el tren de pulsos de control que harn que el circuito de control diferencial interno ponga el servo en la posicin indicada por la anchura del pulso. En la siguiente tabla estn indicados los valores de control y disposicin de cables de varias marcas que comercializan servos. Duracin pulso (ms) Fabricante min. neutral. mx.. Futaba 0.9 1.5 2.1 Hitech 0.9 1.5 2.1 Graupner/Jr 0.8 1.5 2.2 Multiplex 1.05 1.6 2.15 Robbe 0.65 1.3 1.95 Simprop 1.2 1.7 2.2 disposicin de cables + batt -batt pwm. rojo negro blanco rojo negro amarillo rojo marrn naranja rojo negro amarillo rojo negro blanco rojo azul negro
Hz 50 50 50 40 50 50
PRACTICA
Para hacer funcionar un servo por primera vez y ver su recorrido me tuve que idear una simple rutina con la que pude experimentar sin problemas con distintas duraciones de pulsos y as poder comprobar el recorrido del servo standard FutabaS3003 que compr por un precio de 3900 Pts. Mediante un interruptor introduciremos dos ordenes bsicas al pic que sern pon el servo en posicin de 0 y pon el servo en posicin de 180 con estas dos posiciones tendremos un circuito practico de comprobacin del recorrido de cualquier servo. El esquema de conexionado es el siguiente.:
La rutina se basa en un bucle continuo de comprobacin de la lnea RA0 a la que le he conectado un interruptor de palanca, si el interruptor esta abierto entonces llega un 0 lgico a RA0 y el servo gira hasta la posicin 0 y si el interruptor esta cerrado por tanto llega un 1 a RA0 y el servo gira a la posicin mxima de 180. El tren de impulsos saldr por la patita RB0 del PIC y conectar directamente con la entrada de pulsos del servo. La anchura del pulso viene definida por el retardo creado por software y que mantendr a nivel lgico 1 la salida durante la duracin de este. Una vez pase a nivel lgico 0 entrar en funcionamiento otra rutina de retardo con el tiempo suficiente para completar los 20 ms para obtener la frecuencia de 50 Hz necesaria, y se repetir el proceso indefinidamente. Los retardos han sido calculados con el programa CalDelay
servocrt.asm
Para descargar el archivo clikea sobre el armario, para verlo clikea sobre el texto
MOTORES CC
TEORIA
Descripcin: El motor elctrico es un dispositivo electromotriz, esto quiere decir que convierte la energa elctrica en energa motriz. Todos los motores disponen de un eje de salida para acoplar un engranaje, polea o mecanismo capaz de transmitir el movimiento creado por el motor. Funcionamiento: El funcionamiento de un motor se basa en la accin de campos magnticos opuestos que hacen girar el rotor (eje interno) en direccin opuesta al estator (imn externo o bobina), con lo que si sujetamos por medio de soportes o bridas la carcasa del motor el rotor con el eje de salida ser lo nico que gire. Para cambiar la direccin de giro en un motor de Corriente Continua tan solo tenemos que invertir la polaridad de la alimentacin del motor. Para modificar su velocidad podemos variar su tensin de alimentacin con lo que el motor perder velocidad, pero tambin perder par de giro (fuerza) o para no perder par en el eje de salida podemos hacer un circuito modulador de anchura de pulsos (pwm) con una salida a transistor de mas o menos potencia segn el motor utilizado.
PRACTICA
Descripcin: Control basado en el driver l293b de 4 canales capaz de proporcionar en cada una de sus salidas hasta 1A y dispone de entrada de alimentacin separada para los drivers. Funcionamiento: Cada canal o driver es controlado por medio de una seal de control compatible TTL (no superior a 7V) y los canales se habilitan de dos en dos por medio de las seales de control EN1 (canal 1 y 2) y EN2 (canal 3 y 4), en la siguiente tabla vemos el funcionamiento de las entradas y como responden las salidas. ENn H H L L INn H L H L OUTn H L Z Z
As pues, vemos que poniendo a nivel alto la entrada de habilitacin "EN" del driver, la salida de este "OUT" pasa de alta impedancia al mismo nivel que se encuentre la entrada del driver "IN" pero amplificado en tensin y en corriente, siendo esta de 1A mximo. La tensin de alimentacin del circuito integrado no es la misma que se aplica a las carga conectada a las salidas de los drivers, y para estas salidas se a de alimentar el driver por su patita nmero 8 (Vs), la tensin mxima aplicable a estas patitas es de 36V
Como este integrado no dispone de disipador, se recomienda hacer pasar una pista ancha de circuito impreso por las patitas de masa que junten todas estas y al mismo tiempo haga de pequeo disipador trmico, aunque para grandes cargas lo mejor es usar un disipador como el mostrado en la pagina 9 del datasheet. Aplicacin prctica: Con un L293B podemos tener control bidireccional con 2 motores o control unidireccional con 4 motores, a continuacin vamos a ver como se han de conectar los motores. Control Unidireccional: En la siguiente figura vemos las dos formas de conectar un motor para control unidireccional, M1 se activa al poner la entrada del driver conectado a este, a nivel bajo "0", mientras que M2 se activa al poner la entrada del driver a nivel alto "1" y se para al ponerla a nivel bajo "0".
La entrada enable es como un interruptor general y deber ponerse a nivel alto "1" para poder operar con los drivers que controla, o a nivel bajo "0" si se quiere desconectar el control de estos. "Vs" ser la tensin de alimentacin necesaria para los motores. Los diodos modelo 1N4007 son para proteger el circuito de los picos de arranque y parada de los motores debido a la corriente inversa inducida por estos. Control Bidireccional: En el siguiente circuito vemos el modo de conectar un motor para permitir controlarlo tanto hacia delante como hacia atrs.
Para tener el control de dos direcciones o bidireccional se usan dos de drivers del l293b conectando sus salidas a los polos del motor, entonces podremos cambiar la polaridad de alimentacin del motor con tan solo cambiar de estado las entradas de los drivers.
Por ejemplo, para que el motor gire hacia la derecha pondremos la entrada "A" a nivel alto "1" y "B" a nivel bajo "0" y para hacer girar el motor a la izquierda tendremos que invertir las seales de entrada de tal menera, la entrada "A" a nivel bajo "0" y "B" a nivel alto "1". Los diodos son como en el caso anterior para proteger el integrado de corrientes inversas.
MOTORES AC
MOTORES PaP
TEORIA Descripcin: Un motor Paso a Paso (PaP en adelante) se diferencia de un motor convencional en que en este se puede posicionar su eje en posiciones fijas o pasos, pudiendo mantener la posicin. Esta peculiaridad es debida a la construccin del motor en si, teniendo por un lado el rotor constituido por un imn permanente y por el otro el stator construido por bobinas, al alimentar estas bobinas se atraer el polo del magntico puesto rotor con respecto al polo generado por la bobina y este permanecer es esta posicin atrado por el campo magntico de la bobina hasta que esta deje de generar el campo magntico y se active otra bobina haciendo avanzar o retroceder el rotor variando los campos magnticos en torno al eje del motor y haciendo que este gire. Funcionamiento: Los motores PaP pueden ser de dos tipos, segn se muestra en la siguiente imagen:
Bipolar: Este tipo de motor lleva dos bobinados independientes el uno del otro, para controlar este motor se necesita invertir la polaridad de cada una de las bobinas en la secuencia adecuada, para esto necesitaremos usar un puente en "H" o driver tipo L293b para cada bobina y de este modo tendremos una tabla de secuencias como la siguiente: Paso 1 A +Vcc B Gnd C +Vcc D Gnd
2 3 4
Cada inversin en la polaridad provoca el movimiento del eje, avanzando este un paso, la direccin de giro se corresponde con la direccin de la secuencia de pasos, por ejemplo para avanzar el sentido horario la secencia seria 1-2-3-4,1-2-3-4.... y para sentido anti-horario seria; 4-3-2-1,-4-3-2-1... Unipolar: El motor unipolar normalmente dispone de 5 o 6 cables dependiendo si el comn esta unido internamente o no, para controlar este tipo de motores existen tres mtodos con sus correspondientes secuencias de encendido de bobinas, el comn ir conectado a +Vcc o masa segn el circuito de control usado y luego tan solo tendremos que alimentar la bobina correcta para que avance o retroceda el motor segn avancemos o retrocedamos en la secuencia. Las secuencias son las siguientes: Paso A B C D
1
Paso simple: Esta secuencia de pasos es la mas simple de todas y consiste en activar cada bobina una a una y por separado, con esta secuencia de encendido de bobinas no se obtiene mucha fuerza ya que solo es una bobina cada vez la que arrastra y sujeta el rotor del eje del motor
1000
0100
0010
0001
Paso doble:
Paso
A B C D
Con el paso doble activamos las bobinas de dos en dos con lo que hacemos un campo magntico mas potente que atraer con mas fuera y retendr el rotor del motor en el sitio. Los pasos tambin sern algo mas bruscos debidos a que la accin del campo magntico es mas poderosa que en la secuencia anterior, pero
1100
0110
0011
1001
Paso
B C D
Medio Paso: Combinando los dos tipos de secuencias anteriores podemos hacer moverse al motor en pasos mas pequeos y precisos y as pues tenemos el doble de pasos de movimiento para el recorrido total de 360 del motor.
1 000
1 100
0 100
0 110
0 010
0 011
0 001
1 001
PRACTICA
Unipolar: Para controlar un motor paso a paso unipolar deberemos alimentar el comn del motor con Vcc y conmutaremos con masa en los cables del devanado correspondiente con lo que haremos pasar la corriente por la bobina del motor adecuada y esta generar un campo electromagntico que atraer el polo magnetizado del rotor y el eje del mismo girar. Para hacer esto podemos usar transistores montados en configuracin Darlington o usar un circuito integrado como el ULN2003 que ya los lleva integrados en su interior aunque la corriente que aguanta este integrado es baja y si queremos controlar motores mas potentes deberemos montar nosotros mismos el circuito de control a base de transistores de potencia. El esquema de uso del ULN2003 para un motor unipolar es el siguiente:
Las entradas son TTL y se activan a nivel alto, tambin disponen de resistencias de polarizacin internas con lo que no deberemos de preocuparnos de esto y podremos dejar "al aire" las entradas no utilizadas. Las salidas son en colector abierto. Bipolar: Para el control de motor bipolar usaremos un puente en H para invertir la polaridad de los devanados, tambin podemos usar un circuito integrado tipo L293b que contiene un puente en H integrado. El esquema ser similar al siguiente:
n var byte portb=0 inicio: for n=50 to 250 step 1 pulsout portb.0,100 pause 100 next for n=50 to 250 step 1 pulsout portb.0,150 pause 100 next goto inicio end
Este codigo en proteus funciona perfectamente, pero luego en la placa de prototipado no funciona. El esquema que monto es el siguiente (va en paint porque ahora no tengo eagle)
A continuacin se puede observar el primer circuito que vamos a utilizar: Primera prueba de control de un servo RC
En el circuito se pueden apreciar los pocos elementos que estamos utilizando en esta primera prueba. Se trata del PIC, que como funciona con su generador interno de reloj de 4 MHz no requiere de un cristal; el enchufe para el servo; y tres pequeos pulsadores. Los resistores son para polarizar a un valor positivo, o valor lgico 1, las entradas del PIC que se utilizan para "leer" los pulsadores. Los pulsadores llevan este nivel a lgico 0, o tierra, cuando se los presiona. Montaje del circuito bsico de control de un servo RC
Como se ve en la foto, al servo le hemos colocado un crculo de cartulina con una lnea negra que nos servir como indicador de su posicin. Los tres pulsadores que se observan en la foto corresponden, de izquierda a derecha, a "pulsador 1", "pulsador 2" y "pulsador 3" en el circuito. El pulsador 1 servir para llevar al servo a su posicin central, o "neutra". Con el pulsador 2 se har avanzar lentamente al servo en sentido antihorario, y con el pulsador 3 se lo har girar, de a poco, en sentido horario. Este circuito, y el programa asociado en el PIC, no cumplen otro propsito que el de dar una primera aproximacin al mtodo de programa utilizado para controlar a este tipo de servos. En las pruebas siguientes iremos avanzando hasta llegar a una sofisticacin y utilidad mucho mayor. Programa bsico de control de servos RC
;********************************************************************** ; MANEJO DE SERVOS - Programa Bsico 1 ; Por Eduardo J. Carletti, Robots Argentina, 2007 ;********************************************************************** list p=16F628A ; definir procesador ; definiciones de variables especficas ; para evitar los mensajes de cambio de ; banco en el resultado del compilador
_INTRC_OSC_NOCLKOUT & _MCLRE_OFF ;***** DEFINICIN DEL NOMBRE DE ENTRADAS Y SALIDAS #define 1 #define #define #define SERVO1 PULSADOR1 PULSADOR2 PULSADOR3 PORTA,0 PORTA,1 PORTA,2 PORTA,3 ; puerto de salida de servo ; puerto de entrada de pulsador 1 ; puerto de entrada de pulsador 2 ; puerto de entrada de pulsador 3
;***** VARIABLES CBLOCK 0x20 acum_A Posic ENDC ; variable momentnea ; posicin servo
;************************************************************************ *********** ; Principal ;************************************************************************ *********** principal movlw b'00000111' movwf CMCON clrf PORTA clrf PORTB bsf STATUS,RP0 movlw b'00001110' movwf TRISA MOVLW b'00000000' movwf TRISB movlw b'00000010' movwf OPTION_REG es ; de 1 MHz si el oscilador es de 4 MHz). ; El contador cuenta cada 8 useg ; deshabilita comparadores. Esto es ; algo importante en el PIC 16F628A ; inicia ports ; inicia ports ; Apunta a banco 1 ; PORTA ; salidas menos 1, 2 y 3, entradas ; PORTB ; salidas ; Configuracin para TMR0 ; preescaler 2, 1:8 con CLK interno (que
;************************************************************************ *********** ; Lazo principal ;************************************************************************ *********** lazo ; Los servos actan 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 mnimo del pulso. ; Con este valor de longitud de pulso y una longitud cero en la parte variable, ; el servo est parado al mximo hacia la izquierda (sentido antihorario). bsf bcf movlw movwf btfss goto bcf ; ; ; ; ms movwf btfss goto bcf bcf TMR0 INTCON,T0IF $-1 SERVO1 INTCON,T0IF ; valor al registro de timer ; espera por timer = ff -> 00 ; pone la seal de servo en 0 ; borra el flag de timer SERVO1 INTCON,T0IF d'192' TMR0 INTCON,T0IF $-1 INTCON,T0IF ; ; ; ; ; pone la seal de servo en 1 borra el flag de timer (256-192 = 64) 64 * 8 us = 0,512 ms valor al registro de timer espera por timer = ff -> 00
A continuacin, 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 vara entre 0 y 2 ms movf Posic,w ; 256-nn x 8 uS = 1 ms, 1,5 ms, 2,5
; Retardo de 20 ms, que es el tiempo estndar que debe separar los pulsos ; de control para los servos comunes de RC
; cantidad de veces: 9 x 2 ms = 18 ms + 2
movwf acum_A 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 ; lee rdenes a travs de pulsadores btfss PULSADOR1 goto iniciaPos btfss PULSADOR2 goto incPos btfss PULSADOR3 goto decPos goto lazo ; servo en posicin central ; incrementa Posic ; decrementa Posic
pulsadores
iniciaPos 512 us
; 256-133 = 123, 123 * 8 us = 984 us + ; posicin central en esta disposicin ; y sale ; ; ; ; se fija si Posic ya es cero si es cero no decrementa si no es cero, decrementa y sale
movf Posic,f bz sale1 decf Posic,f goto lazo movlw 0xFF xorwf Posic,w bz sale2 incf Posic,f goto lazo END
sale2
; se fija si Posic no es 0xFF ; que es el valor mximo ; si es el valor mximo, no incrementa ; si no es el valor mx, incrementa ; y sale
Bajar el programa en formato ASM (puede usar el botn derecho de su mouse) Bajar el programa en formato HEX (puede usar el botn derecho de su mouse) Por las dudas, el archivo incluido P16f628a.inc (puede usar el botn derecho de su mouse) Diagrama de flujo del programa de control de un servo RC
Espero que en este programa se pueda ver con claridad la manera de generar el pulso con los tiempos correctos. De hecho, lo hemos escrito lo ms simple posible por esta razn. Pero la verdad es que esta forma de hacerlo tiene el defecto de que mientras se producen los retardos, el microcontrolador est en un lazo cerrado, dedicado exclusivamente a esperar que se cumplan los tiempos. Cmo se soluciona esto? Haciendo que los retardos se produzcan mientras el microcontrolador est haciendo otra cosa. Y para hacer esto se debe utilizar una de las herramientas ms potentes y necesarias en un sistema que debe ser sensible a sucesos producidos en el mundo real: las interrupciones.
Controlar un servomotor de modelismo con un microcontrolador pic 16f628A mediante 2 pulsadores y indicador luminoso
Con este circuito podemos situar la posicion de un servomotor de los usados en modelismo en 256 posiciones diferentes, la cual se reflejara sobre 8 diodos LED. Manteniendo presionado el pulsador IZQ o DER variaremos la posicion sel servo en un sentido u otro, al mismo tiempo de que los led van indicando secuencias diferentes. Aproximadamente mediante la actuacion de estos 2 pulsadores tardara 50seg el servomotor en realizar todo el recorrido, pero si actuamos al mismo tiempo sobre el pulsador TURBO, se reducira este tiempo a solo 5seg. Tenemos la posibilidad de accionarlo mediante los microswitch, y llevar al servo a unas posiciones concretas sin necesidad de tener que verlo. Con los pulsadores IZQ y DER llevaremos el servo a la posicion deseada, en donde observaremos los LED que permanecen encendidos, colocando en la posicion de ON los microinterruptoes que coincidan con los LED encendidos, de modo que independientemente de donde se encuentre el servo, este regresara a esa posicion siempre que actuemos sobre el pulsador SELEC. Incluso podemos dejar continuamente presionado SELEC y mediante los microinterruptores controlar al servomotor.
Como podeis apreciar en el Esquema el microcontrolador funciona sin el tipico cristal de cuarzo de 4Mhz. Prestar atencion a los valores de las resistencias R1 a R16, ya que son valores criticos para que los microinterruptores polaricen adecuadamente las entradas del PIC.
El que desee ampliar los conocimientos sobre servomotores puede acudir a la WIKIPEDIA. En la imagen se representan los tiempos del pulso generado en funcion de la posicion que queramos adquirir. Estos tiempos de funcionamiento no son estandar para todas las marcas de servomotores, de modo que segun el modelo que utiliceis, os encontrreis con el problema que no alacanza la totalidad del recorrido de los 180 o bien que esteis sobrepasando el limite inferior o superior, haciendo que el servomotor se vuelva muy inestable. Los tiempos utilizados para este circuito, NO corresponden con los de la imagen, aunque os indirare mas adelante como modificarlos.
En la siguiente tabla se representan algunos fabricantes de servomotores y los tiempos que utilizan para posicionar al servo en una posicion determinada, asi como los colores de los cables empleados. Duracin pulso (ms) Fabricante min. neutral. mx.. Futaba 0.9 1.5 2.1 Hitech 0.9 1. 5 2. 1 Graupner/Jr 0.8 1.5 2.2 Multiplex 1.05 1.6 2.15 Robbe 0.65 1.3 1.95 Simprop 1.2 1.7 2.2 disposicin de cables + batt - batt pwm. rojo negro blanco rojo negro amarillo rojo marrn naranja rojo negro amarillo rojo negro blanco rojo azul negro
Hz 50 50 50 40 50 50
En mi caso para los servomotores que yo disponia en ese momento utilice un tiempo minimo de 550ms, los cuales podeis modificar en ensamblador en la parte del programa: bucle_2 bsf call call call
Salida ;pongo en alto la salida Retardo_300micros ;tiempo minimo de 550 us Retardo_200micros Retardo_50micros
Como el tiempo del pulso lo puedo seleccionar en 256 valores diferentes, he utilizado un multiplo de tiempo de 7useg. Por lo tanto 7us X 256 = 1792useg, los cuales sumados a los 550us minimos, nos dan un total de 2342useg o 2,34 mseg.
Para variar el tiempo maximo solo teneis que variar el multiplo de 7us en la siguiente parte del programa ,quitando o aadiendo instrucciones NOP, las cuales afectan en el tiempo 1micro segundo: Tiempo nop nop nop nop ;nop ; 4us ; 5us ; 6us ; 7us ; 8us no utilizado
Podeis descargar el archivo generado por Proteus y el codigo Hex para su montaje o simulacion. Para aquellos que sepan programar en Ensamblador tambien teneis el archivo ASM por si quereis realizar alguna modificacion.
;controlar un servomotor con un microcontrolador pic ; ; | | | | | | | | | | | | ; _|__|__|__|__|__|__|__|__|__|__|__|_ _\\|//_ Jose ; | | (| o-o |) Martinez ; | www.microcontroladorespic.com | \ (_) / Ortiz ; |) | \_"_/ ; | Control de servomotor en 256 | __|U|__ ; | posiciones con el pic 16f628A | / \ ; |_ __ __ __ __ __ __ __ __ __ __ __ _| / /| |\ \ ; | | | | | | | | | | | | / / | | \ \ ; | | | | | | | | | | | | "" |___| "" ;
; DESCRIPCION ;Generamos una seal comprendida entre un tiempo de .55ms y 2,34mseg, pudiendo ;regular este tiempo en 256 intervalos de 7useg. ;con los 7us consegimos un tiempo maximo de 1792usg para alcanzar los 2,34ms ;El programa arranca con el servo en la posicion central ;************************ BITS DE CONFIGURACION ************************* ;CP_OFF - Codigo de proteccion programa desactivado ;CPD_OFF - Codigo de proteccion eeprom desactivado ;WDT_OFF - Perro guardian desconectado ;BODEN_OFF - No actua el reset por bajada de tension ;PWRTE_OFF - Reset de inicio desconectado ;MCLRE_OFF - Reset externo desconectado, sino pierdo una entrada A5 ;XT_OSC - oscilador exterior ;INTOSC_OSC_NOCLKOUT - funcionamiento con reloj interno ;LVP_OFF - programacion de bajo voltage desconectado, ; para activar el pin 4 de RB __CONFIG _LVP_OFF & _MCLRE_OFF & _BODEN_OFF & _CP_OFF & _PWRTE_ON & _WDT_OFF & _INTOSC_OSC_NOCLKOUT LIST P=16F628A INCLUDE <P16F628A.INC> ERRORLEVEL 0, -302 ;Procesador utilizado. ;suppress bank selection messages
;****************************** ZONA DE DATOS #define Banco0 bcf STATUS,RP0 #define Banco1 bsf STATUS,RP0 #define #define #define #define #define #define #define #define #define #define #define #define #define #define #define #define #define #define #define #define #define Salida Pulsador_IZQ Pulsador_DER Selec Pulsador_Vel Led_0 Led_1 Led_2 Led_3 Led_4 Led_5 Led_6 Led_7 Pulsador_0 Pulsador_1 Pulsador_2 Pulsador_3 Pulsador_4 Pulsador_5 Pulsador_6 Pulsador_7 PORTA,0 PORTA,3 PORTA,4 PORTA,5 PORTA,2 PORTB,0 PORTB,1 PORTB,2 PORTB,3 PORTB,4 PORTB,5 PORTB,6 PORTB,7 PORTB,0 PORTB,1 PORTB,2 PORTB,3 PORTB,4 PORTB,5 PORTB,6 PORTB,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 bsf Pulsador_DER bsf Pulsador_IZQ bsf Selec bsf Pulsador_Vel bcf bcf bcf bcf bcf Salida Led_0 Led_1 Led_2 Led_3 ;Acceso al Banco 1. ;entradas
;salidas
bcf bcf bcf bcf bcf Banco0 movlw movwf clrf clrf clrf movlw movwf goto
Led_4 Led_5 Led_6 Led_7 OPTION_REG,NOT_RBPU ;Activa las resistencias Pull-Up del Puerto B ;Acceso al Banco 0. 0x07 CMCON contador contador_ velocidad .128 contador principal ;desconecta los comparadores analogicos del ;pic 16f628
Entradas Banco1 bsf Pulsador_0 bsf Pulsador_1 bsf Pulsador_2 bsf Pulsador_3 bsf Pulsador_4 bsf Pulsador_5 bsf Pulsador_6 bsf Pulsador_7 Banco0 return Salidas Banco1 bcf Led_0 bcf Led_1 bcf Led_2 bcf Led_3 bcf Led_4 bcf Led_5 bcf Led_6 bcf Led_7 Banco0 return Led_OFF bsf Led_0 bsf Led_1 bsf Led_2 bsf Led_3 bsf Led_4 bsf Led_5 bsf Led_6 bsf Led_7 return Led_ON bcf bcf bcf bcf Led_0 Led_1 Led_2 Led_3
;Acceso al Banco 0.
;Acceso al Banco 0.
;led apagados
;led encendidos
bcf Led_4 bcf Led_5 bcf Led_6 bcf Led_7 return ;****************************************************************************** ;************************* PRINCIPAL **************************** ;****************************************************************************** principal bcf Salida ;a nivel bajo goto bucle_1 call call call call call call call call call call call call bucle_1 btfss call btfsc call movlw movwf Led_ON Retardo_500ms Led_OFF Retardo_500ms Led_ON Retardo_500ms Led_OFF Retardo_500ms Led_ON Retardo_500ms Led_OFF Retardo_500ms Selec microswitch Selec pulsadores 0x0A velocidad ;10 veces x 20ms =200ms ;veces que manda la seal antes de actualizarla ;efectos luminosos NO UTILIZADOS (goto detante)
;************************* SEAL DE SALIDA bucle_2 bsf Salida ;pongo en alto la salida call Retardo_300micros ;tiempo minimo de 550 us call Retardo_200micros call Retardo_50micros call bcf call call btfss goto decfsz goto goto TEMPO Salida Retardo_10ms Retardo_5ms Pulsador_Vel bucle_1 ;incremento el tiempo seleccionado ;pongo la salida en bajo ;tiempo para completar un ciclo conpleto ;tiempo para completar un ciclo conpleto ;si esta pulsado contara mas rapido
velocidad,F ;decrementa el contador bucle_2 ;vuelve a mandar el mismo pulso bucle_1 ;vuelvo a repetir esta secuencia
;****************************************************************************** ;************************* PULSADORES **************************** ;****************************************************************************** pulsadores call Salidas ;configuro el puerto para encender los led
;apago todos los led ;el valor del contador lo paso ;invierto todos los bit a los led
;salta si vale 1
incf contador,F movf contador,W btfss STATUS,Z RETURN movlw 0xFF movwf contador RETURN Restar movf contador,F btfsc STATUS,Z return decfsz contador,F nop RETURN
; rutina de incremento ; incremento las unidades ;Mira si vale cero ;vuelvo a dejarlo en 256 ;se carga sobre si mismo ;Mira si vale cero ;regresa si vale cero ;decrementa el contador ;importante, para que no me salte el return.
;****************************************************************************** ;************************* MICROSWITCH **************************** ;****************************************************************************** microswitch call Entradas ;configuro el puerto para leer los microswitch movf PORTB,W xorlw 0xFF movwf contador return ;****************************************************************************** ;************************* MEDIR TIEMPO **************************** ;****************************************************************************** ;cada unidad del contador_ equivale a un tiempo de 4us TEMPO movf contador,W movwf contador_ movf btfsc return Tiempo nop nop nop nop ; nop decfsz contador_,F contador_,F STATUS,Z ;se carga sobre si mismo ;Mira si vale cero ;regresa si vale cero ; ; ; ; ; 4us 5us 6us 7us 8us
no utilizado 1us
;decrementa el contador
goto return
Tiempo
3us
;****************************************************************************** ;************************* 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
Control de un servo - Prueba 02: Control con interrupciones por Eduardo J. Carletti
Esta es la segunda etapa de un grupo de pruebas de laboratorio en las que implementamos el control de servos de modelismo por medio de un microcontrolador PIC. Si usted ha llegado directamente a este artculo, sepa que para tener una idea completa de cmo venimos trabajando con este desarrollo debera ver antes la primera parte de la serie, Control de un servo Prueba 01: Control bsico. Si bien el programa de la primera parte funciona y es simple, y permite ver con claridad la manera de generar el pulso con los tiempos correctos, la verdad es que esa manera de solucionar el control de servos tiene el defecto de que mientras se producen los retardos, el microcontrolador est en un lazo cerrado, dedicado exclusivamente a esperar que se cumplan los tiempos.
Servos de modelismo o RC
Cmo se soluciona esto? Haciendo que los retardos se produzcan mientras el microcontrolador est haciendo otra cosa. Y para hacerlo se debe utilizar una de las herramientas ms potentes en un sistema que debe ser sensible a sucesos producidos en el mundo real: las interrupciones. El circuito que vamos a utilizar sigue siendo el mismo de la primera parte: Segunda prueba de control de un servo RC
La foto que sigue nos permite apreciar la simplicidad del circuito. Podemos ver un integrado de 18 patas, que es el PIC16F628A (sin cristal, porque funciona con su generador interno de reloj de 4 MHz); el enchufe estndar de tres patas para el servo; y tres pequeos pulsadores. Los resistores son para polarizar las entradas del PIC que se utilizan para "leer" los pulsadores a un valor positivo, o valor lgico 1. Los pulsadores llevan este nivel a lgico 0, o tierra, cuando se los presiona. Montaje del circuito bsico de control de un servo RC
Al servo le hemos colocado un crculo de cartulina con una lnea que facilita la visualizacin de su posicin. Los tres cuadrados negros pequeos son los pulsadores, que corresponden, de izquierda a derecha, a "pulsador 1", "pulsador 2" y "pulsador 3" en el circuito. El pulsador 1 servir para llevar al servo a su posicin central, o "neutra". Con el pulsador 2 se har avanzar al servo en sentido antihorario, y con el pulsador 3 se lo har girar en sentido horario. Programa de control de servos RC con interrupciones
;********************************************************************** ; MANEJO DE SERVOS - Programa Bsico 2 - Manejo con interrupciones ; Por Eduardo J. Carletti, Robots Argentina, 2007 ;********************************************************************** list p=16F628A ; definir procesador ; definiciones de variables especficas ; 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
;***** DEFINICIN DEL NOMBRE DE ENTRADAS Y SALIDAS #define 1 #define #define #define SERVO1 PULSADOR1 PULSADOR2 PULSADOR3 PORTA,0 PORTA,1 PORTA,2 PORTA,3 ; puerto de salida de servo ; puerto de entrada de pulsador 1 ; puerto de entrada de pulsador 2 ; puerto de entrada de pulsador 3
;***** VARIABLES CBLOCK 0x20 acum_A ; Posic ; fase ; Guardar_STATUS Guardar_W ; ENDC variable momentnea posicin servo fase de programa para interrupcin ; Guardar Status Guardar W
;************************************************************************ *********** org goto org goto 0x000 principal 0x004 interrupcion
;************************************************************************ *********** ; Principal ;************************************************************************ *********** principal movlw b'00000111' movwf CMCON clrf PORTA clrf PORTB bsf STATUS,RP0 movlw b'00001110' movwf TRISA MOVLW b'00000000' movwf TRISB movlw b'00000010' movwf OPTION_REG es ; deshabilita comparadores. Esto es ; algo importante en el PIC 16F628A ; inicia ports ; inicia ports ; Apunta a banco 1 ; PORTA ; salidas menos 1, 2 y 3, entradas ; PORTB ; salidas ; Configuracin para TMR0 ; preescaler 2, 1:8 con CLK interno (que
; de 1 MHz si el oscilador es de 4 MHz). ; El contador cuenta cada 8 useg bcf STATUS,RP0 clrf (centro) movwf Posic clrf fase ; inicia para que comience con la fase 0 ; Interrupciones habilitadas ; GIE (global), T0IE (timer 0) ; Interrupcin General, Interrupcin TMR0 ; Apunta a banco 0 ; inicia registro de timer en 0 ; inicia valor de posicin de servo
movlw d'133'
;************************************************************************ *********** ; Lazo principal ;************************************************************************ *********** lazo movf bz goto fase,f fase0 lazo
;************************************************************************ *********** ; Rutina de apoyo ;************************************************************************ *********** ; Fase 0: Los servos actan 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 mnimo del pulso. ; Con este valor de longitud de pulso y una longitud cero en la parte variable, ; el servo est parado al mximo hacia la izquierda (sentido antihorario). fase0 bsf SERVO1 bcf INTCON,T0IF movlw d'192' ; pone la seal de servo en 1 ; borra el flag de timer ; (256-192 = 64) 64 * 8 us = 0,512 ms
;************************************************************************ *********** ; Manejo interrupciones ;************************************************************************ *********** interrupcion ; Salva todo bcf movwf swapf movwf ; distribuidor movf xorlw bz movf xorlw bz movf xorlw bz goto ; ; ; ; INTCON,T0IE ; deshabilita interrupcin de timer Guardar_W STATUS, w Guardar_STATUS fase,w 0x01 fase1 fase,w 0x02 fase2 fase,w 0x03 fase3 salidaint
Fase 1: Aqu 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 vara entre 0 y 2 ms movf Posic,w ; 256-nn x 8 uS = 1 ms, 1,5 ms, 2,5 ; valor al registro de timer ; pasa a fase 2
fase1 ms
; Fase 2: Retardo de 20 ms, que es el tiempo estndar que debe separar los pulsos ; de control para los servos comunes de RC fase2 bcf bsf movlw movwf SERVO1 STATUS,RP0 b'00000111' OPTION_REG ; ; ; ; pone la seal de servo en 0 Apunta a banco 1 Configuracin para TMR0 preescaler 7, 1:256 con CLK interno
(que es bcf STATUS,RP0 movlw d'249' ms pulso movwf TMR0 incf fase,f goto salidaint ; valor al registro de timer ; pasa a fase 3 ; de 1 MHz si el oscilador es de 4 MHz). ; El contador cuenta cada 256 useg ; Apunta a banco 0 ; (256-249 = 7) 7 * 256 us = 17,92 ms + 2
; Fase 3: Como en el bloque de la fase 2 cambi el prescaler del timer a 7, ahora ; debe reponerlo al valor de un conteo cada 8 useg, y volver al estado de fase = 0, ; con lo cual el ciclo se reinicia. Tambin hemos insertado en esta fase, que se ; ejecuta cada 20 ms aproximadamente, la lectura de los pulsadores. fase3 bsf STATUS,RP0 movlw b'00000010' movwf OPTION_REG es bcf clrf pulsadores ; lee btfss goto btfss goto btfss goto goto STATUS,RP0 fase ; ; ; ; de 1 MHz si el oscilador es de 4 MHz). El contador cuenta cada 8 useg Apunta a banco 0 pasa a fase 0 ; Apunta a banco 1 ; Configuracin para TMR0 ; preescaler 2, 1:8 con CLK interno (que
rdenes a travs de pulsadores PULSADOR1 iniciaPos ; servo en posicin central PULSADOR2 incPos ; incrementa Posic PULSADOR3 decPos ; decrementa Posic salidaint
;************************************************************************ *********** ; Rutinas de apoyo ;************************************************************************ *********** iniciaPos 512 us movlw d'133' movwf Posic goto salidaint decPos movf Posic,f ; 256-133 = 123, 123 * 8 us = 984 us + ; posicin central en esta disposicin ; y sale ; se fija si Posic ya es cero
sale1 incPos
bz sale1 decf Posic,f goto salidaint movlw 0xFF xorwf Posic,w bz sale2 incf Posic,f goto salidaint
; si es cero no decrementa ; si no es cero, decrementa ; y sale ; se fija si Posic no es 0xFF ; que es el valor mximo ; si es el valor mximo, no incrementa ; si no es el valor mx, incrementa ; y sale
sale2
; Regresa todo salidaint bcf INTCON,T0IF ; borra el flag de timer swapf Guardar_STATUS, w movwf STATUS swapf Guardar_W, f swapf Guardar_W, w bsf INTCON,T0IE ; habilita interrupcin de timer retfie ; retorna END
Bajar el programa en formato ASM (puede usar el botn derecho de su mouse) Bajar el programa en formato HEX (puede usar el botn derecho de su mouse) Por las dudas, el archivo incluido P16f628a.inc (puede usar el botn derecho de su mouse) Para que el lector no deba buscar con lupa los cambios (aunque algunos son muy evidentes), listaremos qu es lo que debimos cambiar para que el PIC funcione con interrupciones. En primer lugar, se observa el agregado de tres variables: "fase", que nos servir para que cuando entremos a la rutina de manejo de interrupcin podamos saber en qu parte del pulso estamos, y las variables "Guardar_W" y "Guardar_STATUS", en las que nuestra rutina de interrupcin reservar estos dos importantes valores (registro STATUS y registro W, o acumulador), para que cuando regrese al sitio de programa donde se produjo la interrupcin las cosas estn tal cual estaban al salir. En segundo lugar notaremos la declaracin "org 0x004", seguida de la instruccin "goto interrupcion". Con este valor se define (para el funcionamiento interno del PIC) dnde est la rutina que se ejecutar cuando aparezca una interrupcin. Ntese que en la parte final del programa la palabra "interrupcion" es la etiqueta que seala la rutina de manejo de las interrupciones. En tercer lugar encontramos, hacia el final de la parte de inicializacin de sistema, puertos y variables (justo antes de entrar al lazo principal), la habilitacin del funcionamiento en base a interrupciones, que se logra al definir valores del registro de control de interrupciones, INTCON. El valor que definimos tiene el bit 7 en 1, que significa que se habilita el funcionamiento de interrupcin a nivel gobal (el bit es GIE, Global Interrupt Enable); y el bit 5 en 1, que significa que habilitamos la interrupcin por sobrepaso (overflow) del timer 0 (cero). Esto significa una interrupcin cada vez que el registro del timer 0 cuente hasta su valor mximo, que es 255 hexadecimal 0xFF, y pase de nuevo a cero. Nosotros usaremos esta caracterstica para colocar distintos valores en el registro, que avanza de valor a un ritmo conocido por nosotros, de manera de lograr retardos controlados y exactos. Como se ve, con dos bits solamente hemos cambiado del todo el funcionamiento de nuestro microcontrolador.
El siguiente cambio en el programa, ste s muy evidente, es en la rutina principal o lazo principal. Como se ve, consta de apenas tres instrucciones. Es obvio que as el PIC tambin est desaprovechado, pero est claro que en este lugar ubicaremos, en el futuro, programas ms importantes. A continuacin de este lazo vemos una parte del programa anterior, la que determina el encendido del pulso de control del servo a valor 1, y define el primer retardo, bsico, de unos 0,5 ms. Lo que se debe observar es que el retardo no se produce en esta rutina, sino que slo se "lanza" al timer, programando su registro o contador con el valor necesario. Aqu no hay un lazo cerrado de espera. Cmo se produce entonces el retardo? El retardo ha comenzado ya, y transcurre durante todo el tiempo en que el programa se encuenta en fase 1. Este pequeo bloque de programa, que inici el pulso y el retardo, tambin ha puesto el programa en esta fase, poniendo a valor 1 la variable "fase". Qu ocurre ahora? El PIC sigue con sus tareas habituales (en este programa, bien, el PIC prcticamente no hace nada, pero podra estar comandando un robot). El contador del timer 0 va contando, cada 8 microsegundos, hasta que llega a sobrepasar su cuenta, rebasando su valor mximo, que es 0xFF ( 255 en decimal) y llegando de nuevo al valor 0x00. Aqu se produce la interrupcin. Qu significa esto? Significa que la lgica interna del PIC registra el lugar exacto en el que est el programa (para luego volver a l), se fija en ese vector 0x004 que hemos programado para ver dnde debe ir a ejecutar su rutina de manejo de la interrupcin, y all va... Revisemos entonces la rutina de interrupcin. A la entrada vemos que lo primero que hace es inhibir una nueva interrupcin a causa del timer. Esto es importante y debe ser una prctica comn a utilizar porque si se produce una nueva interrupcin mientras estamos atendiendo sta, es decir, mientras estamos dentro de la rutina de atencin de interrupciones, algo fallar. A continuacin, la rutina se ocupa de guardar el estado (STATUS) y el valor del acumulador (W). Esto es necesario para no afectar el funcionamiento del programa cuando el PIC retorne al lugar donde se produjo la interrupcin. Ya veremos que a la salida de la rutina de manejo de la interrupcin los valores se reponen. En la siguiente parte de la rutina de manejo de interrupcin vemos que sta debe hacer diferentes cosas segn en qu fase de programa nos encontremos. A este punto del seguimiento estamos en fase 1, as que entrar a la rutina llamada "fase1". fase1 es un fragmento del programa anterior, en el que definamos el valor de ancho, o retardo, del resto del pulso: la parte variable. Slo se ha quitado, una vez ms, el lazo de espera sobre s mismo (que es el que volva esclavo al microcontrolador). Como se observa en las lneas de programa, lo nico que debe hacer esta rutina es colocar un valor variable, la variable Posic, en el registro del timer, pasar el estado a fase 2, y salir. En la prxima interrupcin (que se producir cuando se cumpla el tiempo de la segunda parte del pulso, o la parte variable del pulso de control), la rutina de manejo de interrupcin entrar a la parte de la rutina con la etiqueta fase2. fase2 tambin es una parte del programa anterior, y tambin qued sin el lazo de espera. Aqu se pone a cero la seal de control del servo y se define la siguiente espera, que es la separacin entre pulsos de control. Avanza el estado del programa a fase 3 y sale. Si observamos el cdigo, vemos que en esta parte estamos cambiando algo en la configuracin del timer. Qu es esto? A no asustarse. Debido a que en los retardos anteriores tenamos pulsos angostos, la velocidad de conteo del registro del timer la habamos definido en un pulso (o conteo) cada 8 microsegundos. Esto nos daba una buena resolucin para controlar el servo y nos permita alcanzar los valores de retardo necesario con slo un byte para definirlos (la variable Posic). El mximo es de 256 x 8 us = 2048 microsegundos, 2,048 milisegundos. Pero en esta parte necesitamos un retardo de 20
milisegundos. No nos alcanza. Por eso, cambiando el valor elegido de prescaler, cambiamos el ritmo del contador para que cuente una vez cada 256 microsegundos. Un valor de 7 en el contador (7 x 256 us) nos dar el valor deseado, de (aproximadamente) 18 milisegundos. Cuando se cumpla este tiempo, se producir una nueva interrupcin y entraremos a la parte etiquetada fase3 de la rutina de manejo de interrupciones. En fase3 debemos preparar todo para un nuevo ciclo. Se repone el prescaler anterior, que nos da un conteo cada 8 us, y se pone el estado del programa en fase 0. Esta parte de la rutina es muy sencilla, como se ve. Dentro de fase3 hemos incluido la lectura de los pulsadores y, segn su estado, la actualizacin de la posicin del servo. Lo colocamos aqu porque a esta parte de las fases entra una vez cada ms o menos 20 milisegundos, y as, al actuar un pulsador, el avance y dismimucin de la posicin que se produce en el movimiento del servo no es excesivamente veloz. Si dejsemos esta parte de la rutina en el lazo principal, los pulsadores seran ledos tantas veces, y a tanta velocidad, que el servo saltara de un extremo al otro en lugar de moverse gradualmente. Se nota aqu cmo los tiempos estn mejor aprovechados, ya que el movimiento del servo es ms fluido. En este punto regresamos a la fase 0. Al salir de la rutina de manejo de interrupciones volvemos al lazo principal de programa y desde all volveremos a repetir, una vez ms, el ciclo completo de fases. Espero haber sido claro. Quizs sea necesario leer un par de veces este programa, imprimiendo la rutina y haciendo marcas en los lugares que nos resulte necesario. Para facilitar el seguimiento, aqu van los diagramas de flujo:
Diagrama de flujo de la parte en el programa principal
;********************************************************************** ; MANEJO DE SERVOS - Programa Bsico 1 ; Por Eduardo J. Carletti, Robots Argentina, 2007 ;********************************************************************** list p=16F628A ; definir procesador ; definiciones de variables especficas del ; para evitar los mensajes de cambio de ; banco en el resultado del compilador
_CP_OFF & _WDT_OFF & _LVP_OFF & _PWRTE_ON & _INTRC_OSC_NOCLKOUT &
;***** DEFINICIN DEL NOMBRE DE ENTRADAS Y SALIDAS #define #define #define #define SERVO1 PULSADOR1 PULSADOR2 PULSADOR3 PORTA,0 PORTA,1 PORTA,2 PORTA,3 ; ; ; ; puerto puerto puerto puerto de de de de salida de servo 1 entrada de pulsador 1 entrada de pulsador 2 entrada de pulsador 3
;***** VARIABLES CBLOCK 0x20 acum_A Posic ENDC ; variable momentnea ; posicin servo
;*********************************************************************************** ; Principal ;*********************************************************************************** principal movlw b'00000111' movwf CMCON clrf PORTA clrf PORTB bsf STATUS,RP0 movlw b'00001110' movwf TRISA MOVLW b'00000000' movwf TRISB movlw movwf b'00000010' OPTION_REG ; deshabilita comparadores. Esto es ; algo importante en el PIC 16F628A ; inicia ports ; inicia ports ; Apunta a banco 1 ; PORTA ; salidas menos 1, 2 y 3, entradas ; PORTB ; salidas ; ; ; ; Configuracin para TMR0 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 ; Apunta a banco 0 ; inicia registro de timer en 0
;*********************************************************************************** ; Lazo principal ;*********************************************************************************** lazo ; ; ; ; ; Los servos actan 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 mnimo del pulso. Con este valor de longitud de pulso y una longitud cero en la parte variable, el servo est parado al mximo hacia la izquierda (sentido antihorario). bsf bcf movlw movwf btfss goto bcf ; ; ; ; SERVO1 INTCON,T0IF d'192' TMR0 INTCON,T0IF $-1 INTCON,T0IF ; ; ; ; ; pone la seal de servo en 1 borra el flag de timer (256-192 = 64) 64 * 8 us = 0,512 ms valor al registro de timer espera por timer = ff -> 00
A continuacin, 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 vara entre 0 y 2 ms movf movwf btfss goto bcf bcf Posic,w TMR0 INTCON,T0IF $-1 SERVO1 INTCON,T0IF ; 256-nn x 8 uS = 1 ms, 1,5 ms, 2,5 ms ; valor al registro de timer ; espera por timer = ff -> 00 ; pone la seal de servo en 0 ; borra el flag de timer
; Retardo de 20 ms, que es el tiempo estndar que debe separar los pulsos ; de control para los servos comunes de RC movlw movwf bcf movlw movwf btfss goto decfsz goto d'9' acum_A INTCON,T0IF d'6' TMR0 INTCON,T0IF $-1 acum_A retardo ; cantidad de veces: 9 x 2 ms = 18 ms + 2 ms ; ; ; ; borra el flag de timer (256-6 = 250) 250 * 8 us = 2 ms valor al registro de timer espera por timer = ff -> 00
retardo
pulsadores btfss PULSADOR1 goto iniciaPos btfss PULSADOR2 goto incPos btfss PULSADOR3 goto decPos goto lazo iniciaPos movlw d'133' movwf Posic goto lazo
; 256-133 = 123, 123 * 8 us = 984 us + 512 us ; posicin central en esta disposicin ; y sale
movf Posic,f bz sale1 decf Posic,f goto lazo movlw 0xFF xorwf Posic,w bz sale2 incf Posic,f goto lazo END
; ; ; ; ; ; ; ; ;
se fija si Posic ya es cero si es cero no decrementa si no es cero, decrementa y sale se fija si Posic no es 0xFF que es el valor mximo si es el valor mximo, no incrementa si no es el valor mx, incrementa y sale
sale2
:020000040000FA :10000000012807309F008501860183160E30850088 :100010000030860002308100831281018530A1000A :1000200005140B11C03081000B1D14280B11210881 :1000300081000B1D192805100B110930A0000B11B0 :10004000063081000B1D2228A00B1F28851C2D289F :10005000051D3528851D302810288530A100102861 :10006000A10803193428A1031028FF302106031921 :060070003A28A10A102845 :02400E00503F21 :00000001FF
;********************************************************************** ; MANEJO DE SERVOS - Programa Bsico 2 - Manejo con interrupciones ; Por Eduardo J. Carletti, Robots Argentina, 2007 ;********************************************************************** list p=16F628A ; definir procesador ; definiciones de variables especficas del ; para evitar los mensajes de cambio de ; banco en el resultado del compilador
__CONFIG _MCLRE_OFF
_CP_OFF & _WDT_OFF & _LVP_OFF & _PWRTE_ON & _INTRC_OSC_NOCLKOUT &
;***** DEFINICIN DEL NOMBRE DE ENTRADAS Y SALIDAS #define #define #define #define SERVO1 PULSADOR1 PULSADOR2 PULSADOR3 PORTA,0 PORTA,1 PORTA,2 PORTA,3 ; ; ; ; puerto puerto puerto puerto de de de de salida de servo 1 entrada de pulsador 1 entrada de pulsador 2 entrada de pulsador 3
;***** VARIABLES CBLOCK 0x20 acum_A Posic fase Guardar_STATUS Guardar_W ENDC ; ; ; ; ; variable momentnea posicin servo fase de programa para interrupcin Guardar Status Guardar W
;*********************************************************************************** ; Principal ;*********************************************************************************** principal movlw b'00000111' movwf CMCON clrf PORTA clrf PORTB bsf STATUS,RP0 movlw b'00001110' movwf TRISA MOVLW b'00000000' movwf TRISB movlw movwf b'00000010' OPTION_REG ; deshabilita comparadores. Esto es ; algo importante en el PIC 16F628A ; inicia ports ; inicia ports ; Apunta a banco 1 ; PORTA ; salidas menos 1, 2 y 3, entradas ; PORTB ; salidas ; ; ; ; Configuracin para TMR0 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 ; Apunta a banco 0 ; inicia registro de timer en 0 ; inicia valor de posicin de servo (centro) ; inicia para que comience con la fase 0 ; Interrupciones habilitadas ; GIE (global), T0IE (timer 0)
bcf STATUS,RP0 clrf movlw movwf clrf movlw TMR0 d'133' Posic fase b'10100000'
movwf
INTCON
;*********************************************************************************** ; Lazo principal ;*********************************************************************************** lazo movf bz goto fase,f fase0 lazo
;*********************************************************************************** ; Rutina de apoyo ;*********************************************************************************** ; ; ; ; ; Fase 0: Los servos actan 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 mnimo del pulso. Con este valor de longitud de pulso y una longitud cero en la parte variable, el servo est parado al mximo hacia la izquierda (sentido antihorario). bsf bcf movlw movwf incf goto SERVO1 INTCON,T0IF d'192' TMR0 fase,f lazo ; ; ; ; ; pone la seal de servo en 1 borra el flag de timer (256-192 = 64) 64 * 8 us = 0,512 ms valor al registro de timer pasa a fase 1
fase0
;*********************************************************************************** ; Manejo interrupciones ;*********************************************************************************** interrupcion ; Salva todo bcf movwf swapf movwf ; distribuidor movf xorlw bz movf xorlw bz movf xorlw bz goto ; ; ; ; fase,w 0x01 fase1 fase,w 0x02 fase2 fase,w 0x03 fase3 salidaint ; fase 1? ; s ; fase 2? ; s ; fase 3? ; s ; ninguna de ellas, sale INTCON,T0IE ; deshabilita interrupcin de timer Guardar_W STATUS, w Guardar_STATUS
Fase 1: Aqu 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 vara entre 0 y 2 ms movf movwf incf Posic,w TMR0 fase,f ; 256-nn x 8 uS = 1 ms, 1,5 ms, 2,5 ms ; valor al registro de timer ; pasa a fase 2
fase1
goto
salidaint
; Fase 2: Retardo de 20 ms, que es el tiempo estndar que debe separar los pulsos ; de control para los servos comunes de RC fase2 bcf bsf movlw movwf SERVO1 STATUS,RP0 b'00000111' OPTION_REG ; ; ; ; ; ; pone la seal de servo en 0 Apunta a banco 1 Configuracin para TMR0 preescaler 7, 1:256 con CLK interno (que es de 1 MHz si el oscilador es de 4 MHz). El contador cuenta cada 256 useg ; Apunta a banco 0 ; (256-249 = 7) 7 * 256 us = 17,92 ms + 2 ms ; valor al registro de timer ; pasa a fase 3
bcf STATUS,RP0 movlw d'249' pulso movwf incf goto ; ; ; ; TMR0 fase,f salidaint
Fase 3: Como en el bloque de la fase 2 cambi el prescaler del timer a 7, ahora debe reponerlo al valor de un conteo cada 8 useg, y volver al estado de fase = 0, con lo cual el ciclo se reinicia. Tambin hemos insertado en esta fase, que se ejecuta cada 20 ms aproximadamente, la lectura de los pulsadores. bsf STATUS,RP0 movlw b'00000010' movwf OPTION_REG bcf clrf STATUS,RP0 fase ; ; ; ; ; ; ; Apunta a banco 1 Configuracin para TMR0 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 Apunta a banco 0 pasa a fase 0
fase3
pulsadores
; lee rdenes a travs btfss PULSADOR1 goto iniciaPos btfss PULSADOR2 goto incPos btfss PULSADOR3 goto decPos goto salidaint
;*********************************************************************************** ; Rutinas de apoyo ;*********************************************************************************** iniciaPos movlw d'133' movwf Posic goto salidaint movf Posic,f bz sale1 decf Posic,f goto salidaint movlw 0xFF xorwf Posic,w bz sale2 incf Posic,f goto salidaint ; 256-133 = 123, 123 * 8 us = 984 us + 512 us ; posicin central en esta disposicin ; y sale ; ; ; ; ; ; ; ; ; se fija si Posic ya es cero si es cero no decrementa si no es cero, decrementa y sale se fija si Posic no es 0xFF que es el valor mximo si es el valor mximo, no incrementa si no es el valor mx, incrementa y sale
salidaint bcf swapf movwf swapf swapf bsf retfie END INTCON,T0IF ; borra el flag de timer Guardar_STATUS, w STATUS Guardar_W, f Guardar_W, w INTCON,T0IE ; habilita interrupcin de timer ; retorna
:020000040000FA :020000000528D1 :08000800212807309F0085014B :10001000860183160E308500003086000230810094 :10002000831281018530A100A201A0308B00A208BB :1000300003191B28172805140B11C0308100A20AD0 :1000400017288B12A400030EA3002208013A0319FB :1000500032282208023A031936282208033A0319E3 :100060003F28592821088100A20A59280510831623 :10007000073081008312F9308100A20A59288316C3 :10008000023081008312A201851C4B28051D5328D4 :10009000851D4E2859288530A1005928A10803192B :1000A0005228A1035928FF30210603195828A10A14 :1000B00059280B11230E8300A40E240E8B16090061 :02400E00503F21 :00000001FF
; This header file defines configurations, registers, and other useful bits of ; information for the PIC16F628A microcontroller. These names are taken to match ; the data sheets as closely as possible. ; Note that the processor must be selected before this file is ; included. The processor may be selected the following ways: ; ; ; ; ; 1. Command line switch: C:\ MPASM MYFILE.ASM /PIC16F628A 2. LIST directive in the source file LIST P=PIC16F628A 3. Processor Type entry in the MPASM full-screen interface
;==========================================================================
; ; Revision History ; ;========================================================================== ;Rev: ;1.01 ;1.00 Date: Reason: 14 Nov 2002 Updated to reflect BOD terminology changed to BOR 22 Aug 2002 Initial Release
;========================================================================== ; ; Verify Processor ; ;========================================================================== IFNDEF __16F628A MESSG "Processor-header file mismatch. ENDIF Verify selected processor."
;----- Register Files-----------------------------------------------------INDF TMR0 PCL STATUS FSR PORTA PORTB PCLATH INTCON PIR1 TMR1L TMR1H T1CON TMR2 T2CON CCPR1L CCPR1H CCP1CON RCSTA TXREG RCREG CMCON OPTION_REG TRISA TRISB PIE1 PCON PR2 TXSTA SPBRG EEDATA EQU EQU EQU EQU EQU EQU EQU EQU EQU EQU EQU EQU EQU EQU EQU EQU EQU EQU EQU EQU EQU EQU EQU EQU EQU EQU EQU EQU EQU EQU EQU H'0000' H'0001' H'0002' H'0003' H'0004' H'0005' H'0006' H'000A' H'000B' H'000C' H'000E' H'000F' H'0010' H'0011' H'0012' H'0015' H'0016' H'0017' H'0018' H'0019' H'001A' H'001F' H'0081' H'0085' H'0086' H'008C' H'008E' H'0092' H'0098' H'0099' H'009A'
;----- STATUS Bits -------------------------------------------------------IRP RP1 RP0 NOT_TO NOT_PD Z DC C EQU EQU EQU EQU EQU EQU EQU EQU H'0007' H'0006' H'0005' H'0004' H'0003' H'0002' H'0001' H'0000'
;----- INTCON Bits -------------------------------------------------------GIE PEIE T0IE INTE RBIE T0IF INTF RBIF EQU EQU EQU EQU EQU EQU EQU EQU H'0007' H'0006' H'0005' H'0004' H'0003' H'0002' H'0001' H'0000'
;----- PIR1 Bits ---------------------------------------------------------EEIF CMIF RCIF TXIF CCP1IF TMR2IF TMR1IF EQU EQU EQU EQU EQU EQU EQU H'0007' H'0006' H'0005' H'0004' H'0002' H'0001' H'0000'
;----- T1CON Bits --------------------------------------------------------T1CKPS1 EQU H'0005' T1CKPS0 EQU H'0004' T1OSCEN EQU H'0003' NOT_T1SYNC EQU H'0002' TMR1CS EQU H'0001' TMR1ON EQU H'0000' ;----- T2CON Bits --------------------------------------------------------TOUTPS3 EQU H'0006' TOUTPS2 EQU H'0005' TOUTPS1 EQU H'0004' TOUTPS0 EQU H'0003' TMR2ON EQU H'0002' T2CKPS1 EQU H'0001' T2CKPS0 EQU H'0000' ;----- CCP1CON Bits --------------------------------------------------------CCP1X EQU H'0005' CCP1Y EQU H'0004' CCP1M3 EQU H'0003' CCP1M2 EQU H'0002' CCP1M1 EQU H'0001' CCP1M0 EQU H'0000'
;----- RCSTA Bits --------------------------------------------------------SPEN EQU H'0007' RX9 EQU H'0006' SREN EQU H'0005' CREN EQU H'0004' ADEN EQU H'0003' FERR EQU H'0002' OERR EQU H'0001' RX9D EQU H'0000' ;----- CMCON Bits --------------------------------------------------------C2OUT C1OUT C2INV C1INV CIS CM2 CM1 CM0 EQU EQU EQU EQU EQU EQU EQU EQU H'0007' H'0006' H'0005' H'0004' H'0003' H'0002' H'0001' H'0000'
;----- OPTION Bits -------------------------------------------------------NOT_RBPU INTEDG T0CS T0SE PSA PS2 PS1 PS0 EQU EQU EQU EQU EQU EQU EQU EQU H'0007' H'0006' H'0005' H'0004' H'0003' H'0002' H'0001' H'0000'
;----- PIE1 Bits ---------------------------------------------------------EEIE CMIE RCIE TXIE CCP1IE TMR2IE TMR1IE EQU EQU EQU EQU EQU EQU EQU H'0007' H'0006' H'0005' H'0004' H'0002' H'0001' H'0000'
;----- PCON Bits ---------------------------------------------------------OSCF NOT_POR NOT_BO NOT_BOR NOT_BOD EQU EQU EQU EQU EQU H'0003' H'0001' H'0000' H'0000' H'0000' ;Backwards compatability to 16F62X
;----- TXSTA Bits ---------------------------------------------------------CSRC EQU H'0007' TX9 EQU H'0006' TXEN EQU H'0005' SYNC EQU H'0004' BRGH EQU H'0002' TRMT EQU H'0001' TX9D EQU H'0000' ;----- EECON1 Bits --------------------------------------------------------WRERR EQU H'0003' WREN EQU H'0002'
WR RD
EQU EQU
H'0001' H'0000'
;----- VRCON Bits --------------------------------------------------------VREN VROE VRR VR3 VR2 VR1 VR0 EQU EQU EQU EQU EQU EQU EQU H'0007' H'0006' H'0005' H'0003' H'0002' H'0001' H'0000'
;========================================================================== ; ; RAM Definition ; ;========================================================================== __MAXRAM __BADRAM __BADRAM __BADRAM __BADRAM H'01FF' H'07'-H'09', H'0D', H'13'-H'14', H'1B'-H'1E' H'87'-H'89', H'8D', H'8F'-H'91', H'93'-H'97', H'9E' H'105', H'107'-H'109', H'10C'-H'11F', H'150'-H'16F' H'185', H'187'-H'189', H'18C'-H'1EF'
;========================================================================== ; ; Configuration Bits ; ;========================================================================== _BODEN_ON _BODEN_OFF _BOREN_ON _BOREN_OFF _CP_ON _CP_OFF _DATA_CP_ON _DATA_CP_OFF _PWRTE_OFF _PWRTE_ON _WDT_ON _WDT_OFF _LVP_ON _LVP_OFF _MCLRE_ON _MCLRE_OFF _RC_OSC_CLKOUT _RC_OSC_NOCLKOUT _ER_OSC_CLKOUT _ER_OSC_NOCLKOUT _INTOSC_OSC_CLKOUT _INTOSC_OSC_NOCLKOUT _INTRC_OSC_CLKOUT _INTRC_OSC_NOCLKOUT _EXTCLK_OSC _HS_OSC _XT_OSC _LP_OSC LIST EQU EQU EQU EQU EQU EQU EQU EQU EQU EQU EQU EQU EQU EQU EQU EQU EQU EQU EQU EQU EQU EQU EQU EQU EQU EQU EQU EQU H'3FFF' ;Backwards compatability to 16F62X H'3FBF' ;Backwards compatability to 16F62X H'3FFF' H'3FBF' H'1FFF' H'3FFF' H'3EFF' H'3FFF' H'3FFF' H'3FF7' H'3FFF' H'3FFB' H'3FFF' H'3F7F' H'3FFF' H'3FDF' H'3FFF' H'3FFE' H'3FFF' ;Backwards compatability to 16F62X H'3FFE' ;Backwards compatability to 16F62X H'3FFD' H'3FFC' H'3FFD' ;Backwards compatability to 16F62X H'3FFC' ;Backwards compatability to 16F62X H'3FEF' H'3FEE' H'3FED' H'3FEC'
Para el caso del motor HS-311 es necesario cambiar la configuracin del motor para la simulacin como muestra la siguiente figura:
Vamos a programar una secuencia que mantenga al motor en continuo movimiento de un extremo al otro. Aqu entra el ciclo for-next. m var byte n var byte trisb=0 portb=0 for m=50 to 250 step 1 pulsout portb.0,m pause 10 next for m=250 to 50 step -1 pulsout portb.0,m pause 10 next Vamos a ir un poco ms adelante, y controlaremos la posicin del motor con dos pulsadores: uno para girar el motor a una posicin y el otro para llevarlo a la posicin contraria. ;Only Hardware cmcon=7 control var portb.1 incrementar var porta.0 'Pin de pulsador para incremento disminuir var porta.1 'Pin de pulsador para decremento
x var byte 'x de tamao 256 r var byte 'y de tamao 256 trisb=0 portb=0 x=150 ; 'Posicin inicial del servo motor inicio: pulsout control,x 'Enva x por el pin portb.1 (control) gosub timer 'Subrutina de chequeo del pulsador goto inicio timer: if incrementar=0 then gosub mas 'Si el p esta a tierra, ir a subr "mas" if disminuir=0 then gosub menos 'Si el p esta a tierra, ir a subr "menos" return mas: 'Subrutina de aumento de posicin pause 10 x=x+1 ; 'Aumento del pulso de salida if x>200 then x=200 'Determina un valor mximo de 200 return menos: 'Subrutina de disminucin de posicin pause 10 x=x-1 'Disminucin del pulso de salida if x<100 then x=100 'Determina un valor mnimo de 100 return end El esquema de este programa se muestra en la siguiente figura:
Controlar un servomotor de modelismo con un microcontrolador pic 16f628A mediante 2 pulsadores y indicador luminoso
Con este circuito podemos situar la posicion de un servomotor de los usados en modelismo en 256 posiciones diferentes, la cual se reflejara sobre 8 diodos LED. Manteniendo presionado el pulsador IZQ o DER variaremos la posicion sel servo en un sentido u otro, al mismo tiempo de que los led van indicando secuencias diferentes. Aproximadamente mediante la actuacion de estos 2 pulsadores tardara 50seg el servomotor en realizar todo el recorrido, pero si actuamos al mismo tiempo sobre el pulsador TURBO, se reducira este tiempo a solo 5seg. Tenemos la posibilidad de accionarlo mediante los microswitch, y llevar al servo a unas posiciones concretas sin necesidad de tener que verlo. Con los pulsadores IZQ y DER llevaremos el servo a la posicion deseada, en donde observaremos los LED que permanecen encendidos, colocando en la posicion de ON los microinterruptoes que coincidan con los LED encendidos, de modo que independientemente de donde se encuentre el servo, este regresara a esa posicion siempre que actuemos sobre el pulsador SELEC. Incluso podemos dejar continuamente presionado SELEC y mediante los microinterruptores controlar al servomotor.
Como podeis apreciar en el Esquema el microcontrolador funciona sin el tipico cristal de cuarzo de 4Mhz. Prestar atencion a los valores de las resistencias R1 a R16, ya que son valores criticos para que los microinterruptores polaricen adecuadamente las entradas del PIC.
El que desee ampliar los conocimientos sobre servomotores puede acudir a la WIKIPEDIA. En la imagen se representan los tiempos del pulso generado en funcion de la posicion que queramos adquirir. Estos tiempos de funcionamiento no son estandar para todas las marcas de servomotores, de modo que segun el modelo que utiliceis, os encontrreis con el problema que no alacanza la totalidad del recorrido de los 180 o bien que esteis sobrepasando el limite inferior o superior, haciendo que el servomotor se vuelva muy inestable. Los tiempos utilizados para este circuito, NO corresponden con los de la imagen, aunque os indirare mas adelante como modificarlos.
En la siguiente tabla se representan algunos fabricantes de servomotores y los tiempos que utilizan para posicionar al servo en una posicion determinada, asi como los colores de los cables empleados. Duracin pulso (ms) Fabricante min. neutral. mx.. Futaba 0.9 1.5 2.1 Hitech 0.9 1. 5 2. 1 Graupner/Jr 0.8 1.5 2.2 Multiplex 1.05 1.6 2.15 Robbe 0.65 1.3 1.95 Simprop 1.2 1.7 2.2 disposicin de cables + batt - batt pwm. rojo negro blanco rojo negro amarillo rojo marrn naranja rojo negro amarillo rojo negro blanco rojo azul negro
Hz 50 50 50 40 50 50
En mi caso para los servomotores que yo disponia en ese momento utilice un tiempo minimo de 550ms, los cuales podeis modificar en ensamblador en la parte del programa: bucle_2 bsf call call call
Salida ;pongo en alto la salida Retardo_300micros ;tiempo minimo de 550 us Retardo_200micros Retardo_50micros
Como el tiempo del pulso lo puedo seleccionar en 256 valores diferentes, he utilizado un multiplo de tiempo de 7useg. Por lo tanto 7us X 256 = 1792useg, los cuales sumados a los 550us minimos, nos dan un total de 2342useg o 2,34 mseg.
Para variar el tiempo maximo solo teneis que variar el multiplo de 7us en la siguiente parte del programa ,quitando o aadiendo instrucciones NOP, las cuales afectan en el tiempo 1micro segundo: Tiempo nop nop nop nop ;nop ; 4us ; 5us ; 6us ; 7us ; 8us no utilizado